Haskell:高效累加器
Posted
技术标签:
【中文标题】Haskell:高效累加器【英文标题】:Haskell: Efficient accumulator 【发布时间】:2016-02-02 00:12:14 【问题描述】:当您的结果与列表的类型不同时,使用每个映射的结果来映射列表的最佳方式是什么。
例如
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 的东西?
谢谢!
注意上面的功能只是为了说明。
【问题讨论】:
一般来说你可以使用滑动窗口 【参考方案1】:这只是输入列表中对的一个折叠:
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 的答案。
【讨论】:
没有理由害怕foldl'
!【参考方案2】:
似乎是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)
【讨论】:
【参考方案3】:当然,您可以传递折叠累加器中的前一个元素,而不是压缩。例如:
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)
【讨论】:
以上是关于Haskell:高效累加器的主要内容,如果未能解决你的问题,请参考以下文章