当前位置:  开发笔记 > 小程序 > 正文

为什么这样评估?

如何解决《为什么这样评估?》经验,为你挑选了1个好方法。

我有这个功能

doubleMe :: Num a => [a] -> [a]
doubleMe [] = []
doubleMe (x:xs) = (2*x):(doubleMe xs)

考虑一下:

doubleMe(doubleMe([1,2,3]))

显然,第一步是

doubleMe(doubleMe([1,2,3])) = doubleMe(2:doubleMe[2,3])

因为没有其他可能性.

这是我想知道的下一步.究竟是为什么

doubleMe(2:doubleMe[2,3]) = 4:(doubleMe(doubleMe([2,3])))

代替

doubleMe(2:doubleMe[2,3]) = doubleMe(2:4:doubleMe([3]))

到目前为止我唯一能够提出的答案是

因为它有道理.否则Haskell不会在列表上懒散地行事.

但这不是一个答案,而是一个问题.真正的答案是什么?



1> leftaroundab..:

显然,第一步是 doubleMe(doubleMe([1,2,3])) = doubleMe(2:doubleMe[2,3])

其实不是很明显!

为了区分,

doubleMe' = doubleMe

并考虑

doubleMe' $ doubleMe [1,2,3]

正如你所说,第一步的唯一原因,即

? doubleMe' $ 2 : doubleMe [2,3]

是因为doubleMe'需要能够以它的参数匹配要么[]_:_.为此,运行时开始计算doubleMe [1,2,3]一点,即一个递归步骤.产量2 : doubleMe [2,3]足以满足doubleMe':

? 4 : doubleMe' (doubleMe [2,3])

请注意,实际上该语言不需要此评估顺序:允许编译器对其进行重新排序(例如,出于性能原因),因此实际上内部列表会立即完全处理 - 如果它可以证明这不会改变语义,即对于一个无限的列表,doubleMe [1..]如果你只要求前几个结果,就不能陷入永恒的循环中.

GHC不进行此类重新排序.

推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有