我正在Haskell中学习有关monad的信息,我了解了为什么它们有用,我通常了解绑定,联接,返回的作用。
我还查看了基本阅读器/作者/状态/列表/可能还有单子的基本用法示例。
还是个初学者,我仍然不了解“运行”功能(例如runState,runReader,runWriter)的含义。它似乎没有像上面的函数那样的通用签名,如果它是可定义的/对所有单子都有意义,我就不会得到它。
答案 0 :(得分:13)
大多数monad的run
函数实际上只是内部表示monad的一种人工产物。例如,Reader
单子理论上可以表示为公正
type Reader r a = r -> a
State
为
type State s a = s -> (s, a)
,依此类推。但是,如果这样做,我们将无法为Monad
和Reader
提供不同的类型类(包括State
)实现,因为它们都仅由(->)
表示。
-也就是说,如果我们写
instance Functor (Reader r)
-- ....
和
instance Functor (State s)
-- ...
我们的编译器会抱怨我们试图为Functor
提供两个不同的(->) a
实现。
因此,我们或多或少地用type
来代替newtype
,例如
newtype Reader r a = Reader { runReader :: r -> a }
或
newtype State s a = State { runState :: s -> (s, a)}
如您所见,run
函数实际上在这里没有做,它们只是“解包”新类型,因此我们可以获得基础值。
(实际实现可能涉及monad转换器,因此看起来有些复杂,但实际上它们仍在做相同的事情)。