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

Add MonadWriter instance #534

Merged
merged 1 commit into from
Jul 7, 2023
Merged

Add MonadWriter instance #534

merged 1 commit into from
Jul 7, 2023

Conversation

olafklinke
Copy link
Contributor

A general function hoistP can be used to implement monad transformer class methods of the form MonadFoo m => m (f a) -> m (g a) for example local, listen and pass. Usage of hoistP becomes more ergonomic when Result and Reply have Traversable instances.

@@ -100,6 +103,7 @@ instance (Ord t) => Monoid (Hints t) where
--
-- See also: 'Consumption', 'Result'.
data Reply e s a = Reply (State s e) Consumption (Result s e a)
deriving (Functor)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functor instances can be automatically derived.

hoistP ::
(Stream s, Monad m) =>
(m (Reply e s a) -> m (Reply e s b)) ->
ParsecT e s m a ->
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, I opted for a less polymorphic version of the signature, since the extra flexibility is not actually needed, so it could confuse future readers (e.g. "do we actually perform a natural tranformation in these cases?").

instance (Stream s, MonadWriter w m) => MonadWriter w (ParsecT e s m) where
tell w = lift (tell w)
listen = hoistP (fmap (\(repl, w) -> fmap (,w) repl) . listen)
pass = hoistP $ \m -> pass $ do
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I do appreciate the clever point-free implementation using traversals and Endo, I think it is not the most readable one. I went ahead and rewrote it in a more verbose way.

@mrkkrp mrkkrp merged commit 2e4970a into mrkkrp:master Jul 7, 2023
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.

2 participants