Scala по параметрам имени с несколькими списками аргументов и currying

В Scala (2.9.2) Я пытаюсь создать функцию, которая предоставляет другое значение при доступе

() => Any

Я думал, что успешно делаю это через решение по имени/карри:

def byName(theValue : => Any)() : Any = theValue
val myHolder = byName(myValue)_

Итак, мой держатель имеет правильный тип. Однако я обнаружил, что в процессе создания этой карри-функции оценивается параметр name. Если я делаю следующее, то он работает по-своему:

def byName(theValue : => Any) : Any = () => theValue
val myHolder = byName(myValue)

Я заключаю, что часть процесса currying ссылается на первый список параметров и вызывает его оценку. Может ли кто-нибудь подтвердить это и/или объяснить, почему или если существуют какие-либо рекомендации по использованию параметров имени с несколькими списками параметров?

Ответ 1

Это кажется ошибкой для меня. Я мог бы вызвать это странное поведение в scala 2.9.1, но не в scala 2.10 RC1, поэтому я предполагаю, что это было исправлено в какой-то момент.

В scala 2.9.1:

Welcome to Scala version 2.9.1.final (Java HotSpot(TM) Client VM, Java 1.6.0_27).
Type in expressions to have them evaluated.
Type :help for more information.
scala> def byName(theValue : => Any)() : Any = theValue
byName: (theValue: => Any)()Any
scala> def myValue: String = { println("Computing myValue"); "hello" }
myValue: String
scala> val myHolder = byName(myValue)_
Computing myValue
myHolder: () => Any = <function0>
scala> myHolder()
res0: Any = hello

В scala 2.10-RC1:

Welcome to Scala version 2.10.0-RC1 (Java HotSpot(TM) Client VM, Java 1.6.0_27).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def byName(theValue : => Any)() : Any = theValue
byName: (theValue: => Any)()Any
scala> def myValue: String = { println("Computing myValue"); "hello" }
myValue: String
scala> val myHolder = byName(myValue)_
myHolder: () => Any = <function0>
scala> myHolder()
Computing myValue
res0: Any = hello

Ответ 2

Проблемы https://issues.scala-lang.org/browse/SI-302 а также https://issues.scala-lang.org/browse/SI-5610

Лично я нахожу, что теперь "старое" поведение более интуитивно понятное: частичное приложение означает, что что-то применяется.

Или, как это сделал Одерский:

Нет, это то, как определяется расширение eta. Вы не просто обертываете лямбдой вокруг выражения, вы сначала оцените, что можете.

Но, наоборот, легче заставить оценивать, чем разрабатывать синтаксис для его приостановки.