首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在haskell中反转列表

在haskell中反转列表
EN

Stack Overflow用户
提问于 2014-11-10 23:31:27
回答 5查看 52.4K关注 0票数 22

我正在尝试颠倒一个列表。

以下是我的代码:

代码语言:javascript
运行
复制
reverseList :: [Int] -> [Int]
reverseList [] = []
reverseList (x:xs) =  x:reverseList xs

最终发生的事情是,我最终以相同的顺序重新获得了列表。我甚至有一个如何反转列表的解决方案,但我正在试图理解我在这里做错了什么?我对haskell非常陌生,所以我认为我应该专注于更多的理解,然后才能轻松地解决更多的问题。我知道这个问题有很多解决方案,但我需要更多的帮助来理解,特别是我在这段代码中做错了什么。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-11-10 23:33:41

您将列表分为头部和尾部,但随后以相同的顺序重新组合列表。拿着清单[1, 2, 3]例如:

在第一个调用中,x将会是1,以及xs将会是[2, 3]..。然后创建一个新列表,该列表包含x(所以1)在前面,然后是reverseList [2, 3]..。

票数 8
EN

Stack Overflow用户

发布于 2014-11-10 23:40:27

在Haskell中有几种方法可以解决这个问题。简单的方法是使用concatenate函数++

代码语言:javascript
运行
复制
reverseList [] = []
reverseList (x:xs) = reverseList xs ++ [x]

然而,对于大型列表来说,这会非常慢,因为Haskell列表实际上是单链表,所以为了附加一个元素,你必须遍历整个列表。另一种方法是跟上你在helper函数中构建的列表:

代码语言:javascript
运行
复制
reverseList = go []
    where
        go acc [] = acc
        go acc (x:xs) = go (x:acc) xs

然而,这实际上只是fold模式:

代码语言:js
复制
reverseList = foldl (\acc x -> x : acc) []

但是\acc x -> x : acc只是flip (:),所以这可以写成

代码语言:js
复制
reverseList = foldl (flip (:)) []

但是,最简单的方法可能是只使用reverse前言中的函数。

我想指出的是,你的类型reverseList :: [Int] -> [Int]可以概括为:: [a] -> [a],你不需要对列表中的元素做任何特殊的事情,你只需要用它们构建一个新的列表即可。

票数 62
EN

Stack Overflow用户

发布于 2018-07-06 20:16:47

在Haskell中有几种方法可以解决这个问题。下面是一个包含cons和last/init的解决方案:

代码语言:javascript
运行
复制
reverseList  [] = []
reverseList  xs = last xs : reverseList (init xs)

或者使用foldl:

代码语言:js
复制
reverseList xs = foldl (\x y -> y:x) [] xs
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26847192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档