In scala, functions are covariant in their output type, and contravariant in their input type.
For example, if Dog
is a subtype of Animal
, then
T => Dog
is a subtype of T => Animal
, and
Animal => T
is a subtype of Dog => T
In other words, a producer of Dog
can go where a producer of Animal
is expected, and
a consumer of Animal
can go where a consumer of Dog
is expected.
So why do I get this compile error:
def useF(f: Nothing => Unit): Unit = ()
def f(x: Unit): Unit = ()
useF(f) // ok
useF(() => ()) // error
/*
example.scala:4: error: type mismatch;
found : () => Unit
required: Nothing => Unit
useF(() => ())
*/
I thought that Nothing
is a subtype of Unit
, so () => ()
should be a subtype of Nothing => ()
, since () => ()
is of type Unit => Unit
. What is the difference in type signature between f
and () => ()
?
Your logic is correct. Just syntax is wrong.
() => T
is notFunction1[Unit, T]
. It is actually a syntax for lambda with no argument which results inFunction0[T]
. The parenthesis here is not Unit. It's a syntax to denote zero argumentsThe correct way to construct a
Unit => Unit
is:You can add explicit type annotation to verify: