展平列表清单

时间:2012-02-29 22:00:52

标签: list haskell types abstract

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

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

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

4 个答案:

答案 0 :(得分:26)

有点不清楚你要求的是什么,但是列表列表是一个名为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]

答案 1 :(得分:9)

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

答案 2 :(得分:1)

这一个班轮将完成这项工作。虽然正如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 :(得分:0)

通过列表理解进行铺平。

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