我正在尝试颠倒一个列表。
以下是我的代码:
reverseList :: [Int] -> [Int]
reverseList [] = []
reverseList (x:xs) = x:reverseList xs
最终发生的事情是,我最终以相同的顺序重新获得了列表。我甚至有一个如何反转列表的解决方案,但我正在试图理解我在这里做错了什么?我对haskell非常陌生,所以我认为我应该专注于更多的理解,然后才能轻松地解决更多的问题。我知道这个问题有很多解决方案,但我需要更多的帮助来理解,特别是我在这段代码中做错了什么。
发布于 2014-11-10 23:33:41
您将列表分为头部和尾部,但随后以相同的顺序重新组合列表。拿着清单[1, 2, 3]
例如:
在第一个调用中,x
将会是1
,以及xs
将会是[2, 3]
..。然后创建一个新列表,该列表包含x
(所以1)在前面,然后是reverseList [2, 3]
..。
发布于 2014-11-10 23:40:27
在Haskell中有几种方法可以解决这个问题。简单的方法是使用concatenate函数++
reverseList [] = []
reverseList (x:xs) = reverseList xs ++ [x]
然而,对于大型列表来说,这会非常慢,因为Haskell列表实际上是单链表,所以为了附加一个元素,你必须遍历整个列表。另一种方法是跟上你在helper函数中构建的列表:
reverseList = go []
where
go acc [] = acc
go acc (x:xs) = go (x:acc) xs
然而,这实际上只是fold
模式:
reverseList = foldl (\acc x -> x : acc) []
但是\acc x -> x : acc
只是flip (:)
,所以这可以写成
reverseList = foldl (flip (:)) []
但是,最简单的方法可能是只使用reverse
前言中的函数。
我想指出的是,你的类型reverseList :: [Int] -> [Int]
可以概括为:: [a] -> [a]
,你不需要对列表中的元素做任何特殊的事情,你只需要用它们构建一个新的列表即可。
发布于 2018-07-06 20:16:47
在Haskell中有几种方法可以解决这个问题。下面是一个包含cons和last/init的解决方案:
reverseList [] = []
reverseList xs = last xs : reverseList (init xs)
或者使用foldl:
reverseList xs = foldl (\x y -> y:x) [] xs
https://stackoverflow.com/questions/26847192
复制相似问题