展平列表列表

Posted

技术标签:

【中文标题】展平列表列表【英文标题】:Flatten a list of lists 【发布时间】:2012-03-19 10:12:14 【问题描述】:

我必须编写一个扁平化列表的函数。

例如flatten [] = []flatten [1,2,3,4] = [1,2,3,4]flatten [[1,2],[3],4,5]] = [1,2,3,4,5]

我无法根据给定的 flatten 函数匹配类型。

这是我所拥有的:

data A a = B a | C [a] deriving (Show, Eq, Ord)

flatten::(Show a, Eq a, Ord a)=>A a -> A a
flatten (C []) = (C [])
flatten (C (x:xs) ) = (C flatten x) ++ (C flatten xs)
flatten (B a) = (C [a])

据我所知,问题是++ 运算符期望它的两个参数都有一个列表,我试图给它一些A 类型的东西。我添加了 A 类型,因此该函数可以获取单个元素或元素列表。

有没有人知道一种不同的方法来做到这一点,或者解释我可以做些什么来修复类型错误?

【问题讨论】:

我不确定你到底想要什么。也许flatten :: A [a] -> A a; flatten (B xs) = C xs; flatten (C xss) = C (concat xss) 会帮助你?基本上,您不能编写 flatten 以便它获取不同嵌套的列表并对它们执行不同的操作,除非您将它们包装成新类型并通过构造函数区分情况。 你的函数类型应该是[[a]] -> [a]。这意味着flatten [] 有效,flatten [[1,2,3,4]] 有效,但flatten [1,2,3,4] 无效。 [1,2,3,4] 不是列表列表。如果您考虑到这一点并从头开始,摆脱您的特殊类型,您会发现它会容易得多。 operation on list of lists | how的可能重复 【参考方案1】:

通过列表理解展平。

flatten arr = [y | x<- arr, y <- x]

【讨论】:

【参考方案2】:

这一个班轮将完成这项工作。尽管正如 Malin 提到的,类型签名不同:

flatten :: [[a]] -> [a]         
flatten xs = (\z n -> foldr (\x y -> foldr z y x) n xs) (:) []

简单测试

frege> li = [[3,4,2],[1,9,9],[5,8]]
frege> flatten li
[3,4,2,1,9,9,5,8]

【讨论】:

关键是该函数应该适用于简单列表和嵌套列表。您的作品仅适用于简单列表。【参考方案3】:

首先,A 类型是在正确的轨道上,但我不认为它是完全正确的。您希望它能够展平任意嵌套的列表,因此“A a”类型的值应该能够包含“A a”类型的值:

data A a = B a | C [A a]

其次,函数的类型应该略有不同。您可能希望它只返回 a 的列表,而不是返回类型为“A a”的值,因为根据定义,该函数始终返回一个平面列表。所以类型签名是这样的:

flatten :: A a -> [a]

还要注意,不需要类型类约束——这个函数是完全通用的,因为它根本不查看列表的元素。

这是我的实现:

flatten (B a) = [a]
flatten (C []) = []
flatten (C (x:xs)) = flatten x ++ flatten (C xs)

【讨论】:

flatten (B a) = [a]; flatten (C xs) = flatten =&lt;&lt; xs【参考方案4】:

有点不清楚您要的是什么,但展平列表列表是一个标准函数,在前奏中称为concat,类型签名为[[a]] -&gt; [a]

如果您像上面开始的那样创建嵌套列表的数据类型,也许您想将数据类型调整为如下所示:

 data Lists a = List [a] | ListOfLists [Lists a]

然后你可以将它们展平为一个列表;

 flatten :: Lists a -> [a]
 flatten (List xs) = xs
 flatten (ListOfLists xss) = concatMap flatten xss

作为测试,

 > flatten (ListOfLists [List [1,2],List [3],ListOfLists [List [4],List[5]]])
 [1,2,3,4,5]

【讨论】:

以上是关于展平列表列表的主要内容,如果未能解决你的问题,请参考以下文章

将列表列表(用逗号分隔的语句)展平为列表列表[重复]

展平列表列表

当列表包含另一个列表的 1 个单个项目时,展平嵌套列表

Python:展平内部列表时保留外部列表

如何展平列表列表?

将嵌套列表展平为 1 深列表