Почему частичная оценка не строго оценивается в момент частичного применения и почему она переоценивается более одного раза? Как вопрос о хипстере, примеры из Scala и Haskell (на мгновение я думал, что Haskell будет вести себя по-другому):
В Scala:
scala> def f(x: Int)(y: Int) = {println("inside"); x * y}
f: (x: Int)(y: Int)Int
scala> val f2 = f(2) _
f2: Int => Int = <function1>
scala> f2(3)
inside //internals of f calculated for the first time
res7: Int = 6
scala> f2(7)
inside //internals of f recalculated
res8: Int = 14
В Haskell:
Prelude> import Debug.Trace
Prelude Debug.Trace> let f x y = trace "inside" x * y
Prelude Debug.Trace> let f2 = f 2
Prelude Debug.Trace> f2 3
inside //internals of f calculated for the first time
6
Prelude Debug.Trace> f2 3
inside //internals of f recalculated
6
Prelude Debug.Trace> f2 7
inside //internals of f recalculated
14
Я знаю, что можно переопределить f
, чтобы вернуть функцию, как в коде ниже, но было бы интересно, чтобы функции, которые действительно были частично оценены даже до того, как они были полностью оценены:
scala> def f(x: Int) = {println("inside"); (y:Int) => x * y}
f: (x: Int)Int => Int
scala> val f2 = f(2)
inside //internals of f calculated only this time
f2: Int => Int = <function1>
scala> f2(3)
res12: Int = 6
scala> f2(7)
res13: Int = 14