请注意琐碎的解决方案
reverse a = foldr (\b c -> c ++ [b] ) [] a
由于复杂性的二次增长,效率不高。如果试图使用通常的foldl进行折叠转换(盲目),但我的尝试
foldr (\b g x -> g ((\x old -> x:old) x b)) id list []
没有像我预期的那样工作。
答案 0 :(得分:19)
试试这个:
reverse bs = foldr (\b g x -> g (b : x)) id bs []
虽然使用foldl'编写它通常会更好:
reverse = foldl' (flip (:)) []
答案 1 :(得分:8)
请考虑以下事项:
foldr (<>) seed [x1, x2, ... xn] == x1 <> (x2 <> (... <> (xn <> seed)))
让我们把它“剪切”成碎片:
(x1 <>) (x2 <>) ... (xn <>) seed
现在我们有了这一系列功能,让我们来组合它们:
(x1 <>).(x2 <>). ... .(xn <>).id $ seed
((.), id)
它是Endo
monoid,所以
foldr (<>) seed xs == (appEndo . foldr (mappend.Endo.(<>)) mempty $ xs) seed
对于左侧折叠,我们只需要Dual
monoid。
leftFold (<>) seed xs = (appEndo . getDual . foldr (mappend . Dual . Endo . (<>)) mempty $ xs) seed
(<>) = (:)
和seed = []
reverse' xs = (appEndo . getDual . foldr (mappend . Dual . Endo . (:)) mempty $ xs) []
或简单:
reverse' xs = (appEndo . foldr (flip mappend . Endo . (:)) mempty $ xs) []
reverse' xs = (foldr (flip (.) . (:)) id $ xs) []
reverse' = flip (foldr (flip (.) . (:)) id) []
答案 2 :(得分:2)
基本上,您需要将1:2:3:[]转换为(3 :)(2:)。(1 :)并将其应用于[]。因此:
reverse' xs = foldr (\x g -> g.(x:)) id xs []
这里积累的g的意思是它通过将xs的反转部分尾追加到它上来作用于它的参数。
对于1:2:3:[]示例,在最后一步中,x将为3,g将为(2:)。(1:)。
答案 3 :(得分:0)
foldl (\acc x -> x:acc) [] [1,2,3]
答案 4 :(得分:-2)
reverse' :: [a] -> [a]
reverse' = foldr (\x acc -> acc ++ [x]) []
是(++)明显慢于(:),这需要一些逻辑扭曲,如FUZxxl的回答所示