从列表中过滤出空列表

rig*_*wed 1 haskell haskell-platform

考虑清单

  [[],[1],[1,2],[1,2,3],[],[2],[2,3],[],[3],[]]
Run Code Online (Sandbox Code Playgroud)

我想过滤掉所有非空列表的元素,即过滤后的输出应该给我一个结果,如:

  [[1],[1,2],[1,2,3],[2],[2,3],[3]]
Run Code Online (Sandbox Code Playgroud)

以下代码失败:

  myfilter lst = filter(\x -> x/=[]) lst
Run Code Online (Sandbox Code Playgroud)

[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, []]
Run Code Online (Sandbox Code Playgroud)

C. *_*ann 16

你的功能看起来不错,但是:

myfilter [12, 3, []]
Run Code Online (Sandbox Code Playgroud)

...是类型错误.列表包含同类型的值,而您在此处放置了数字和空列表.

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

在GHCi中:

> myfilter [[12], [3], []]
[[12],[3]]
Run Code Online (Sandbox Code Playgroud)

......这似乎正是你想要的.


对于将来,参考,您获得的错误的翻译密钥:

No instance for (Num [a])
Run Code Online (Sandbox Code Playgroud)

这意味着它尝试并失败,找到Num该类型的实例[a].我们不希望这个实例存在,所以问题出在其他地方.

arising from the literal `3' at <interactive>:1:13
Run Code Online (Sandbox Code Playgroud)

Num类型类包含fromInteger,这是用来转换数字文字像3一些特定的类型.所以这告诉我们的是,它3在一个上下文中找到了它所期望的某种类型[a],并尝试使用fromInteger它.这导致上面的"无实例"错误.

Possible fix: add an instance declaration for (Num [a])
Run Code Online (Sandbox Code Playgroud)

这条线是无稽之谈.丢失Num实例导致的错误几乎从不会因忘记编写合理的实例声明而导致.

In the expression: 3
Run Code Online (Sandbox Code Playgroud)

这告诉我们发现错误的表达式.不过,我们之前已经知道了这一点3.

In the first argument of `myfilter', namely `[12, 3, []]'
Run Code Online (Sandbox Code Playgroud)

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