在Scala中的代号与Haskell中的懒惰评估?
Haskell的懒惰评估
will never采取更多的评估步骤而不是热切的评价.
另一方面,Scala的通过评估评估may require更多的评估步骤比通过值(如果短路利益被多次计算的成本抵消). 我认为call-by-name大概相当于懒惰的评估.那为什么这样的时间差在保证? 我猜猜Haskell语言可能指定在评估过程中必须使用回忆;但是在这种情况下,为什么Scala也不一样呢? 解决方法
评估策略的名称有一些广度,但大致来说,
>通过名称调用一个参数几乎只是被替换成函数体,以函数被调用的方式(未评估).这意味着它可能需要在身体中多次评估. 在斯卡拉,你写这样: scala> def f(x:=> Int): Int = x + x scala> f({ println("evaluated"); 1 }) evaluated evaluated 2 在Haskell中,您没有内置的方式来执行此操作,但您可以始终将名称值转换为type()的函数 – >一个.这是有点更加模糊,因为参考透明度 – 你将无法用Scala的方式测试(编译器可能会优化您的呼叫的“按名称”部分). 在Scala中,你不声明你的函数参数是懒惰的,你做出一个声明懒惰: scala> lazy x: Int = { println("evaluated"); 1 } scala> x + x evaluated 2 在Haskell中,这是默认情况下所有函数的工作原理. 在Scala中,这是默认情况下函数的工作原理. scala> def f(x: Int): Int = x + x scala> f({ println("evaluated"); 1 }) evaluated 2 在Haskell中,您可以通过函数参数上的bang模式强制执行此行为: ghci> :{ ghci> f :: Int -> Int ghci> f !x = x ghci> :} 所以如果通过需要(懒惰)进行或多或少的评估(作为其他策略之一),为什么要使用别的? 懒惰评估是很难推理的,除非你有参考透明度,因为那时你需要弄清楚你的懒惰值被评估.由于Scala是与Java进行互操作的,因此它需要支持强制性,副作用的编程.因此,在许多情况下,在Scala中使用懒惰并不是个好主意. 此外,懒惰具有性能开销:您需要有一个额外的间接来检查该值是否已经被评估.在Scala中,它转化成一堆更多的对象,这对垃圾收集器造成了更大的压力. 最后,有一些懒惰评估离开“空间”的情况.例如,在Haskell中,将大量的数字列表从右边折叠起来是一个坏主意,因为Haskell将在对它们进行评估之前,先建立一系列这种懒惰的调用(在现实中你只需要它一个累积器,即使在简单的上下文中,您获得的空间问题的一个着名例子是 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |