对monad"run"函数的直觉

jac*_*ick 7 monads haskell functional-programming

我正在学习Haskell中的monad,我理解为什么它们很有用,我一般都理解bind,join,return do.

我还查看了基本读者/编写器/状态/列表/​​可能是monad的基本用法示例.

尽管如此,作为一名初学者,我仍然不觉得我对"运行"功能(例如runState,runReader,runWriter)的含义有所了解.它似乎没有像上面这些函数一样的通用签名,如果它可以定义/对所有monad都有意义,我就不会得到它.

Cub*_*bic 13

run大多数monad 的函数实际上只是monad在内部表示的工件; 例如,Readermonad理论上可以表示为just

type Reader r a = r -> a
Run Code Online (Sandbox Code Playgroud)

State

type State s a = s -> (s, a)
Run Code Online (Sandbox Code Playgroud)

等等.但是,如果我们这样做,那么我们就无法提供不同的类型类(包括Monad)实现Reader,State因为它们都只是由它们表示(->).

- 也就是说,如果我们写的

instance Functor (Reader r)
  -- ....
Run Code Online (Sandbox Code Playgroud)

instance Functor (State s)
  -- ...
Run Code Online (Sandbox Code Playgroud)

我们的编译器会抱怨我们试图给出两种不同的Functor实现(->) a.

所以,而不是type我们或多或少地写同样的东西newtype,例如

newtype Reader r a = Reader { runReader :: r -> a }
Run Code Online (Sandbox Code Playgroud)

要么

newtype State s a = State { runState :: s -> (s, a)}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这些run函数实际上没有在这里任何事情,它们只是"解包"新类型,因此我们可以获得基础值.

(实际的实现可能涉及monad变换器,因此看起来有点复杂,但它们基本上仍在做同样的事情).