There is a state monad's define.
data SM a = SM (S -> (a,S)) -- The monadic type
instance Monad SM where -- defines state propagation
SM c1 >>= fc2 = SM (/s0 -> let (r,s1) = c1 s0
SM c2 = fc2 r in
c2 s1)
return k = SM (/s -> (k,s))
-- extracts the state from the monad
readSM :: SM S
readSM = SM (/s -> (s,s))
-- updates the state of the monad
updateSM :: (S -> S) -> SM () -- alters the state
updateSM f = SM (/s -> ((), f s))
-- run a computation in the SM monad
runSM :: S -> SM a -> (a,S)
runSM s0 (SM c) = c s0
This exampel defined a new monad type, "SM", to be computation that implicitly carries a type "S". The definition
of "SM" is simple: it consists of functions that take a state and produce two results: a retruned value (of any type)
and an updated state.
The "bind" operator here may puzzle us. Let's look at how to implement the "return" operator. The "return" just
defines a monad of "SM" type. The parameter of it, "k", will be made a tupe with another "s". But this process is
delayed due to a lambda express here. In fact, "SM a" is just to wrap the "a" into a lambda express which make a tupe
with "a" and the value of its parameter. Now, we come back to the "bind" operator. There two things must be done by
"bind" operator: to get the "kernel" into a monad; to apply a function to the "kernel".
How to get out the "kernel" from a "SM" monad. Because a instance value of "SM" is just a function, so evaluate
it with a argument. The result return by the function is a tuple, so it can assign to another tuple, "let (r,s1) = c1 s0".
OK. Now we can fetch a "kernel" from a "SM" monad. The "r" is just the "kernel". So, the first thing is finished.
Moreover, pass the "kernel" into the function and get its returned value, a temporary monad value. The temporary
monad is also a lambda express, so this lambda (function) is applied to the "s1", which is same to the "s0", a new
tuple is produced.
While ">>=" and "return" are the basic monadic sequencing operations, we also need some monadic primitives. A monadic
primitive is simply an operation that uses the insides of the monad abstraction and taps into the 'wheels and gears'
that make the monad work.
What is the "SM" doing? Looking ar the bigger picture, it is tring to define an overall computation as a series of steps
(functions with type "SM a"), sequenced using ">>=" and "return". These steps may interact with the state(via "readSM"
or "updateSM") or my ignore the state. However, the use (or non-use) of the state is hidden.
本文详细解析了状态 Monad 的定义及其实现原理。通过具体的代码示例,解释了如何使用 bind 和 return 操作符来管理和操作状态,以及如何通过 readSM 和 updateSM 函数与状态 Monad 进行交互。

被折叠的 条评论
为什么被折叠?



