Skip to content

Proposal: Add Elevator modifier to lift over transformers #86

@sjshuck

Description

@sjshuck

[original issue 82 by @Icelandjack]

This would be the place any transformer library can attach their lifting instance, which can then be derived via the newtype Elevator (British English: lift) (MonadTransformer = (Type -> Type) -> (Type -> Type))

type    Elevator :: MonadTransformer -> MonadTransformer
newtype Elevator trans m a = Elevator (trans m a)
 deriving
 newtype (Functor, Applicative, Monad, MonadTrans)

type    ContT :: Type -> MonadTransformer
newtype ContT r m a = ..
 deriving (MonadIO, MonadState s)
 via Elevator (ContT r) m

has instances

instance (MonadTrans trans, MonadIO m) => MonadIO (Elevator trans m) where
 liftIO :: IO ~> Elevator trans m
 liftIO = lift . liftIO

-- ?
instance (MonadTrans trans, MonadFail m) => MonadFail (Elevator trans m) where
 fail :: String -> Elevator trans m a
 fail = lift . fail

instance (MonadTrans trans, MonadState s m) => MonadState s (Elevator trans m) where
 get :: Elevator trans m s
 get = lift get

 put :: s -> Elevator trans m ()
 put = lift . put

 state :: (s -> (a, s)) -> Elevator trans m a
 state = lift . state

I haven't been able to work out how to derive other classes like MonadReader/MonadWriter/MonadError which use map*T/liftListen/liftPass/liftCatch functions to define local/listen/pass/catchError.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions