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)
当您的结果与列表的类型不同时,在整个列表中映射的最佳方式是什么,使用每个映射的结果。
例如
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)