Haskell:高效的累加器

时间:2016-02-02 00:12:14

标签: haskell accumulator

当您的结果与列表的类型不同时,使用每张地图的结果来映射列表的最佳方式是什么。

例如

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

l = [1,2,3,4]

我希望在列表中有一些内容并且可以:

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

我可以将它与累加器一起使用,但它似乎相当麻烦。有没有一种标准的方法可以做到这一点......或者这是莫纳德的事情吗?

谢谢!

注意上述功能仅供参考。

3 个答案:

答案 0 :(得分:4)

这只是输入列表中对的剩余部分:

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的答案。

答案 1 :(得分:3)

似乎是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)

答案 2 :(得分:1)

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

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)