T) = f; hello (() => 12)` compile, but `def hello (f: => Int) = f; hello (() => 12) `no? The following code can ...">

Why does "def hello [T] (f: => T) = f; hello (() => 12)` compile, but `def hello (f: => Int) = f; hello (() => 12) `no?

The following code can be compiled:

def hello[T](f: => T) = f
hello(() => 12)

      

But not the following:

def hello(f: => Int) = f
hello(() => 12)

      

What error messages:

<console>:9: error: type mismatch;
 found   : () => Int
 required: Int
                  hello(() => 12)

      

Why?

+1


source to share


2 answers


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.

+6


source


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

0


source







All Articles