haskell / mtl

The Monad Transformer Library
http://www.haskell.org/haskellwiki/Monad_Transformers
Other
360 stars 63 forks source link

Bypass Coercible Type for Deriving Monad* Classes of New Transformers Composed of Transformers #149

Open BebeSparkelSparkel opened 4 months ago

BebeSparkelSparkel commented 4 months ago

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

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

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

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.

rhendric commented 4 months ago

(Earlier message was a mistake; sorry for noise.)

Is this basically the same concept as LiftingAccum and LiftingSelect? If so, why not follow that convention, or propose aliasing those newtypes to Bypass?

BebeSparkelSparkel commented 4 months ago

I appreciate the established convention you pointed out. So, for the case above propose to create LiftingReader?

kozross commented 4 months ago

The reason we don't have LiftingX for every X at the moment is because DerivingVia wasn't in our support window until recently. I have no objection to adding such a type class for every 'capability type class' we support.

BebeSparkelSparkel commented 4 months ago

@kozross Where do I find what is in your support window?

BebeSparkelSparkel commented 4 months ago

I have implemented a partial example for LiftingReader. Can you check if this is what you are looking for?

BebeSparkelSparkel commented 4 months ago

Is there anything else that needs to be discussed before I finish this up for MonadReader, MonadWriter, and MonadState?

BebeSparkelSparkel commented 3 months ago

I have tried a different approach for LiftingWriter and am using a type family and mapping classes. Let me know what you think of this.

BebeSparkelSparkel commented 1 month ago

@rhendric Could you review the changes since your last review?

rhendric commented 1 month ago

I see no glaring issues.

BebeSparkelSparkel commented 1 month ago

@kozross Could you check if this is ready to pull?