2011-08-24 136 views
1

考虑名单从列表中过滤掉空列表

[[],[1],[1,2],[1,2,3],[],[2],[2,3],[],[3],[]] 

我想筛选出不属于空列表,即滤波输出应该给我像一个结果的所有元素:

[[1],[1,2],[1,2,3],[2],[2,3],[3]] 

下面的代码失败:

myfilter lst = filter(\x -> x/=[]) lst 

与以下错误为[12,3,[]]

No instance for (Num [a]) 
    arising from the literal `3' at <interactive>:1:13 
Possible fix: add an instance declaration for (Num [a]) 
In the expression: 3 
In the first argument of `myfilter', namely `[12, 3, []]' 
In the expression: myfilter [12, 3, []] 
+1

它为什么失败?您提供的代码提供了与所需输出完全匹配的结果。也许你需要详细说明究竟出了什么问题。 – fuz

+2

这不会解决你的问题,但作为一种风格的东西,它通常被认为是使用'null'或'not'的好形式。 null“而不是'(== [])'或'(/ = [])',因为它不需要虚假的'Eq'实例。 –

+4

是的,这会更优雅:'myFilter = filter(not.null)'。 – Landei

回答

16

你的函数看起来不错,但这样的:

myfilter [12, 3, []] 

...是一个类型的错误。列表包含同类型的值,而您在这里放置了两个数字和一个空列表。

我希望你想要的是[[12], [3], []]

在GHCI:

> myfilter [[12], [3], []] 
[[12],[3]] 

...这似乎是你想要什么。


并为未来,引用,错误翻译关键你有:

No instance for (Num [a]) 

这意味着试过了,失败了,找到Num实例的类型[a]。我们并不期望这种情况存在,所以问题在于别处。

arising from the literal `3' at <interactive>:1:13 

Num型类包含fromInteger,其用于数字文字等3转化为一些特定的类型。所以这告诉我们它发现3在它期望的东西类型[a],并试图使用fromInteger它的上下文。这导致了上面的“无实例”错误。

Possible fix: add an instance declaration for (Num [a]) 

这条线是无稽之谈。由缺少Num实例导致的错误几乎不会由于忘记编写明智的实例声明而导致。

In the expression: 3 

这告诉我们发现错误的表达式。不过,我们已经知道这一点,因为早些时候提到了文字3

In the first argument of `myfilter', namely `[12, 3, []]' 

与错误的表达更多的上下文,而这正是我们终于可以发现问题:由于给定[a]类型的12Num a => a3[]具有同质类型列表,中,它是统一的那些得到Num [a] => [a],导致错误。在这种情况下的修正是我上面所说的,并且[[12], [3], []]具有(正确的)类型Num a => [[a]]

+0

谢谢。确实是一个愚蠢的错误! – rightskewed

+0

@Saket Choudhary:发生在我们所有人身上。 :]好的一点是,一旦你习惯了错误报告的方式,那么在你运行程序之前,它会为你捕捉像这样的愚蠢错误节省很多麻烦。 –