Reputation: 1
I have a Scala pre-examination question which I cannot get through. Probably someone could help.
Does the expression on the right conforms to the declared type, and why?
(a) val x1: B => D = (b: A) => new D
(b) val x2: A => C => D = (a: A) => (b: D) => new C
(c) val x3: (D => B) => A = (db: D => A) => new B
The class hierarchy:
class A
class B extends A
class C
class D extends C
Upvotes: 1
Views: 154
Reputation: 1301
Mb there is an answer, which has more information then needed.
when we write T => F
-- it means a function type, sugar for a trait Function1[-P, +R] { def apply(p: P): R }
when we write (t: T) => new F
it means a lambda function, which has a type T => F
, or (alias, sugar) Function1[T, F]
, as you can notice t
is an application argument.
we have relations on types, one of them is sub typing, so you need an explanation of function sub typing in this task.
Let's consider why code, provided here by @ChrisMartin, compiling.
So function, is a trait:
trait Function1[-P, +R] {
def apply(p: P): R
}
That means that function is contravariant (+
) by argument and covariant (-
) by result.
Let F: P → R, p ∈ P => F(p) ∈ R
, and let F' : P' → R' : P' ⊃ P, R' ⊂ R'
. Then, p ∈ P => p ∈ P' => F'(p) ∈ R'=> F'(p) ∈ R
.
That means that F'
function is a special case of F
function on its domain. In other words some function from a super type of P
to the sub type of R
is a subtype of function from P
to R
.
In your examples:
B => D
is a more general function then A => D
(A
is a super type of B
) (check: implicitly[(A => D) <:< (B => D)]
)A => C => D
is a more specific function then A => D => C
(check: implicitly[(A => C => D) <:< (A => D => C)]
)(D => B) => A
is a more general function then (D => A) => B
(check: implicitly[((D => A) => B) <:< ((D => B) => A)]
)Upvotes: 0
Reputation: 30736
You don't need us for this. Just paste the code into the REPL.
scala> class A
defined class A
scala> class B extends A
defined class B
scala> class C
defined class C
scala> class D extends C
defined class D
scala> val x1: B => D = (b: A) => new D
x1: B => D = <function1>
scala> val x2: A => C => D = (a: A) => (b: D) => new C
<console>:10: error: type mismatch;
found : C
required: D
val x2: A => C => D = (a: A) => (b: D) => new C
^
scala> val x3: (D => B) => A = (db: D => A) => new B
x3: (D => B) => A = <function1>
Upvotes: 1
Reputation: 50
I guess that there is no correct expression amongst them.
Upvotes: 0