Почему `def hello[T](f: => T) = f; hello(()=>12)`компилируется, но`def hello(f: => Int) = f; привет (() => 12) `нет?

Следующий код может быть скомпилирован:

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

Но следующий не:

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

Который сообщает об ошибке:

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

Зачем?

2 ответа

Я бы сказал, потому что T может быть любым () => x, но Int не может быть () => x,

В вашей ситуации вы проходите () => 12 в качестве параметра, который является судебным иском, потому что T не имеет ограничений и может быть чем угодно, фактически возвращая частично примененную функцию:

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

scala> hello(()=>12)
res1: () => Int = <function0>

Что вы можете назвать так:

scala> res1()
res2: Int = 12

Во втором случае вместо этого вы передаете функцию из Unit в Int который не является Int (возвращает Int но это не Int).

Дело в том, что f передается как параметр по имени, здесь не имеет значения:

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)

Не путайте это: f: => T с этим: f: () => Tэто разные вещи, чтобы было понятно

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>

Теперь он компилируется в обоих случаях, потому что f это функция от Unit в T в первом случае (где T конечно может быть Int) и во втором случае f это функция от Unit в Int и вы можете пройти () => 12 в качестве параметра.

Это просто из-за того, что => T не то же самое, что () => T...

=> T это имя по имени, что означает

def hello(f: => Int) = f

Предполагается, что называется так:

hello(12)

Причина def hello[T](f: => T) = f работает с () => 12 потому что вы кладете в Function0[Int] на месте Т, который отличается от просто Int

Чтобы сделать () => Синтаксис работает, как и ожидалось, рассмотрите возможность сделать это:

def hello(f: () => Int) = f // can also be written as:
def hello(f: Function0[Int]) = f

Теперь ваша функция ожидает Function0где это не было раньше, и hello(() => 12) будет работать как положено

Другие вопросы по тегам