Ray Standers
Ray Standers

Reputation: 1

Type definitions in Scala

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

Answers (3)

DaunnC
DaunnC

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

Chris Martin
Chris Martin

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

Michael Nedokushev
Michael Nedokushev

Reputation: 50

I guess that there is no correct expression amongst them.

Upvotes: 0

Related Questions