ekmett / free

free monads
http://hackage.haskell.org/package/free
Other
161 stars 65 forks source link

instance {Monoid,Semigroup} ({,Co}Free f a) #152

Open Icelandjack opened 7 years ago

Icelandjack commented 7 years ago

Is there a use for those instances (and similar Free instances)?

instance (Semigroup a, Semigroup (f (Cofree f a))) => Semigroup (Cofree f a) where
  (a :< as) <> (b :< bs) = (a <> b) :< (as <> bs)

instance (Monoid a, Monoid (f (Cofree f a))) => Monoid (Cofree f a) where
  mempty = mempty :< mempty

  (a :< as) `mappend` (b :< bs) = (a `mappend` b) :< (as `mappend` bs)

These instances

instance (Monoid a, Monoid b) => Monoid (Cofree (Const a) b)
instance (Monoid a)           => Monoid (Cofree Identity  a)

correspond to

instance (Monoid a, Monoid b) => Monoid (a, b)
instance Monoid a             => Monoid (Stream a)
--                                  ^
-- https://github.com/Frege/frege/blob/master/frege/data/Stream.fr#L84

while sadly Semigroup a => Semigroup (Cofree Maybe a) does not correspond to Semigroup (NonEmpty a).

Icelandjack commented 7 years ago

Alternative instance based on Alternative

instance Functor f => Monoid (Free f a) where
  mempty = empty
  mappend = (<|>)
  mconcat as = from (as >>= to)
    where
      to (Plus xs) = xs
      to x       = [x]
      from [x] = x
      from xs  = Plus xs
andrewthad commented 7 years ago

It's worth pointing out that in your first post, you gave instances for Cofree and in the second one you gave instances for Free. I think the Cofree instances are clearly correct. In fact, I had just come here to request them as you have written them. (I haven't thought as much about the Free instance). @ElvishJerricco or @ekmett, would a PR be accepted for the Cofree instances?