At the risk of using difficult words, here are my thoughts

what you need is a `Monoid`

*type class* and an extra *object* and *implicit class* to make `mzero`

and `|+|`

ready for use (they correspond to your `zero`

and `+`

).

```
trait Monoid[M] {
def mzero: M
def mappend(lhs: M, rhs: M): M
}
object Monoid {
def mzero[M: Monoid]: M = implicitly[Monoid[M]].mzero
}
object Ops {
implicit class MonoidOps[M: Monoid](lhs: M) {
def |+|(rhs: M): M = implicitly[Monoid[M]].mappend(lhs, rhs)
}
}
```

Now you can define instances

the most common for collections (like `List`

and friends) is

```
object ListMonoid {
implicit def listMonoid[M]: Monoid[List[M]] = new Monoid[List[M]] {
override def mzero: List[M] = List.empty
override def mappend(lhs: List[M], rhs: List[M]): List[M] = lhs ::: rhs
}
}
```

But, from your post, I understand that you want to make use of the fact that `M`

itself is a `Monoid`

.

I guess what you want is

```
object OtherListMonoid {
implicit def listMonoid[M: Monoid]: Monoid[List[M]] = new Monoid[List[M]] {
override def mzero: List[M] = ???
override def mappend(lhs: List[M], rhs: List[M]): List[M] =
lhs.zip(rhs).map {
case (lhs, rhs) => implicitly[Monoid[M]].mappend(lhs, rhs)
}
}
}
```

The problem is that it is not clear what `???`

should be.

For *stream*’s it could be an infinite stream of `implicitly[Monoid[M]].mzero`

's.