gpt4 book ai didi

scala - 从不重新计算相同的部分评估两次的意义上说,部分函数应用程序可以是惰性的吗?

转载 作者:行者123 更新时间:2023-12-04 03:27:45 25 4
gpt4 key购买 nike

为什么部分评估在部分申请的那一刻没有严格评估,为什么要多次重新评估?
作为一个时髦的问题,Scala 和 Haskell 中的示例(有一刻我认为 Haskell 的行为会有所不同):

在斯卡拉:

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

最佳答案

在 Haskell 中,是的。你必须小心你的函数定义去糖的 lambda 表达式。例如

Prelude> import Debug.Trace
Prelude Debug.Trace> let f x = let x1 = trace "inside" x in \y -> x1 * y
Prelude Debug.Trace> let f2 = f 2
Prelude Debug.Trace> f2 3
inside
6
Prelude Debug.Trace> f2 3
6
Prelude Debug.Trace> f2 7
14

Sassa NF 建议的另一个示例。请注意,在 g trace "inside" succ每次调用都会重新创建闭包,而在 h关闭绑定(bind)到 h一劳永逸。 Eta 减少不保留 Haskell 中的操作语义!
Prelude Debug.Trace> let g = \x -> (trace "inside" succ) x :: Int
Prelude Debug.Trace> g 1
inside
2
Prelude Debug.Trace> g 2
inside
3
Prelude Debug.Trace> g 3
inside
4
Prelude Debug.Trace> let h = trace "inside" succ :: Int -> Int
Prelude Debug.Trace> h 1
inside
2
Prelude Debug.Trace> h 2
3
Prelude Debug.Trace> h 3
4

关于scala - 从不重新计算相同的部分评估两次的意义上说,部分函数应用程序可以是惰性的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21212336/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com