aqu*_*an9 2 haskell list lazy-evaluation lazy-sequences map-function
这是给出的问题:下表中的前8个元素是什么?
mystery = 0 : 10 : (map(+1)mystery)
Run Code Online (Sandbox Code Playgroud)
答案是 [0,10,1,11,2,12,3,13...]
但我认为答案应该是[0,10,1,11,1,11,2,12]。以下步骤显示了原因:
1)我们得到了; list,[0,10]因此在第一次应用该函数后,我们有了列表[ 0,10,1, 11]
2)现在有了一个列表[ 0,10,1,11]因此,在再次应用该函数后,结果列表应该是[0,10,1,11,1,11,2,12]
显然不是这样。谁能解释为什么?
在深入探讨的定义之前mystery,让我们看一下要map遵守的法律之一:
map f (map g xs) == map (f . g) xs
Run Code Online (Sandbox Code Playgroud)
此法的非正式证明很容易理解:
map f (map g [x1, x2, ..., xn]) == map f [g x1, g x2, ..., g xn]
== [f (g x1), f (g x2), ..., f (g xn)]
== [(f.g) x1, (f.g) x2, ..., (f.g) xn]
== map (f.g) [x1, x2, ..., xn]
Run Code Online (Sandbox Code Playgroud)
考虑到这一点,让我们mystery逐步扩展:
mystery == 0 : 10 : map (+1) mystery
-- by definition of mystery
== 0 : 10 : map (+1) (0 : 10 : map (+1) mystery)
-- by definition of map and the fact that 0 + 1 == 1
== 0 : 10 : 1 : map (+1) (10 : map (+1) mystery)
-- by definition of map and the fact that 10 + 1 == 11
== 0 : 10 : 1 : 11 : map (+1) (map (+1) mystery)
-- using the law above, and the fact that (+1) . (+1) == (+2)
== 0 : 10 : 1 : 11 : map (+2) mystery
== 0 : 10 : 1 : 11 : map (+2) (0 : 10 : map (+1) mystery)
== 0 : 10 : 1 : 11 : 2 : map (+2) (10 : map (+1) mystery)
== 0 : 10 : 1 : 11 : 2 : 12 : map (+2) (map (+1) mystery)
== 0 : 10 : 1 : 11 : 2 : 12 : map (+3) mystery
-- etc
Run Code Online (Sandbox Code Playgroud)
您不是从有限列表开始的[0, 10];您从以0和10 开头的无限列表开始,其余元素以递归方式定义。
从某种意义上说,列表没有封闭的形式,但这并不重要。懒惰意味着你只适用map于mystery为需要得到要求的项目。例如,既不head mystery也不是head (tail mystery)永远需要评估的呼吁map,并且head (tail (tail mystery))只需要映射(+1)到head mystery,而不是整个无限名单。
懒惰模糊了列表与计算列表的算法之间的区别。
| 归档时间: |
|
| 查看次数: |
113 次 |
| 最近记录: |