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.

3
  • val is used for constant values, var for changeable variables, and def for declaring a function. Commented Feb 20, 2017 at 17:15
  • And in your second example, you said you're using val, but I only see a var. Commented Feb 20, 2017 at 17:16
  • The other question and answers say nothing about generics, but that is being asked about here. Commented Feb 20, 2017 at 19:19

3 Answers 3

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
}
Sign up to request clarification or add additional context in comments.

Comments

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

Comments

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
}

2 Comments

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, you could be right. It's not obvious what the OP is asking. The question should probably be closed as unclear.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.