The Pause monad

前端 未结 6 1932
遥遥无期
遥遥无期 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 17:39

    Sure; you just let any computation either finish with a result, or suspend itself, giving an action to be used on resume, along with the state at the time:

    data Pause s a = Pause { runPause :: s -> (PauseResult s a, s) }
    
    data PauseResult s a
        = Done a
        | Suspend (Pause s a)
    
    instance Monad (Pause s) where
        return a = Pause (\s -> (Done a, s))
        m >>= k = Pause $ \s ->
            case runPause m s of
                (Done a, s') -> runPause (k a) s'
                (Suspend m', s') -> (Suspend (m' >>= k), s')
    
    get :: Pause s s
    get = Pause (\s -> (Done s, s))
    
    put :: s -> Pause s ()
    put s = Pause (\_ -> (Done (), s))
    
    yield :: Pause s ()
    yield = Pause (\s -> (Suspend (return ()), s))
    
    step :: Pause s () -> s -> (Maybe (Pause s ()), s)
    step m s =
        case runPause m s of
            (Done _, s') -> (Nothing, s')
            (Suspend m', s') -> (Just m', s')
    

    The Monad instance just sequences things in the normal way, passing the final result to the k continuation, or adding the rest of the computation to be done on suspension.

提交回复
热议问题