stella stella - 3 months ago 10
Scala Question

A <:< SomeType parameter declaration

Looking at

scala.Option
sources I found the following implicit parameter declaration
implicit ev: Null <:< A1
. So, trying it myself

class Test[T](val i: Int){
def test(p: T <:< Option[Int]) = 1
}


I found that
p
looks like a
Function1
. It has
apply
,
andThen
etc methods. What would be the difference if we wrote:

class TestMatch[T](val i: Int){
def test(p: T <:< Option[Int]) = //..
def test2(p: T => Option[Int]) = //...
}


Is there some principal difference between singatures of
test
and
test2
? This example beahves is this:

tm.test2(x => { //fine
println(x)
Some(x)
})

tm.test(x => { //Compile error
println(x)
Some(x)
})


I also tried this:

tm.test(x <:< { //Compile error
println(x)
Some(x)
})


but it didn't work either. How to use
test
?

Answer

I found that p looks like a Function1

<:< is defined as:

sealed abstract class <:<[-From, +To] extends (From => To) with Serializable

Which is a derived of Function1[From, To], and that's where you're seeing apply and andThen come from. <:< means a generic parameter type constraint, where T is a subtype of Option[Int].

Generally, <:< is meant to be used as a type constraint which forces an implicit evidence to be in scope:

An instance of A <:< B witnesses that A is a subtype of B. Requiring an implicit argument of the type A <:< B encodes the generalized constraint A <: B.


But couldn't you explain who creates this implicit <:< parameter? Where did it come from? I guess compiler's aware about <:< and know what to do with it

In your example, there is no implicit evidence created. You're simply using <:< as a type, not a constraint. If you wanted to create one, you'd need to do it yourself by declaring the implicit:

def greaterThan[T](x: T, y: T)(implicit ev: T <:< Ordered[T]): Boolean = x > y
Comments