haskell - 使用 monad 转换器和恒等 monad 派生基础 monad

标签 haskell monads

我读到(例如 herehere )所有基本单子(monad) (Mabye, Error, ...) 源自其相应的 monad 转换器 (MaybeT, ErrorT, ...) 使用身份 monad Identity。一个例子是:

type Maybe a = MaybeT Identity a

但这当然不会产生 Maybe a 的构造函数。 并在 sources MaybeT 定义为 newtype MaybeT m a = MaybeT (m (Maybe a))

我错过了什么重要的事情吗? 如何使用相应的 monad 转换器和恒等 monad 派生出一个基础 monad,从而产生具体的
可以匹配的构造函数?

最佳答案

这里使用了不同的方法。

有时,基本单子(monad) Foo根据其变压器定义为 FooT Identity 。例如, State 正如 Daniel Wagner 指出的那样,来自 Transformer 包。

其他时候,基本单子(monad) Foo是独立定义的。在这些情况下,通常会发生 FooFooT Indentity是不同的类型,但是同构。这意味着您可以在两种类型之间进行转换,而不会丢失任何信息。

我猜从Maybe开始在 Haskell 报告中定义为 Prelude类型,我们不能轻易地将其重新定义为同构 MaybeT Identity 。事实上,因为破坏/消除 Maybe a 中的值很常见通过与 Nothing 进行模式匹配和Just _ ,我们不能使用其他定义。如果我们有用户可定义的模式,我们可以使用 pattern Just x = Module.Just (Identity x) ,但我们(目前)还没有这些。

相反,其他单子(monad)如 State不在 Prelude 中,也不在 Haskell 报告中。它们通常也不会被导入 Control.Monad.State 的人通过模式匹配破坏。 。在这种情况下,转移到 StateT Identity 感觉危害较小。变体。

关于haskell - 使用 monad 转换器和恒等 monad 派生基础 monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28971572/

相关文章:

haskell - 在新行上打印列表的元素

haskell - 将 MonadError 与 Parsec 结合使用

list - Do-notation 和列表单子(monad)

c++ - 继续延续 monad 元组。怎么了?

haskell - 在 monad 变压器堆栈中使用 WeightedSample 时为 "No instance for MonadRandom"

haskell - 如何在 Haskell 中使用可变数据有效地建模关系

haskell - 使用 IO 列表查找?

optimization - 如果我在 Haskell/GHC 中使用未装箱类型(如 Int#),我应该注意哪些事项?

haskell - MonadWriter 类中的冗余

haskell - 并行 haskell 。对生产者进行速率限制