当参数是一个列表时,lazy函数会立即通过参数吗?

时间:2018-06-18 11:45:27

标签: haskell lazy-evaluation

假设您有一个不可变的数字列表xs = [1,2,3,4,5,6,7,8]和一个函数 doubleMe ,它将每个元素乘以2然后返回一个新列表。

当我们调用doubleMe(doubleMe(doubleMe(xs)))时,懒惰函数将如何工作?

doubleMe([1,2,3,4,5,6,7,8]) -> doubleMe(doubleMe([1,2,3,4,5,6,7,8])) -> doubleMe(doubleMe(doubleMe([1,2,3,4,5,6,7,8])))

doubleMe(doubleMe(doubleMe(1))) -> doubleMe(doubleMe(doubleMe(2))) -> ... -> doubleMe(doubleMe(doubleMe(8)))

1 个答案:

答案 0 :(得分:4)

假设doubleMe被懒惰地实施,它的评估如下:

doubleMe (doubleMe (1:2:3:[]))
= doubleMe (2 : doubleMe (2:3:[]))
= 4 : doubleMe (doubleMe (2:3:[]))
= 4 : doubleMe (4 : doubleMe (3:[]))
= 4 : 8 : doubleMe (doubleMe (3:[]))
= 4 : 8 : doubleMe (6 : doubleMe [])
= 4 : 8 : 12 : doubleMe (doubleMe [])
= 4 : 8 : 12 : doubleMe []
= 4 : 8 : 12 : []

有三个嵌套调用,而不是两个,评估是类似的。

基本上,评估策略会找到最外层 doubleMe调用,该调用具有弱头正常形式的参数 - 即[]或{{1}形式}}。然后它应用定义:

x : xs