我知道如何使用递归来逆转列表,但我正在尝试使用foldl来使其更有效。我的代码如下:未能使用foldl来逆转Haskell中的列表
reverse list = foldl (++) [] (map (\x -> [x]) list)
当在GHCi中运行它时,它将返回与输入相同的列表。出了什么问题?我也试着用foldr来完成它,但它没有显示任何改变。
我知道如何使用递归来逆转列表,但我正在尝试使用foldl来使其更有效。我的代码如下:未能使用foldl来逆转Haskell中的列表
reverse list = foldl (++) [] (map (\x -> [x]) list)
当在GHCi中运行它时,它将返回与输入相同的列表。出了什么问题?我也试着用foldr来完成它,但它没有显示任何改变。
foldl
将累加器作为第一个参数传递给该函数。 ++
将第一个参数连接到第二个参数,但是,要反转列表,需要将第二个参数连接到第一个参数。您可以使用flip (++)
做到这一点:
Prelude> let reverse list = foldl (flip (++)) [] (map (\x -> [x]) list)
Prelude> reverse [1..5]
[5,4,3,2,1]
“连接...到”是非定向的;混乱。 “之前”会好很多。 –
取代先转换列表中的所有元素独居列表(这是昂贵的为好),你可以使用利弊(:)
功能:
reverse :: Foldable t => t a -> [a]
reverse = foldl (flip (:)) []
所以这里我们使用flip (:) :: [a] -> a -> [a]
作为折叠函数。它需要一个尾部[a]
和一个头部a
,并构建一个头部作为第一个元素和尾部作为最后一个元素的列表。
那么什么情况是:
foldl (flip (:)) [] [1,4,2,5]
-> foldl (flip (:)) (1:[]) [4,2,5]
-> foldl (flip (:)) (4:1:[]) [2,5]
-> foldl (flip (:)) (2:4:1:[]) [5]
-> foldl (flip (:)) (5:2:4:1:[]) []
-> (5:2:4:1:[])
-> [5,2,4,1]
见https://stackoverflow.com/questions/26847192/reverse-a-list-in-haskell – icc97
的[反在Haskell列表]可能的复制(HTTPS ://sackoverflow.com/questions/26847192/reverse-a-list-in-haskell) – icc97
@ icc97虽然在这个问题中给出了正确的'foldl'解决方案,但问题本身并不是真的,所以我不会说它是重复的。 – leftaroundabout