Skip to content

Instantly share code, notes, and snippets.

@hallettj
Last active August 29, 2015 13:55
Show Gist options
  • Save hallettj/8722628 to your computer and use it in GitHub Desktop.
Save hallettj/8722628 to your computer and use it in GitHub Desktop.
import Control.Applicative ((<$>), (<*>))
import Control.Concurrent.Async (Concurrently(..), runConcurrently)
import Data.Monoid (Monoid, (<>), mappend, mempty)
instance (Monoid a) => Monoid (IO a) where
mappend x y = runConcurrently $ (<>) <$> Concurrently x <*> Concurrently y
mempty = return mempty
-- example:
action = getLine <> getLine
main = action >>= putStrLn
@LeifW
Copy link

LeifW commented Feb 1, 2014

Maybe not for IO... but for Concurrently?

import Control.Applicative ((<$>), (<*>), pure)
import Control.Concurrent.Async (Concurrently(..), runConcurrently)
import Data.Monoid (Monoid, (<>), mappend, mempty)

instance (Monoid a) => Monoid (Concurrently a) where
    mappend x y = (<>) <$> x <*> y
    mempty = pure mempty

-- example:
futureLine = Concurrently getLine

action = futureLine <> futureLine

main = runConcurrently action >>= putStrLn

I think in general you can generate Monoids from Applicatives like that.
The Monoid for Future is generated by calling Monoid.liftMonoid, which, given an Applicative[F] and a Monoid[M], returns a Monoid[F[M]].
https://github.com/scalaz/scalaz/blob/scalaz-seven/core/src/main/scala/scalaz/Monoid.scala#L101

And also vice-versa; I guess those are the dotted lines @tpolecat drew on this chart: http://leifwarner.net/scalaz.svg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment