Reputation: 2270
Suppose I have an interface for a Thing
:
abstract class Thing[A](a_thing: A) {
def thingA = a_thing
}
and I implement that Thing
as follows:
class SpecificThing(a: String) extends Thing[String](a)
Furthermore, suppose I have a function that takes a Thing
and a lambda that does something to that Thing
as parameters:
def doSomething[A](fn: Thing[A] => A, t: Thing[A]) : A = fn(t)
Now, let's use this stuff:
val st = new SpecificThing("hi")
val fn1: (Thing[String]) => String = (t: Thing[String]) => { t.thingA }
println(doSomething(fn1, st))
This prints hi
. So far, so good. But I'm lazy, and I don't like typing so much, so I change my program to the following:
type MyThing = Thing[String]
val st = new SpecificThing("hi")
val fn2: (MyThing) => String = (t: MyThing) => { t.thingA }
println(doSomething(fn2, st))
and this also prints hi
. Fabulous! The compiler can tell that a SpecificThing
is both a Thing[String]
and a MyThing
. But what about this case?
val st = new SpecificThing("hi")
val fn3: (SpecificThing) => String = (t: SpecificThing) => { t.thingA }
println(doSomething(fn3, st))
Now I get:
Error:(14, 23) type mismatch;
found : SpecificThing => String
required: Thing[?] => ?
println(doSomething(fn3, st))
^
What's going on? What's a Thing[?]
?
Upvotes: 1
Views: 99
Reputation: 17431
f3
isn't a Thing[String] => String
, it's a SpecificThing => String
. For an example of why they couldn't be compatible:
class SpecificThing2 extends Thing[String] {
def thingB = 2.0
}
val f4: SpecificThing2 => String = {
st: SpecificThing2 => f"%f${st.thingB / 3.0}"
}
val t = new Thing[String]("haha"){}
f4(t) // would be an error when f4 tried to access t.thingB
More formally, Function1
is contravariant in its first type parameter, Function1[-T, +R]
.
A Thing[?]
is what it looks like; it's a Thing[X]
for some unknown type X
. The compiler is gamely trying to infer what the type A
should be, but it can't make it work: it needs a Thing[A] => A
for some (unknown-to-it) type A
, and you're passing it a SpecificThing => String
; that's the error.
Upvotes: 6