I am struggling a little with scala 2.12:
I have the following hierarchy:
trait A
case class B(format: String) extends A
trait Writer {
def write(config: A): Unit
}
val writer = new Writer {
override def write(config: A) = println("hi")
}
val w = B("console")
writer.write(w)
which works fine. But I want to provide an alternate implementation for writer:
val writer = new Writer {
override def write(config: B) = println("hi")
}
But I get object creation impossible, since method write in trait Writer of type (config: Playground.A)Unit is not defined
I assumed that since B is an A, this should work. How can I override write with a config of type B where B <: A
Scastie: https://scastie.scala-lang.org/QBaiiDP4Sj2lptUjrWLJYw
EDIT: ------------------------------------------------------------
Based on some inputs, I changed the implementation to:
sealed trait A
case class B(format: String) extends A
trait Writer[+T] {
def write[S >: T](config: S): Unit
}
val writer: Writer[A] = new Writer[B] {
override def write[B](config: B) = println("hi")
}
val b = B("console")
writer.write(b)
which works.
But if I modify it to access the variables in config, it breaks:
sealed trait A
case class B(format: String) extends A
trait Writer[+T] {
def write[S >: T](config: S): Unit
}
val writer: Writer[A] = new Writer[B] {
override def write[B](config: B) = println(config.format)
}
val b = B("console")
writer.write(b)
with value format is not a member of type parameter B
https://scastie.scala-lang.org/Xj2rKbbiTmG7raZgQZYfHA
Appreciate the inputs.
You're very close with your latest version. As Matthias Berndt pointed out, the
writemethod declares a new type parameter, but should use the one declared on the trait. In addition, the type parameter should be contravariant.This code compiles and prints
console:Note that, because
Bis a subtype ofA, you can also use aWriter[A]with an instance ofB. BecauseWriteris contravariant, you can assign a value of typeWriter[A]to a variable of typeWriter[B]:You can't do the opposite (assign a
Writer[B]value to aWriter[A]variable) because aWriter[A]would be able to accept any value of typeA, while aWriter[B]can only accept values of typeB.https://scastie.scala-lang.org/TimMoore/bd5E1p99TLCDVfMbElKqFg/8