1

I have this scala code:

trait Monoid[A] {
  def op(a1: A, a2: A): A
  def zero: A
}

val stringMonoid = new Monoid[String] {
  override def op(a1: String, a2: String): String = a1 + a2

  override def zero: String = ""
}

def listMonoid[A] = new Monoid[List[A]] {
  override def op(a1: List[A], a2: List[A]): List[A] = a1 ++ a2

  override def zero: List[A] = Nil
}

My question is if I change from def to val in this case, Scala will not compile:

var listMonoid[A] = new Monoid[List[A]] {
  override def op(a1: List[A], a2: List[A]): List[A] = a1 ++ a2

  override def zero: List[A] = Nil
}

Please explain for me this.

Trần Kim Dự
  • 5,872
  • 12
  • 55
  • 107

3 Answers3

1

A var stores a reference to a certain object (or a certain primitive value, to be complete). It doesn't make sense to have, for instance a

var list[A] = mutable.ListBuffer.empty[A]

Because it would enable you to treat the same instance of a list as different types of lists at the same time. Like in the following example:

val listInt = list[Int]
listInt += 42
val listString = list[String]
val str: String = listString.head // world implodes
Jasper-M
  • 14,966
  • 2
  • 26
  • 37
1

The problem there is that the listMonoid method is parametrized with the type A, that is not possible to do with a var or a val, you can not instanciate an object that is generic on the type, you need to specify what A is

var listMonoid = new Monoid[List[Any]] {
  override def op(a1: List[Any], a2: List[Any]): List[Any] = a1 ++ a2

  override def zero: List[Any] = Nil
}
Mikel San Vicente
  • 3,831
  • 2
  • 21
  • 39
0

Your assumption is wrong. Use of val or var will compile without error.

trait Monoid[A] {
  val op: (A, A) => A
  var zero: A
}

def listMonoid[A] = new Monoid[List[A]] {
  override val op = (a1: List[A], a2: List[A]) => a1 ++ a2
  override var zero: List[A] = Nil
}
jwvh
  • 50,871
  • 7
  • 38
  • 64
  • I think the question is not about the signature inside the trait, it's about moving from def listMonoid[A] to var listMonoid[A] – Mikel San Vicente Feb 20 '17 at 18:07
  • @Mikel, you could be right. It's not obvious what the OP is asking. The question should probably be closed as _unclear_. – jwvh Feb 20 '17 at 18:19