object ExistentialTypesAsFunctionParameters extends App{
def m(p: T forSome {type T})=p.toString
def m1(p:Any)=p.toString
println(m("Hello"))
println(m1("Hello"))
}
This program runs and prints Hello
twice.
What is the difference between m
and m1
, is there any ?
What are the values that are allowed by the existential type T forSome {type T}
as compared to Any
?
Most importantly:
How can these questions be answered based on the Scala Language Specification ?
In other words, an explanation is needed in terms of the Scala Language Specification.
EDIT:
Follow up question:
class Top
class Middle extends Top {override def toString()="Middle"}
class Bottom extends Middle
object ExistentialTypesAsFunctionParameters extends App{
def m3(p: T forSome {type T >: Middle })=p.toString
println(m3(new Middle))
println(m3(new Bottom))
println(m3(new Top))
}
This code compiles and runs.
But I would expect println(m3(new Bottom))
not to compile because of the restriction T forSome {type T >: Middle }
that should mean that any value v
whose type can be a subtype of Middle
should not have the type T forSome {type T >: Middle }
.
So why does this code still compile ?