简体   繁体   中英

Why does Data.Tree.Tree not have a monoid instance?

I realise that the answer may be that there are multiple valid such instances (as is the case for eg 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 fm) . 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 []

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM