-- This module provides a mechanism to embed `IO` computations -- into the effect monad. Note that the `IO` can only ever be at -- the base of your stack (for the same reasons as with transformers). module Control.Effects.IO where import Control.Effects.Eff -- |The functor representing the effect. You shouldn't need -- to create this manually, just use `liftIO`. data LiftIO a = forall r . LiftIO (IO r) (r -> a) deriving (Typeable) instance Functor LiftIO where fmap f (LiftIO c k) = LiftIO c (f . k) -- |Lift an existing `IO` action into the effect monad. liftIO :: Member LiftIO r => IO a -> Eff r a liftIO c = effect $ \k -> inj $ LiftIO c k -- |Handle by converting back to `IO`. Note that it is required that -- the effect stack is otherwise empty - this handler would not -- typecheck otherwise. ioHandler :: Handler LiftIO '[] a (IO a) ioHandler (Value a) = return $ return a ioHandler (Comp (LiftIO c k)) = return $ c >>= (runPureRes . k)