"run" 单子函数的直觉
Intuition for "run" function of monads
我正在 Haskell 中学习 monad,我了解它们为什么有用,我大致了解绑定、连接、return 的作用。
我还查看了基本 reader/writer/state/list/maybe monads 的基本用法示例。
不过,作为一个初学者,我仍然觉得我不了解 "run" 函数(例如 runState、runReader、runWriter)的一般含义。它似乎没有像上述函数那样的通用签名,如果它是可定义的/对所有 monad 都有意义,我不明白。
大多数 monad 的 run
函数实际上只是 monad 内部表示方式的产物;例如,Reader
monad 理论上可以表示为
type Reader r a = r -> a
State
作为
type State s a = s -> (s, a)
等等。但是,如果我们这样做,那么我们就无法为 Reader
和 State
提供不同的类型类(包括 Monad
)实现,因为它们都只由 (->)
表示。
——也就是说,如果我们写
instance Functor (Reader r)
-- ....
和
instance Functor (State s)
-- ...
我们的编译器会抱怨我们试图为 (->) a
.
提供两种不同的 Functor
实现
所以我们只是用 newtype
或多或少地写了相同的东西而不是 type
,例如
newtype Reader r a = Reader { runReader :: r -> a }
或
newtype State s a = State { runState :: s -> (s, a)}
如你所见,run
函数实际上并没有做 任何事情,它们只是 "unwrap" 新类型所以我们可以得到底层值。
(实际实现可能涉及 monad 转换器,因此看起来有点复杂,但它们本质上仍在做同样的事情)。
我正在 Haskell 中学习 monad,我了解它们为什么有用,我大致了解绑定、连接、return 的作用。
我还查看了基本 reader/writer/state/list/maybe monads 的基本用法示例。
不过,作为一个初学者,我仍然觉得我不了解 "run" 函数(例如 runState、runReader、runWriter)的一般含义。它似乎没有像上述函数那样的通用签名,如果它是可定义的/对所有 monad 都有意义,我不明白。
大多数 monad 的 run
函数实际上只是 monad 内部表示方式的产物;例如,Reader
monad 理论上可以表示为
type Reader r a = r -> a
State
作为
type State s a = s -> (s, a)
等等。但是,如果我们这样做,那么我们就无法为 Reader
和 State
提供不同的类型类(包括 Monad
)实现,因为它们都只由 (->)
表示。
——也就是说,如果我们写
instance Functor (Reader r)
-- ....
和
instance Functor (State s)
-- ...
我们的编译器会抱怨我们试图为 (->) a
.
Functor
实现
所以我们只是用 newtype
或多或少地写了相同的东西而不是 type
,例如
newtype Reader r a = Reader { runReader :: r -> a }
或
newtype State s a = State { runState :: s -> (s, a)}
如你所见,run
函数实际上并没有做 任何事情,它们只是 "unwrap" 新类型所以我们可以得到底层值。
(实际实现可能涉及 monad 转换器,因此看起来有点复杂,但它们本质上仍在做同样的事情)。