In Scala, why can I use `Unit` as return type here?

functional-programming, java, scala, type-inference, types

Solution

Scala will automatically insert `()` (the singleton `Unit` value) in this case to make the typechecking work. So what you have is equivalent to:

def f(x:Int => Unit):Unit = { 1; () }

This is known as "value discarding" in Scala. From the spec:

Value Discarding

If `e` has some value type and the expected type is `Unit`, `e` is converted to the expected type by embedding it in the term `{ e; () }`

Like in many programming languages, this is meant to facilitate just "throwing out" the return value of the expression. This allows you to make a method of type `Unit` that only uses the side effects of an expression.

Problem

The codes are below: ``` scala> def f(x:Int => Unit):Unit = 1 <console>:7: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses def f(x:Int => Unit):Unit = 1 ^ f: (x: Int => Unit)Unit scala> f(_=>2); <console>:9: warning: a pure expression does nothing in statement position; you may be omitting necessary parentheses f(_=>2); ^ scala> f(_=>List(1,2)); ``` All three expressions above worked in REPL(with some warnings), but they look a bit confusing.. In the first expression, `f`'s return type is `Unit`, which is the subtype of `AnyVal` but not the Supertype of `Int`, therefore, I can't understand why `1` can be used as the returned value. In the second expression, `_=>2` also used `2` instead of `Unit` as the returned value, which conflicts with the definition. In the third expression, `_=> List(1,2)` even uses `List`, subtype of `AnyRef` as the returned value, but the REPL still doesn't complain about this.. Does anyone have ideas about why `Unit` can tolerate the non-subtype type conversion here? Thanks!

Original source