Why does "def hello [T] (f: => T) = f; hello (() => 12)` compile, but `def hello (f: => Int) = f; hello (() => 12) `no?
I would say because it T
can be anything () => x
, but Int
it cannot be () => x
.
In your situation, you are passing () => 12
as a parameter, which is a legal action because it T
has no restrictions and can be anything, in fact it returns a partial application function:
scala> def hello[T](f: => T) = f
hello: [T](f: => T)T
scala> hello(()=>12)
res1: () => Int = <function0>
You can do it like this:
scala> res1()
res2: Int = 12
In the second case, you are passing a function from Unit
to Int
, which is not Int
(it returns Int
, but is not Int
).
The fact that it f
is passed as a name-by-name parameter is irrelevant here:
scala> def hello[T](f: T) = f
hello: [T](f: T)T
scala> hello(()=>12)
res11: () => Int = <function0>
scala> def hello(f: Int) = f
hello: (f: Int)Int
scala> hello(()=>12)
<console>:9: error: type mismatch;
found : () => Int
required: Int
hello(()=>12)
Don't confuse this: f: => T
with this:, f: () => T
they are different things to make it clear:
scala> def hello[T](f: () => T) = f
hello: [T](f: () => T)() => T
scala> hello(()=>12)
res13: () => Int = <function0>
scala> def hello(f: () => Int) = f
hello: (f: () => Int)() => Int
scala> hello(()=>12)
res14: () => Int = <function0>
Now it will compile in both cases, because it f
is a function from Unit
to T
in the first case (where it T
can, of course Int
), and in the second case it f
is a function from Unit
to Int
, and you can pass it () => 12
as a parameter.
source to share
This is simply due to => T
not being the same as () => T
...
=> T
is a call by name, which means
def hello(f: => Int) = f
It is supposed to be called like this:
hello(12)
The reason it def hello[T](f: => T) = f
works with () => 12
is that you are putting Function0[Int]
on a T-point that is different fromInt
To make the syntax () =>
work as expected, consider this:
def hello(f: () => Int) = f // can also be written as:
def hello(f: Function0[Int]) = f
NOW your function expects Function0
where it is not before, but hello(() => 12)
will work as expected
source to share