Confusion over the State Monad code on “Learn you a Haskell”

后端 未结 4 741
南笙
南笙 2021-02-02 10:30

I am trying to get a grasp on Haskell using the online book Learn you a Haskell for great Good.

I have, to my knowledge, been able to understand Monads so far until I hi

4条回答
  •  终归单人心
    2021-02-02 11:19

    The State monad represents stateful computations i.e. computations that use values from, and perhaps modify, some external state. When you sequence stateful computations together, the later computations might give different results depending on how the previous computations modified the state.

    Since functions in Haskell must be pure (i.e. have no side effects) we simulate the effect of external state by demanding that every function takes an additional parameter representing the current state of the world, and returns an additional value, representing the modified state. In effect, the external state is threaded through a sequence of computations, as in this abomination of a diagram that I just drew in MSPaint:

    enter image description here

    Notice how each box (representing a computation) has one input and two outputs.

    If you look at the Monad instance for State you see that the definition of (>>=) tells you how to do this threading. It says that to bind a stateful computation c0 to a function f that takes results of a stateful computation and returns another stateful computation, we do the following:

    1. Run c0 using the initial state s0 to get a result and a new state: (val, s1)
    2. Feed val to the function f to get a new stateful computation, c1
    3. Run the new computation c1 with the modified state s1

    How does this work with functions that already take n arguments? Because every function in Haskell is curried by default, we simply tack an extra argument (for the state) onto the end, and instead of the normal return value, the function now returns a pair whose second element is the newly modified state. So instead of

    f :: a -> b
    

    we now have

    f :: a -> s -> (b, s)
    

    You might choose to think of as

    f :: a -> ( s -> (b, s) )
    

    which is the same thing in Haskell (since function composition is right associative) which reads "f is a function which takes an argument of type a and returns a stateful computation". And that's really all there is to the State monad.

提交回复
热议问题