当我编译"修改后的总和"(«_sum_folds.hs»)文件时:
*--------------------------- [
import Debug.Trace 
_sum = 
    foldl ( \ acc x -> 
            trace (
              show x
              ++ " - " ++ show acc
              )
          acc + x
        ) 
        0
*--------------------------- ]
[1 of 1] Compiling Main             ( _sum_folds .hs, interpreted )
Ok, modules loaded: Main.
...并将其应用于'[1..5]',我得到:
*Main > _sum ([1..5])
* 1 - 0
* 2 - 1
* 3 - 3
* 4 - 6
* 5 - 10
* 15
* it :: Integer
('foldl'过程的顺序没问题......)
如果我删除<++" - "++ show acc>,我得到:
(我们只有<trace(show x)>)
*Main > _sum ([1..5])
* 5
* 4
* 3
* 2
* 1
* 15
* it :: Integer
...:<[1..5]>('x')内部元素的处理顺序似乎已被反转(它是'foldl')......!
这是什么意思 ?
表达式foldl (+) 0 [1..3]创建以下表达式树:
              +
             / \
            +   3
           / \
          +   2
         / \
        0   1
在你的情况下,_sum并_sum2建立一个这样的树:
              tr
             / \
            tr  3
           / \
          tr   2
         / \
        0   1
这tr是折叠中的功能,用于累积和跟踪.
要访问的第一个操作是tr ___ 3在树的顶部.3是x和___ acc在tr函数中.
当这发生在_sum23打印.
然后acc进行评估,因此tr ___ 2进行评估,结果显示为2.
然后tr ___ 1进行评估,因此打印1.
然而,在_sum不同的事件过程中展开(没有双关语意).
我们再次从树顶开始:tr ___ 3.
步骤1) 
因为在_sum你也打印出来acc,Haskell需要评估它,即tr ___ 2.评估完成后,将打印出来acc然后打印3.
步骤2) 
为了评估tr ___ 2,因为你打印出来acc,Haskell需要评估它,即2左边的树 - 即tr ___ 1.评估完成后,将打印出来acc然后打印2.
步骤3) 
为了评估tr ___ 1,因为你正在打印出来acc,Haskell需要评估1左边的树,即0.当这个评估完成时,它将打印出来acc,然后是1.在这种情况下,0已被评估,所以它打印出0然后打印1.
然后控制转回到步骤2并acc显示(1)然后显示2.
然后控制转回到步骤1并acc显示(3)和3.
| 归档时间: | 
 | 
| 查看次数: | 74 次 | 
| 最近记录: |