trace可以给出折叠处理的"反转"

Mik*_*MES 7 haskell

当我编译"修改后的总和"(«_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.
Run Code Online (Sandbox Code Playgroud)

...并将其应用于'[1..5]',我得到:

*Main > _sum ([1..5])

* 1 - 0
* 2 - 1
* 3 - 3
* 4 - 6
* 5 - 10
* 15
* it :: Integer
Run Code Online (Sandbox Code Playgroud)

('foldl'过程的顺序没问题......)

如果我删除<++" - "++ show acc>,我得到:

(我们只有<trace(show x)>)

*Main > _sum ([1..5])

* 5
* 4
* 3
* 2
* 1
* 15
* it :: Integer
Run Code Online (Sandbox Code Playgroud)

...:<[1..5]>('x')内部元素的处理顺序似乎已被反转(它是'foldl')......!

这是什么意思 ?

Eri*_*ikR 5

表达式foldl (+) 0 [1..3]创建以下表达式树:

              +
             / \
            +   3
           / \
          +   2
         / \
        0   1
Run Code Online (Sandbox Code Playgroud)

在你的情况下,_sum_sum2建立一个这样的树:

              tr
             / \
            tr  3
           / \
          tr   2
         / \
        0   1
Run Code Online (Sandbox Code Playgroud)

tr是折叠中的功能,用于累积和跟踪.

_sum2

要访问的第一个操作是tr ___ 3在树的顶部.3是x和___ acctr函数中.

当这发生在_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.