11

Scala (2.9.2) では、アクセス時に他の値を提供する関数を作成しようとしています

() => Any

名前/カリー化ソリューションを介してこれをうまくやっていると思いました:

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

だから私のホルダーは正しいタイプです。ただし、このカリー化された関数を作成する過程で、名前によるパラメーターが評価されることがわかりました。代わりに次のようにすると、意図したとおりに機能します。

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

カリー化プロセスの一部は、最初のパラメーター リストを参照し、その評価をトリガーしていると結論付けています。誰かがそれを確認および/または説明できますか、または複数のパラメーターリストで名前パラメーターを使用することに関するガイドラインがあるかどうかを説明できますか?

4

2 に答える 2

3

これは私にはバグのようです。この奇妙な動作はscala2.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
于 2012-11-06T09:03:04.040 に答える
2

問題は https://issues.scala-lang.org/browse/SI-302 および https://issues.scala-lang.org/browse/SI-5610です。

個人的には、現在の「古い」動作の方がより直感的だと思います。部分適用とは、何かが適用されることを意味します。

または、Oderskyが持っていたように:

いいえ、それが eta 拡張の定義方法です。式をラムダでラップするだけでなく、最初に何ができるかを評価します。

しかし逆に、評価を一時停止するための構文を考案するよりも、評価を強制する方が簡単です。

于 2012-11-06T09:30:42.970 に答える