下面,据说foldl'都是严格版的foldl。
但是我很难理解,strict是什么意思??
foldl f z0 xs0 = lgo z0 xs0
         where
            lgo z []     =  z
            lgo z (x:xs) = lgo (f z x) xs
foldl' f z0 xs0 = lgo z0 xs0
    where lgo z []     = z
          lgo z (x:xs) = let z' = f z x in z' `seq` lgo z' xs发布于 2013-01-11 21:54:56
foldl和(严格的) foldl‘在语义上几乎是等价的。不同之处在于性能,特别是在遍历大型列表时。懒惰有一个构建thunk的开销,而foldl‘是达到这个结果的更有效的方法,因为它不会构建一个巨大的thunk。
在Haskell Wiki上有一篇非常好的文章详细解释了这一点
严格函数的工作原理类似于C或其他语言中的函数,因为它们的参数通常会被迫切地计算出来。
发布于 2013-01-12 00:39:18
回想一下类型:
foldl' :: (a -> b -> a) -> a -> [b] -> a它在参数2中的严格程度取决于为参数1指定的函数的严格程度,如果您传递const,就会看到这一点
Prelude Data.List> foldl' (const (+1)) undefined [1]
2
Prelude Data.List> foldl' (const (+1)) undefined [1..4]
5你可能会天真地认为,"foldl‘is strict“的意思是”严格的累加器参数“。上述情况与此相矛盾。
然而,它甚至更加隐蔽,因为严格程度只在循环的cons情况下函数应用的结果上。
Prelude Data.List> foldl' (const (+1)) undefined []
*** Exception: Prelude.undefined所以in argument 2的严格性也取决于参数3的值!
我是这样写的:在它的第二个参数中“完全”严格。
foldl' f z0 xs0 = go z0 xs0
  where
    go !z []     = z
    go !z (x:xs) = go (f z x) xsPrelude Data.List.Stream> foldl' (\a b -> 1) undefined [undefined]
*** Exception: Prelude.undefined与Haskell2010版本相比:
Prelude Data.List.Stream> Data.List.foldl' (\a b -> 1 ) undefined [undefined]
1这实际上有一个实际的影响--当前的定义不会一致地拆开它的累加器参数。
历史注释:这是我们在2007年为流融合论文指定列表库的严格语义时发现的,并且在Duncan Coutt的PhD thesis中给出了指定严格程度的方法。
发布于 2013-01-11 21:30:13
严格函数是指在计算正文之前计算其参数的函数。
https://stackoverflow.com/questions/14279199
复制相似问题