加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在Scala中的代号与Haskell中的懒惰评估?

发布时间:2020-12-16 19:00:46 所属栏目:安全 来源:网络整理
导读:Haskell的懒惰评估 will never采取更多的评估步骤而不是热切的评价. 另一方面,Scala的通过评估评估may require更多的评估步骤比通过值(如果短路利益被多次计算的成本抵消). 我认为call-by-name大概相当于懒惰的评估.那为什么这样的时间差在保证? 我猜猜Hask
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的方式测试(编译器可能会优化您的呼叫的“按名称”部分).
>需要调用(lazy … sort)当函数被调用时,参数不被评估,但是第一次是需要的.在那一刻,它也被缓存.之后,只要再次需要参数,就会查找缓存的值.

在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将在对它们进行评估之前,先建立一系列这种懒惰的调用(在现实中你只需要它一个累积器,即使在简单的上下文中,您获得的空间问题的一个着名例子是foldr vs foldl vs foldl'.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读