{-# LANGUAGE CPP #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE LambdaCase #-} module Test.Pull.Fake.Pure ( PullT (..) , PullM , MonadPull , runPullT , evalPullT , execPullT , runPullM , evalPullM , execPullM , pull ) where import Control.Applicative (Alternative) import Control.Monad (MonadPlus) import Control.Monad.Catch (MonadCatch, MonadMask, MonadThrow) import Control.Monad.Cont.Class (MonadCont) import Control.Monad.Except (MonadError) import Control.Monad.Fix (MonadFix) import Control.Monad.IO.Class (MonadIO) import Control.Monad.RWS.Class (MonadRWS, MonadReader, MonadState, MonadWriter) import Control.Monad.State.Strict (StateT, get, put, runStateT) import Control.Monad.Trans (MonadTrans) import Data.Functor.Identity (Identity, runIdentity) #if __GLASGOW_HASKELL__ < 808 import Control.Monad.Fail (MonadFail) #endif newtype PullT payload m a = PullT { unPullT :: StateT [payload] m a } deriving ( Functor , Applicative , Monad , MonadTrans , MonadIO , Alternative , MonadFix , MonadFail , MonadPlus , MonadState [payload] , MonadReader r , MonadWriter w , MonadRWS r w [payload] , MonadCont , MonadError e , MonadCatch , MonadMask , MonadThrow ) type PullM payload = PullT payload Identity type MonadPull payload = MonadState [payload] runPullT :: PullT payload m a -> [payload] -> m (a, [payload]) runPullT (PullT act) = runStateT act evalPullT :: Functor f => PullT payload f a -> [payload] -> f a evalPullT act = fmap fst . runPullT act execPullT :: Functor f => PullT payload f a -> [payload] -> f [payload] execPullT act = fmap snd . runPullT act runPullM :: PullM payload a -> [payload] -> (a, [payload]) runPullM act = runIdentity . runPullT act evalPullM :: PullM payload a -> [payload] -> a evalPullM act = fst . runPullM act execPullM :: PullM payload a -> [payload] -> [payload] execPullM act = snd . runPullM act pull :: MonadPull payload m => m (Maybe payload) pull = get >>= \case [] -> return Nothing hd : tl -> do put tl return $ Just hd