Proposal: DerivingVia, MTL
Reed Mullanix
reedmullanix at gmail.com
Mon May 20 01:27:09 UTC 2019
As it stands, working with newtypes around transformers can be kind of a
pain. For example,
consider
newtype FreshT m a = { unFreshT :: StateT Int m a }
deriving (Functor, Applicative, Monad, MonadReader r, ...)
Right now, we can't just GND the instance:
instance (MonadState s m) => MonadState s (FreshT m)
However, the instance we end up writing is completely formulaic.
Fortunately, we can solve this by using the recently added -XDerivingVia
newtype Inner (t :: (* -> *) -> * -> *) m a = Inner { getInner :: t m a }
deriving (Functor, Applicative, Monad)
instance (MonadState s m) => MonadState s (Inner (StateT s') m) where
get = Inner $ lift get
put = Inner . lift . put
This lets us derive the instance that we were looking for
newtype FreshT m a = FreshT { unFreshT :: StateT Int m a }
deriving newtype (Functor, Applicative, Monad, MonadReader r)
deriving (MonadState s) via Inner (StateT Int) m
This can be extended to other transformers/classes very easily. It also
works well when dealing with newtyped transformer stacks.
newtype FooT s e m a = FooT { unFooT :: StateT s (WriterT String (ExceptT e
m)) a }
deriving newtype (Functor, Applicative, Monad, MonadError e)
deriving (MonadWriter w) via (StateT s (Inner (WriterT String) (ExceptT e
m)))
deriving (MonadState s') via Inner (StateT s) (WriterT String (ExceptT e
m))
Cheers,
Reed Mullanix
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20190519/f37c2ee5/attachment.html>
More information about the Libraries
mailing list