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 总是 包含一个值吗?好吧,不。仅当 maybeValuefoo 都成功时。