Consider the following method which takes type parameter of * -> *
kind
def g[F[_]] = ???
Why is the following not a syntax error
g[Any] // ok
g[Nothing] // ok
since
scala> :kind -v Any
Any's kind is A
*
This is a proper type.
scala> :kind -v Nothing
Nothing's kind is A
*
This is a proper type.
so Any
and Nothing
should be of wrong shape?
Quotes from Scala spec:
For every type constructor
π
(with any number of type parameters),scala.Nothing <: π <: scala.Any
.
https://scala-lang.org/files/archive/spec/2.13/03-types.html#conformance
Say the type parameters have lower bounds
πΏ1,β¦,πΏπ
and upper boundsπ1,β¦,ππ
. The parameterized type is well-formed if each actual type parameter conforms to its bounds, i.e.ππΏπ<:ππ<:πππ
whereπ
is the substitution[π1:=π1,β¦,ππ:=ππ]
.
https://scala-lang.org/files/archive/spec/2.13/03-types.html#parameterized-types
A polymorphic method type is denoted internally as
[tps]π
where[tps]
is a type parameter section[π1 >: πΏ1 <: π1,β¦,ππ >: πΏπ <: ππ]
for someπβ₯0
andπ
is a (value or method) type. This type represents named methods that take type argumentsπ1,β¦,ππ
which conform to the lower boundsπΏ1,β¦,πΏπ
and the upper boundsπ1,β¦,ππ
and that yield results of typeπ
.
https://scala-lang.org/files/archive/spec/2.13/03-types.html#polymorphic-method-types
So since Any
and Nothing
conform to upper and lower bounds of F[_]
(namely, Any
and Nothing
correspondingly), g[Any]
and g[Nothing]
are legal.