I realise that the answer may be that there are multiple valid such instances (as is the case for e.g. integers; sum, product, ...). Perhaps someone has a more satisfying answer than this?
As Joachim Breitner excellently explains in this answer How do you implement monoid interface for this tree in haskell? any applicative has a monoid instance:
mempty :: Applicative f => Monoid a => f a
mempty = pure mempty
mappend :: Applicative f => Monoid a => f a -> f a -> f a
mappend f g = mappend <$> f <*> g
So I was wondering why Data.Tree.Tree
from containers
does not have such an instance? Same argument could be used for any other monad without an accompanying monoid instance. It only seems natural to me that they should have such instances. Maybe this is not the case. I hope someone can enlighten me.
I suppose another reason could be that the instance I propose for trees is not "useful". This is as unsatisfying as the multiple valid instances argument in my opinion.
I don't know why it isn't available. However, the instance you propose is available once and for all via the Ap
newtype, which provides an instance (Applicative f, Monoid m) => Monoid (Ap f m)
. So if you need the instance you write, you can get it with this, even though it doesn't exist on the bare Tree
type.
There are multiple valid instances. Tree
also supports a "zippy" Applicative
with its corresponding Ap
-based monoid:
instance Applicative Tree where
pure a = let t = Node a (repeat t) in t
liftA2 f (Node a as) (Node b bs) =
Node (f a b) (zipWith (liftA2 f) as bs)
instance Semigroup a => Semigroup (Tree a) where
Node a as <> Node b bs =
Node (a <> b) (zipWith (<>) as bs)
instance Monoid a => Monoid (Tree a) where
mempty = Node mempty (repeat mempty)
I have no idea what instance, if any, would actually be useful.
Just for fun, here's a slightly silly one that just lifts the constructor over underlying monoids:
instance Semigroup a => Semigroup (Tree a) where
Node a as <> Node b bs = Node (a <> b) (as ++ bs)
instance Monoid a => Monoid (Tree a) where
mempty = Node mempty []
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With