How can I describe an this type subjection in Scala?

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:

  1. 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?
  2. 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.


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] = {
        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.

  1. How can I ensure there’s only one zero in a class,
    case class DoubleValue(var value: Double) entends Addable {
    override def +(v: DoubleValue) = DoubleValue(value + v.value)
    val zeroVal = DoubleValue(value)
    override def zero = zeroVal
    It’s dumb but every DoubleValue I got have different “zero”.

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……