The Pause monad

前端 未结 6 1966
遥遥无期
遥遥无期 2020-12-22 17:00

Monads can do many amazing, crazy things. They can create variables which hold a superposition of values. They can allow you to access data from the future before you comput

6条回答
  •  误落风尘
    2020-12-22 18:04

    Note: that you provided yourself no direct access to the current state s in this monad.

    Pause s is just a free monad over the mutate and yield operations. Implemented directly you get:

    data Pause s a
      = Return a
      | Mutate (s -> s) (Pause s a)
      | Yield (Pause s a)
    
    instance Monad (Pause s) where
      return = Return
      Return a   >>= k = k a
      Mutate f p >>= k = Mutate f (p >>= k)
      Yield p    >>= k = Yield (p >>= k)
    

    with a couple of smart constructors to give you the desired API:

    mutate :: (s -> s) -> Pause s ()
    mutate f = Mutate f (return ())
    
    yield :: Pause s ()
    yield = Yield (return ())
    

    and the step function to drive it

    step :: s -> Pause s () -> (s, Maybe (Pause s ()))
    step s (Mutate f k) = step (f s) k
    step s (Return ()) = (s, Nothing)
    step s (Yield k) = (s, Just k)
    

    You could also define this directly using

    data Free f a = Pure a | Free (f (Free f a))
    

    (from my 'free' package) with

    data Op s a = Mutate (s -> s) a | Yield a
    

    then we already have a monad for Pause

    type Pause s = Free (Op s)
    

    and just need to define the smart constructors and stepper.

    Making it faster.

    Now, these implementations are easy to reason about, but they don't have the fastest operational model. In particular, left associated uses of (>>=) yield asymptotically slower code.

    To get around that you can apply the Codensity monad to your existing free monad, or just use the 'Church free' monad directly, both of which I describe in depth on my blog.

    http://comonad.com/reader/2011/free-monads-for-less/

    http://comonad.com/reader/2011/free-monads-for-less-2/

    http://comonad.com/reader/2011/free-monads-for-less-3/

    The result of applying the Church encoded version of the Free monad is that you get an easy to reason about model for the data type, and you still get a fast evaluation model.

提交回复
热议问题