January 19 2007  金曜日

来源:互联网 发布:有人自学java吗 编辑:程序博客网 时间:2024/05/18 03:11

  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. 

原创粉丝点击