The Pause monad

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

    Doesn't match your type signatures exactly, but certainly simple:

    {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-}
    import Control.Monad.State
    
    newtype ContinuableT m a = Continuable { runContinuable :: m (Either a (ContinuableT m a)) }
    instance Monad m => Monad (ContinuableT m) where
        return = Continuable . return . Left
        Continuable m >>= f = Continuable $ do
            v <- m
            case v of
                Left  a -> runContinuable (f a)
                Right b -> return (Right (b >>= f))
    
    instance MonadTrans ContinuableT where
        lift m = Continuable (liftM Left m)
    
    instance MonadState s m => MonadState s (ContinuableT m) where
        get = lift get
        put = lift . put
    
    yield :: Monad m => ContinuableT m a -> ContinuableT m a
    yield = Continuable . return . Right
    
    step :: ContinuableT (State s) a -> s -> (Either a (ContinuableT (State s) a), s)
    step = runState . runContinuable
    
    -- mutate unnecessary, just use modify
    

提交回复
热议问题