Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

BebeSparkelSparkel
Copy link

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
Copy link

(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
Copy link
Author

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

@kozross
Copy link
Collaborator

kozross commented Apr 18, 2024

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
Copy link
Author

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

@BebeSparkelSparkel
Copy link
Author

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

@BebeSparkelSparkel
Copy link
Author

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

@BebeSparkelSparkel
Copy link
Author

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
Copy link
Author

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

@rhendric
Copy link

I see no glaring issues.

@BebeSparkelSparkel
Copy link
Author

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

@BebeSparkelSparkel BebeSparkelSparkel marked this pull request as draft August 22, 2024 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants