首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >一个无点函数是共享的,但是计算了两次。

一个无点函数是共享的,但是计算了两次。
EN

Stack Overflow用户
提问于 2019-09-04 13:38:31
回答 1查看 204关注 0票数 14

我一直在努力了解Haskell中共享计算是如何工作的。根据我的理解,无分共享计算应该只评估一次(向CSE提供)。

(A)例如,考虑下列代码及其输出:

代码语言:javascript
复制
*Main> let foo = trace "eval foo" 5 in foo + foo
eval foo
10

*Main> let foo' = \x -> trace "eval foo'" x in (foo' 5) + (foo' 5)
eval foo'
eval foo'
10

正如预期的那样,foo只进行一次评估(CSE可能会启动),而foo'则被惰性地计算两次。这很好。我使用GHCi 7.6.3版本进行了上述操作。接下来,我在GHCi版本8.6.5中尝试了相同的代码,得到了这个结果:

代码语言:javascript
复制
*Main> let foo = trace "eval foo" 5 in foo + foo
eval foo
eval foo
10

注意,现在对foo进行了两次评估。

(B)与GHCi类似,7.6.3版:

代码语言:javascript
复制
*Main> let goo = const (trace "eval goo" 5) in goo () + goo ()
eval goo
10

但是,GHCi 8.6.5版对goo进行了两次评估:

代码语言:javascript
复制
*Main> let goo = const (trace "eval goo" 5) in goo () + goo ()
eval goo
eval goo
10

(C)最后,这两种版本的结果如下:

代码语言:javascript
复制
*Main> let foo_wrapper x = let foo = trace "eval foo" x in foo + foo
*Main> foo_wrapper 5
eval foo
10

我想知道GHCi-8中是否默认关闭了一些优化,还是trace强制foo的副作用以某种方式进行了两次评估?还是GHCi-7有问题?GHCi应该如何处理(A)和(B)这样的表达式?

(更新1)

对于场景(C),请考虑GHCi-8中的以下运行(trace的第二个参数的主要区别):

代码语言:javascript
复制
*Main> let foo_wrapper x = let foo = trace "eval foo" x in foo + foo 
*Main> foo_wrapper 5
eval foo
10
*Main> :t (foo_wrapper 5)
(foo_wrapper 5) :: Num a => a

*Main> let foo_wrapper' x = let foo = trace "eval foo" 5 in foo + foo 
*Main> foo_wrapper' ()
eval foo
eval foo
10
*Main> :t (foo_wrapper' ())
(foo_wrapper' ()) :: Num a => a
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-04 14:43:51

正如预期的那样,只对foo进行一次评估(CSE可能会启动)

不,这与CSE无关,它只是一个懒惰的评估(也就是按需要调用)的工作方式:foo是一个常量应用形式,因此它只需要计算一次(从一次被强制计算到WHNF),然后就可以被重用而不需要任何进一步的计算。这在GHCi-8中不再有效的原因是7.8已经删除了单态约束中的GHCi。为什么这是相关的?trace "eval foo" 5Num a => a类型的多态表达式。多态表达式不可能是CAF。因此,不必按需要调用,而是按名称调用语义。

再次获得共享的最简单方法是通过添加显式签名,使类型为单形,从而强制执行CAF:

代码语言:javascript
复制
    Prelude Debug.Trace> let foo = trace "eval foo" 5 :: Int in foo + foo
    eval foo
    10
票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57789663

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档