[英]Reverse list of lists using foldr Haskell
我正在嘗試通過使用文件夾反轉Haskell中的列表列表。 有一個我想做的例子:
> reverse'' [[1,2,3],[3,4,5]]
[[5,4,3],[3,2,1]]
和我的代碼(它不起作用):
reverse'':: [[a]]->[[a]]
reverse'' x = foldr (\n acum -> acum:(foldr(\m acum1 -> acum1++[m])) [] n) [[]] x
我的IDE在第二個文件夾的開頭報告了一個錯誤。
為了分析您當前的解決方案,我將您的一線代碼分解為一些輔助函數,並根據其組成推導了它們的類型:
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]
當我嘗試編譯上面的代碼時,ghc抱怨reverse''
類型簽名出現以下錯誤:
Expected type: [[a]] -> [[a]] -> [[a]]
Actual type: [[a]] -> [a] -> [[a]]
我做了一些挖掘,然后為了使“ reverse''
具有類型[[a]] -> [[a]]
,函數f
需要具有類型[a] -> [[a]] -> [[a]]
。 但是,當前f
類型為[a] -> a -> [a]
,或者在這種情況下為[[a]] -> [a] -> [[a]]
。
以下是正確的類型,但是由於累加器的起始值,所以將一個額外的[]
值插入到數組的開頭:
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]
通過將初始累加器值更改為空列表[]
而不是空列表[[]]
列表,我們得到了一個可行的解決方案:
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]
如果您真的希望將此作為單線工作,則為:
reverse'' :: [[a]] -> [[a]]
reverse'' = foldr (\n acum -> acum ++ [foldr (\m acum1 -> acum1 ++ [m]) [] n]) []
與工作:
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]) []
這是一個顯式遞歸解決方案(即不使用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.