joh*_*mos 5 debugging trace haskell fold
myReverse :: [a] -> [a]
myReverse = foldl (\a x -> x:a) []
foldl is (a -> b -> a) -> a -> [b] -> a
Run Code Online (Sandbox Code Playgroud)
lambda函数显然在括号中.从哪里foldl
获得其初始值?什么是[b]
在这种情况下?
例如,我们可以逐步进行评估myReverse [1,2,3]
。我们需要定义foldl
foldl f z [] = z
foldl f z (x:xs) = foldl f (f z x) xs
Run Code Online (Sandbox Code Playgroud)
所以我们有
myReverse [1,2,3,4]
-- definition of myReverse
= foldl (\a x -> x:a) [] [1,2,3]
-- definition of foldl (x:xs case)
= foldl (\a x -> x:a) ((\a x -> x:a) [] 1) [2,3]
-- beta reduction [1]
= foldl (\a x -> x:a) [1] [2,3]
-- definition of foldl
= foldl (\a x -> x:a) ((\a x -> x:a) [1] 2) [3]
-- beta reduction
= foldl (\a x -> x:a) [2,1] [3]
-- definition of foldl
= foldl (\a x -> x:a) ((\a x -> x:a) [2,1] 3) []
-- beta reduction
= foldl (\a x -> x:a) [3,2,1] []
-- definition of foldl ([] case)
= [3,2,1]
Run Code Online (Sandbox Code Playgroud)
[1] 中的重要警告是,对于每个 beta 减少步骤,这种 beta 减少实际上仅在仔细检查结果时才会发生。随着foldl
进展,重复应用f
build up 作为 thunk,所以我们真正得到的(如果f = \a x -> x:a
)是:
foldl f [] [1,2,3]
foldl f (f [] 1) [2,3]
foldl f ((f 2 (f [] 1))) [3]
foldl f (((f 3 ((f 2 (f [] 1)))))) []
(((f 3 ((f 2 (f [] 1))))))
Run Code Online (Sandbox Code Playgroud)
这就是为什么我们有foldl'
,它的累加器很严格,可以防止这种 thunk 累积。
初始值为[]
。本例中的与in[b]
相同,即in 。a
foldl
[a]
myReverse
归档时间: |
|
查看次数: |
157 次 |
最近记录: |