The Pause monad

前端 未结 6 1956
遥遥无期
遥遥无期 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:00

    {-# LANGUAGE TupleSections #-}
    newtype Pause s x = Pause (s -> (s, Either x (Pause s x)))
    
    instance Monad (Pause s) where
      return x = Pause (, Left x)
    
      Pause k >>= f = Pause $ \s -> let (s', v) = k s in
                                    case v of
                                      Left x -> step (f x) s'
                                      Right x -> (s', Right (x >>= f))
    
    mutate :: (s -> s) -> Pause s ()
    mutate f = Pause (\s -> (f s, Left ()))
    
    yield :: Pause s ()
    yield = Pause (, Right (return ()))
    
    step :: Pause s x -> s -> (s, Either x (Pause s x))
    step (Pause x) = x
    

    That's how I would wrote this. I gave step a bit more general definition, it could be as well named runPause. In fact thinking about type of step lead me to definition of Pause.

    In the monad-coroutine package you will find a general monad transformer. The Pause s monad is the same as Coroutine (State s) Id. You can combine coroutines with other monads.

    Related: the Prompt monad in http://themonadreader.files.wordpress.com/2010/01/issue15.pdf

提交回复
热议问题