I am creating a monad transformer that I want to derive the MonadReader class for but ReaderT is part of the type. Is there a transformer that I could use with deriving via to skip over the ReaderT instance of MonadReader?
newtype FileT w m a = FileT (ReaderT Handle m a)
deriving via Bypass r m instance MonadReader r m => MonadReader r (FileT w m)
haskell:master
← BebeSparkelSparkel:bypass
opened 08:08PM - 17 Apr 24 UTC
When creating a new transformer it is often composed of other transformers. The … transformers that it is composed of usually have specific purposes that are unrelated to the more general uses of the Monad* classes and typically you still want to define the Monad* instances for the underlying monad.
My real world use case is the
```haskell
newtype FileT w m a = FileT (ReaderT Handle m a)
```
where I still want to have MonadReader but not for reading Handle but rather the r for m `instance MonadReader r m => MonadReader r (FileT w m)`
This is a bit annoying for this case but even more so for transformers wrapping RWS. In just the ReaderT case the following must be defined
```haskell
instance MonadReader r m => MonadReader r (FileT w m) where
local f (FileT (ReaderT g)) = FileT . ReaderT $ local f . g
reader = lift . reader
```
DerivingVia seems to be a better option for this by using `Bypass`
```haskell
deriving via ByPass (ReaderT Handle) m instance MonadReader r m => MonadReader r (FileT w m)
```
There could probably a more succinct way to write the derivation but this is what I have so far.
1 Like
Perhaps this works?
newtype Bypass t m a = Bypass (t m a)
instance MonadReader r m => MonadReader r (Bypass (ReaderT r') m) where
...
Seems like that would work for MonadState and MonadWriter as well
1 Like
Vlix
April 17, 2024, 9:58pm
6
Since it’s a newtype
around ReaderT
, wouldn’t the following just work?
(Not sure if you’d need to add the Handle
part)
newtype FileT ...
deriving newtype MonadReader (Handle)
They want the MonadReader
instance to come from the inner m
, not the outer ReaderT
.
1 Like