monad 是否保证有办法获得 "unwrapped" 类型?
Does a monad guarantee to have a way to get an "unwrapped" type?
引用 Eric 的回答:
Monads in C# -- why Bind implementations require passed function to return a monad?
"But there simply is no composition of f and g if g returns a monad and f doesn't return the monad -- there is no guarantee that there is a way to go back from the instance of the monad to an "unwrapped" type"
这是否意味着如果 g 和 f return monad 将保证 这是从 monad 实例返回到 "unwrapped"类型?但是怎么办?有人可以向我解释这一点吗?
更新:感谢 Aaron 和 Euge 的回答,现在我明白从 M 取回 T 不是 Monad 要求的一部分(API),而是从内部Monad 绑定函数实现本身,它应该知道如何从 M<T>
获取 T,否则,如何在绑定函数内部调用 Func<T, M<R>>
。
不,那不是 Monad 的已定义属性之一。 Haskell page on Monads explains clearly that you can't directly get an a
back out of an M a
. The quote is explaining that once you've gone from T
to M<T>
, you always need to work with M<T>
, hence the utility of Lifting.
正如亚伦所说,答案是否定的。在我看来,最简单的例子是你不能从 monad always "come back" 经常调用的 Maybe
monad 或 Option
.您可以在此处查看 C# 中的实现:https://mikhail.io/2016/01/monads-explained-in-csharp/
我不太懂C#,所以我会避免写代码,尽量用文字来解释。
为了对可能失败的计算建模,我们可以使用要么是值要么什么都不是的数据类型(想想 null
的替代方案)。该数据类型成为 monad 的要求如下:
- 如果我们有一个永不失败的计算,返回类型
B
的东西,那么我们可以获得 returns Maybe<B>
的等效计算。
这是 return
构造函数,它只是将值包装在 Maybe
. 中
- 我们可以编写可能会失败的计算。如何?好吧,如果第一个失败,那么一切都失败了。如果没有,那么我们将返回值传递给下一个函数。这是 bind.
的行为
- 我们还需要一些法律是有效的,但为了简单起见,让我们忘记它。
考虑我们组合两个可能会失败的函数的情况。我们总能得到一个值吗?好吧,并非总是如此。当两个函数都没有失败时,我们得到一个值。
我现在将尝试用代码来解释它。当我错的时候你可以纠正我。
所以假设我们可能有一个类型 A
的值 maybeValue
Maybe<A> maybeValue = ...;
我们有一个函数 foo
接受类型 A
的值。
Maybe<B> foo(A a) {...}
我们想将 maybeValue
传递给 foo
。 Monad 让您无需检查 maybeValue
来查看它是否具有值。你这样做:
Maybe<B> result = maybeValue.bind(foo)
再次:我可以总是 将result
转换成B
类型的东西吗?我的意思是,result
总是 包含一个值吗?好吧,不。仅当 maybeValue
和 foo
都成功时。
引用 Eric 的回答: Monads in C# -- why Bind implementations require passed function to return a monad?
"But there simply is no composition of f and g if g returns a monad and f doesn't return the monad -- there is no guarantee that there is a way to go back from the instance of the monad to an "unwrapped" type"
这是否意味着如果 g 和 f return monad 将保证 这是从 monad 实例返回到 "unwrapped"类型?但是怎么办?有人可以向我解释这一点吗?
更新:感谢 Aaron 和 Euge 的回答,现在我明白从 M 取回 T 不是 Monad 要求的一部分(API),而是从内部Monad 绑定函数实现本身,它应该知道如何从 M<T>
获取 T,否则,如何在绑定函数内部调用 Func<T, M<R>>
。
不,那不是 Monad 的已定义属性之一。 Haskell page on Monads explains clearly that you can't directly get an a
back out of an M a
. The quote is explaining that once you've gone from T
to M<T>
, you always need to work with M<T>
, hence the utility of Lifting.
正如亚伦所说,答案是否定的。在我看来,最简单的例子是你不能从 monad always "come back" 经常调用的 Maybe
monad 或 Option
.您可以在此处查看 C# 中的实现:https://mikhail.io/2016/01/monads-explained-in-csharp/
我不太懂C#,所以我会避免写代码,尽量用文字来解释。
为了对可能失败的计算建模,我们可以使用要么是值要么什么都不是的数据类型(想想 null
的替代方案)。该数据类型成为 monad 的要求如下:
- 如果我们有一个永不失败的计算,返回类型
B
的东西,那么我们可以获得 returnsMaybe<B>
的等效计算。 这是return
构造函数,它只是将值包装在Maybe
. 中
- 我们可以编写可能会失败的计算。如何?好吧,如果第一个失败,那么一切都失败了。如果没有,那么我们将返回值传递给下一个函数。这是 bind. 的行为
- 我们还需要一些法律是有效的,但为了简单起见,让我们忘记它。
考虑我们组合两个可能会失败的函数的情况。我们总能得到一个值吗?好吧,并非总是如此。当两个函数都没有失败时,我们得到一个值。
我现在将尝试用代码来解释它。当我错的时候你可以纠正我。
所以假设我们可能有一个类型 A
maybeValue
Maybe<A> maybeValue = ...;
我们有一个函数 foo
接受类型 A
的值。
Maybe<B> foo(A a) {...}
我们想将 maybeValue
传递给 foo
。 Monad 让您无需检查 maybeValue
来查看它是否具有值。你这样做:
Maybe<B> result = maybeValue.bind(foo)
再次:我可以总是 将result
转换成B
类型的东西吗?我的意思是,result
总是 包含一个值吗?好吧,不。仅当 maybeValue
和 foo
都成功时。