I wanna to describe a Type which can make add operation, so I defined this trait:

trait Addable[T] {

def +(v: T): T

def zero: T

}

but there’re 2 problems in this code:

- One type which should only have one zero element, so maybe I should define zero in object, but there’s not abstract object in scala, how can I define the unique zero in a class?
- If I defined a trait: IVector extends Addable[IVector], and I want to make type T of addable should be itself

It means X extends Addable[Y] is not allowed, you should only use X extends X, what should I do?

For (1), it sounds like you might actually want to make `Addable[T]`

a type

class, rather than a base class for types. The type class instance for a

given T can then provide the zero element.

For (2), i really can’t understand what you’re asking. I *think* you’re

asking how to make an `Addable`

container `IVector`

require that its

contained elements themselves be `Addable`

? If so, perhaps something like

`class IVector[T <: Addable[T]] extends Addable[IVector[T]]`

However, if `Addable`

were a typeclass, then you’d instead want to be able

to produce a typeclass instance for `IVector[T]`

given a typeclass instance

for `T`

. This would perhaps be an implicit on `IVector`

's companion

object, although other schemes are possible.

`-dave-`

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.

1 Like

It’s hard to understand (because I turned my Abstract Algebra to my teachers) but I believe it may be the solution of my problem and I’m trying to understand it.

Thank you and I had defined Addable like this now:

```
trait Addable[T <: Addable[T]] {
def +(v: T): T
def zero:T
}
```

but there’re some questions to solve……