Works:
trait Transformer[A, B] {
def transform(a: A): B
}
class TransformerImpl extends Transformer[Int, String] {
override def transform(value: Int): String = {
value.toString
}
}
This is what I want, because the trait having one parameter is simpler and because the concrete value of B is determined by A. However, it does not work.
trait Transformer2[A] {
def transform[B](a: A): B
}
class Transformer2Impl extends Transformer2[Int] {
override def transform[String](value: Int): String = {
value.toString
}
}
Error:
-- [E007] Type Mismatch Error: --------
3 | value.toString
| ^^^^^^^^^^^^^^
| Found: String
| Required: String
This too, with a different method signature, does not work:
class Transformer2IntToIntImpl extends Transformer2[Int] {
override def transform(value: Int): Int = {
value
}
}
Error:
-- Error: ----------------------------------------------------------------------
1 |class Transformer2IntToIntImpl extends Transformer2[Int] {
| ^
|class Transformer2IntToIntImpl needs to be abstract, since def transform[B](a: A): B in trait Transformer2 is not defined
|(Note that
| parameter A in def transform[B](a: A): B in trait Transformer2 does not match
| parameter Int in override def transform(value: Int): Int in class Transformer2IntToIntImpl
| )
-- [E038] Declaration Error: ---------------------------------------------------
2 | override def transform(value: Int): Int = {
| ^
|method transform has a different signature than the overridden declaration
|-----------------------------------------------------------------------------
2 errors found
Based on the errors, I tried several alternatives, but with no success.
This worked for me:
trait Transformer2[A] {
type B
def transform(a: A): B
}
class Transformer2Impl extends Transformer2[Int] {
type B = String
override def transform(value: Int): String = {
value.toString
}
}
class Transformer2IntToIntImpl extends Transformer2[Int] {
type B = Int
override def transform(value: Int): Int = {
value
}
}
val ans1 = new Transformer2Impl().transform(5)
// val ans1: String = 5
val ans2 = new Transformer2IntToIntImpl().transform(5)
// val ans2: Int = 5
I would still like to know if the original code failed - albeit with convoluted error messages - because it is syntactically incorrect.