Haskell:高效累加器

Haskell: Efficient accumulator

当您的结果与列表的类型不同时,在整个列表中映射的最佳方式是什么,使用每个映射的结果。

例如

f :: Int -> Int -> String -> String

l = [1,2,3,4]

我想要一些沿着列表 l 走的东西:

f 1 2 [] = result1 => f 2 3 result1 = result2 => f 3 4 result3 ==> return result3.

我可以让这个与累加器一起工作,但它看起来相当麻烦。有没有标准的方法来做到这一点...或者这是 Monads 的东西?

谢谢!

注意上面的函数只是为了说明。

似乎是 fold 的工作:

func f l = foldl (\s (x, y) -> f x y s) "" (zip l (tail l))

-- just some placeholder function
f :: Int -> Int -> String -> String
f x y s = s ++ " " ++ show(x) ++ " " ++ show(y)

l = [1,2,3,4]

main = print $ func f l

打印:

" 1 2 2 3 3 4"

(如果你能改变f的签名,你就能摆脱丑陋的重新排列参数的lambda)

这只是输入列表中对的折叠:

f :: Int -> Int -> String -> String
f = undefined

accum :: [Int] -> String
accum xs = foldl (flip . uncurry $ f) "" $ zip xs (drop 1 xs)

您可能想使用 Data.List.foldl' 而不是 foldl,但这是仅适用于 Prelude 的答案。

当然,您可以传递折叠累加器内的前一个元素,而不是压缩。例如:

l = [1,2,3,4]
f x y = (x,y)
g b@(accum,prev) a = (accum ++ [f prev a],a)

main = print (foldl g ([],head l) (tail l))

输出:

([(1,2),(2,3),(3,4)],4)