2012-02-29 94 views
5

我必须编写一个展开列表清单的函数。展开列表清单

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

我遇到的麻烦的是能够匹配取决于什么是考虑到扁平化的功能类型。

这是我有:

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类型,因此该函数可以获取单个元素或元素列表。

有谁知道以不同的方式来做这个不同的,或解释我能做些什么来解决类型错误?

+0

我不知道你想要什么。也许'flatten :: A [a] - > A a;展平(B xs)= C xs; flatten(C xss)= C(concat xss)'会帮助你吗?基本上,你不能写扁平化,以便它需要不同的嵌套列表并且与它们做不同的事情,除非你将它们包装成新类型并通过构造函数区分这些情况。 – 2012-02-29 22:07:13

+1

函数的类型应该是'[[a]] - > [a]'。这意味着'flatten []'是有效的,并且'flatten [[1,2,3,4]]'是有效的,但是'flatten [1,2,3,4]'不是。 '[1,2,3,4]'不是列表的列表。如果你仔细想想并从头开始,摆脱你的特殊类型,你会发现它更容易。 – 2012-02-29 22:10:42

+0

[列表中的操作| |列表中的操作可能重复如何](http://stackoverflow.com/questions/9477806/operation-on-list-of-lists-how) – rampion 2012-03-01 02:23:32

回答

20

这是有点不清楚你要求什么,但扁平列表是一个标准功能concat在类型签名[[a]] -> [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] 
9

首先,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) 
+2

'flatten(B a)= [a]; flatten(C xs)= flatten = << xs' – luqui 2012-03-01 01:27:00

0

这一个班轮将完成这项工作。虽然因为它是由马林提到的类型签名是不同的:

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] 
+0

关键是函数应该适用于简单列表和嵌套列表。您的作品仅适用于简单列表。 – Lii 2016-02-08 19:58:55