我读到(例如 here 和 here )所有基本单子(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
是独立定义的。在这些情况下,通常会发生 Foo
和FooT 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/