Skip to content

Monoid instance for FreeT #8

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

Merged
merged 6 commits into from
Jan 31, 2017
Merged

Monoid instance for FreeT #8

merged 6 commits into from
Jan 31, 2017

Conversation

athanclark
Copy link
Contributor

This is a pretty terrible pull request, but I still think the idea is valid.

Given any Monad m, and Monoid w, you can make m w a Monoid

It wouldn't be wise to write this instance for every monad, Haskell gets away with it by cherrypicking instances - they have one for IO and Maybe for instance, but that's about it. Also, this would conflate with the meaning behind the monadic instance for lists [], so I think it's wise to stay away from that level of generality.

However, this instance for FreeT (and nest, Eff and Aff) could be useful. In my case, I'm using them to "merge" some PerformAction routines in Thermite:

T.simpleSpec (performAction1 <> performAction2 <> ...) render

The monoid instance for Spec should also be capable of using this behavior in FreeT (and CoTransformer).

Copy link
Contributor

@paf31 paf31 left a comment

Choose a reason for hiding this comment

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

I think these instances are good to have, thanks.

@@ -76,6 +79,18 @@ instance monadRecFreeT :: (Functor f, Monad m) => MonadRec (FreeT f m) where
Loop s1 -> go s1
Done a -> pure a

instance semigroupFreeT :: (Functor f, Monad m, Monoid w) => Semigroup (FreeT f m w) where
Copy link
Contributor

Choose a reason for hiding this comment

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

You can relax the Monad constraint to Applicative and use append = lift2 append.

Copy link
Member

Choose a reason for hiding this comment

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

Although the lift2 change has been made you still have Monad m here 😄

Copy link
Member

Choose a reason for hiding this comment

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

Also, this probably only needs Semigroup w now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh jeez >< I didn't even see that, thank you. The Haskell has run deep

y' <- y
pure (x' <> y')

instance monoidFreeT :: (Functor f, Monad m, Monoid w) => Monoid (FreeT f m w) where
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here.

instance monoidFreeT :: (Functor f, Monad m, Monoid w) => Monoid (FreeT f m w) where
mempty = pure mempty

-- instance monadEffFreeT :: (Functor f, MonadEff m) => MonadEff (FreeT f m) where
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you please remove this?

import Control.Monad.Rec.Class (class MonadRec, Step(..), tailRecM)
import Control.Monad.Trans.Class (class MonadTrans)
import Control.Monad.Trans.Class (class MonadTrans, lift)
Copy link
Contributor

Choose a reason for hiding this comment

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

Unused imports.

@athanclark
Copy link
Contributor Author

Sorry, I didn't see this until now. I think it should be minimal now, sorry about that commented instance.

@@ -76,6 +79,18 @@ instance monadRecFreeT :: (Functor f, Monad m) => MonadRec (FreeT f m) where
Loop s1 -> go s1
Done a -> pure a

instance semigroupFreeT :: (Functor f, Monad m, Monoid w) => Semigroup (FreeT f m w) where
Copy link
Member

Choose a reason for hiding this comment

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

Although the lift2 change has been made you still have Monad m here 😄

append = lift2 append

instance monoidFreeT :: (Functor f, Monad m, Monoid w) => Monoid (FreeT f m w) where
mempty = pure mempty
Copy link
Member

Choose a reason for hiding this comment

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

Likewise you only need Applicative m here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I'm not sure about that - FreeT's Apply instance depends on Monad due to the use of ap - I'm not sure if there's a way around that, I'm not too familiar with FreeT's design :x

@@ -19,6 +19,7 @@
"purescript-control": "^2.0.0",
"purescript-tailrec": "^2.0.0",
"purescript-transformers": "^2.0.1",
"purescript-exists": "^2.0.0"
"purescript-exists": "^2.0.0",
"purescript-eff": "^2.0.0"
Copy link
Member

Choose a reason for hiding this comment

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

You can drop this dependency now, as there's no Eff instance.

@paf31
Copy link
Contributor

paf31 commented Jan 29, 2017

"The import of module Data.Semigroup is redundant"

@athanclark
Copy link
Contributor Author

Sorry, still learning how to use the toolchain ><

@paf31
Copy link
Contributor

paf31 commented Jan 30, 2017

👍

@garyb garyb merged commit 8152707 into purescript-contrib:master Jan 31, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants