<div dir="auto">Sorry, I should've been more clear. The proposal is to add the Inner newtype and it's associated instances to MTL.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, May 19, 2019, 7:57 PM chessai ., <<a href="mailto:chessai1996@gmail.com">chessai1996@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto">I'm confused. This seems more like a helpful tip than a proposal. Where is the proposal?</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, May 19, 2019, 9:27 PM Reed Mullanix <<a href="mailto:reedmullanix@gmail.com" target="_blank" rel="noreferrer">reedmullanix@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>As it stands, working with newtypes around transformers can be kind of a pain. For example,</div><div>consider<br></div><div><br></div><div>newtype FreshT m a = { unFreshT :: StateT Int m a }</div><div>  deriving (Functor, Applicative, Monad, MonadReader r, ...)</div><div><br></div><div>Right now, we can't just GND the instance:</div><div><br></div><div>instance (MonadState s m) => MonadState s (FreshT m)</div><div><br></div><div>However, the instance we end up writing is completely formulaic. Fortunately, we can solve this by using the recently added -XDerivingVia</div><div><br></div><div>newtype Inner (t :: (* -> *) -> * -> *) m a = Inner { getInner :: t m a }<br>  deriving (Functor, Applicative, Monad)</div><div><br></div><div>instance (MonadState s m) => MonadState s (Inner (StateT s') m) where<br>  get = Inner $ lift get<br>  put = Inner . lift . put<br></div><div><br></div><div>This lets us derive the instance that we were looking for</div><div><br></div><div>newtype FreshT m a = FreshT { unFreshT :: StateT Int m a }<br>  deriving newtype (Functor, Applicative, Monad, MonadReader r)<br>  deriving (MonadState s) via Inner (StateT Int) m</div><div><br></div><div>This can be extended to other transformers/classes very easily. It also works well when dealing with newtyped transformer stacks.</div><div><br></div><div>newtype FooT s e m a = FooT { unFooT :: StateT s (WriterT String (ExceptT e m)) a }<br>  deriving newtype (Functor, Applicative, Monad, MonadError e)<br>  deriving (MonadWriter w) via (StateT s (Inner (WriterT String) (ExceptT e m)))<br>  deriving (MonadState s') via Inner (StateT s) (WriterT String (ExceptT e m))<br></div><div><br></div><div>Cheers,</div><div>Reed Mullanix<br></div></div>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" rel="noreferrer noreferrer" target="_blank">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div>
</blockquote></div>