[英]Reverse list of lists using foldr Haskell
I'm trying to reverse list of lists in Haskell by using foldr. 我正在尝试通过使用文件夹反转Haskell中的列表列表。 There is an example of what I want to do:
有一个我想做的例子:
> reverse'' [[1,2,3],[3,4,5]]
[[5,4,3],[3,2,1]]
And my code (it is not working): 和我的代码(它不起作用):
reverse'':: [[a]]->[[a]]
reverse'' x = foldr (\n acum -> acum:(foldr(\m acum1 -> acum1++[m])) [] n) [[]] x
My IDE reports me an error at the start of the second foldr. 我的IDE在第二个文件夹的开头报告了一个错误。
To analyse your current solution, I've broken down your one-liner into some helper functions, with their type deduced based on their composition: 为了分析您当前的解决方案,我将您的一线代码分解为一些辅助函数,并根据其组成推导了它们的类型:
reverse'':: [[a]] -> [[a]]
reverse'' x = foldr f [[]] x
where
f :: [a] -> a -> [a]
f n acum = acum : reverse n
reverse :: [a] -> [a]
reverse n = foldr append [] n
append :: a -> [a] -> [a]
append m acum = acum ++ [m]
When I try to compile the above, ghc complains with the following error for the type signature of reverse''
: 当我尝试编译上面的代码时,ghc抱怨
reverse''
类型签名出现以下错误:
Expected type: [[a]] -> [[a]] -> [[a]]
Actual type: [[a]] -> [a] -> [[a]]
I did some digging, and in order for reverse''
to have the type [[a]] -> [[a]]
, the function f
needs to have the type [a] -> [[a]] -> [[a]]
. 我做了一些挖掘,然后为了使“
reverse''
具有类型[[a]] -> [[a]]
,函数f
需要具有类型[a] -> [[a]] -> [[a]]
。 However the current f
has type [a] -> a -> [a]
, or in this case [[a]] -> [a] -> [[a]]
. 但是,当前
f
类型为[a] -> a -> [a]
,或者在这种情况下为[[a]] -> [a] -> [[a]]
。
The following has the correct type, but inserts an extra []
value into the start of the array, due to the starting value of the accumulator: 以下是正确的类型,但是由于累加器的起始值,所以将一个额外的
[]
值插入到数组的开头:
reverse'':: [[a]] -> [[a]]
reverse'' x = foldr f [[]] x
where
f :: [a] -> [[a]] -> [[a]]
f n acum = acum ++ [reverse n]
reverse :: [a] -> [a]
reverse n = foldr append [] n
append :: a -> [a] -> [a]
append m acum = acum ++ [m]
By changing the initial accumulator value to the empty list []
, as opposed to a list of an empty list [[]]
, we end up at a working solution: 通过将初始累加器值更改为空列表
[]
而不是空列表[[]]
列表,我们得到了一个可行的解决方案:
reverse'':: [[a]] -> [[a]]
reverse'' x = foldr f [] x
where
f :: a -> [a] -> [a]
f n acum = acum ++ [reverse n]
reverse :: [a] -> [a]
reverse n = foldr append [] n
append :: a -> [a] -> [a]
append m acum = acum ++ [m]
If you really want this as a one-liner, here it is: 如果您真的希望将此作为单线工作,则为:
reverse'' :: [[a]] -> [[a]]
reverse'' = foldr (\n acum -> acum ++ [foldr (\m acum1 -> acum1 ++ [m]) [] n]) []
With working: 与工作:
append m acum = acum ++ [m]
append = \m acum1 -> acum1 ++ [m]
reverse n = foldr append [] n
reverse = \n -> foldr append [] n
reverse = foldr append []
reverse = foldr (\m acum1 -> acum1 ++ [m]) []
f n acum = acum ++ [reverse n]
f = \n acum -> acum ++ [reverse n]
f = \n acum -> acum ++ [foldr (\m acum1 -> acum1 ++ [m]) [] n]
reverse'':: [[a]] -> [[a]]
reverse'' x = foldr f [] x
reverse'' x = foldr (\n acum -> acum ++ [foldr (\m acum1 -> acum1 ++ [m]) [] n]) [] x
reverse'' = foldr (\n acum -> acum ++ [foldr (\m acum1 -> acum1 ++ [m]) [] n]) []
Here is an explicitly recursive solution (ie not using a fold
), with definitons of map
and reverse
provided. 这是一个显式递归解决方案(即不使用
fold
),提供了map
和reverse
。
reverse :: [a] -> [a]
reverse (x:xs) = reverse xs ++ [x]
reverse [] = []
map :: (a -> b) -> [a] -> [b]
map f (x:xs) = f x : map f xs
map _ [] = []
reverse'' :: [[a]] -> [[a]]
reverse'' ls = reverse $ map reverse ls
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.