Skip to content

Instantly share code, notes, and snippets.

@aavogt
Last active December 25, 2015 17:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aavogt/7016708 to your computer and use it in GitHub Desktop.
Save aavogt/7016708 to your computer and use it in GitHub Desktop.
apply Control.Monad.Trans.lift a number of times
{-# LANGUAGE DataKinds, FlexibleContexts, FlexibleInstances, FunctionalDependencies, KindSignatures, MultiParamTypeClasses, OverlappingInstances, ScopedTypeVariables, TypeFamilies, TypeOperators, UndecidableInstances #-}
module LiftN_ where
import Control.Monad.Trans
import Data.Proxy
import GHC.TypeLits
{- |
>>> import Control.Monad.Reader
>>> :set -XDataKinds
>>> let { (^) = runReaderT; infixl ^ }
>>> let f p = liftN p (print "hi") ^ () ^ () ^ () :: IO ()
>>> :t f
f :: Proxy Nat 3 -> IO ()
>>> f undefined
"hi"
>>> let g = liftN (Proxy :: Proxy 4) (print "hi")
>>> :t g
g :: (Monad (t (t1 (t2 (t3 IO)))), Monad (t1 (t2 (t3 IO))),
Monad (t2 (t3 IO)), Monad (t3 IO), MonadTrans t, MonadTrans t1,
MonadTrans t2, MonadTrans t3) =>
t (t1 (t2 (t3 IO))) ()
-}
class (Monad m, Monad tm) => LiftN (n :: Nat) m tm | n tm -> m, m tm -> n where
liftN :: Proxy n -> m a -> tm a
instance Monad m => LiftN 0 m m where
liftN _ = id
instance (MonadTrans t, LiftN (j - 1) m n, Monad (t n), Monad m,
tn ~ t n) => LiftN j m tn where
liftN _ = lift . liftN (undefined :: Proxy (j - 1))
{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses #-}
module LiftN where
import Control.Monad.Trans
{- |
>>> import Control.Monad.Reader
>>> import Control.Monad.Writer
>>> runReaderT (liftN (putStrLn "hi")) 4
hi
>>> runReaderT (runWriterT (liftN (putStrLn "hi"))) 4
hi
((),())
-}
class (Monad m, Monad tm) => LiftN m tm where
liftN :: m a -> tm a
instance Monad m => LiftN m m where
liftN = id
instance (MonadTrans t, LiftN m n, Monad (t n), Monad m) => LiftN m (t n) where
liftN = lift . liftN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment