Фильтрация пустых списков из списка - PullRequest
1 голос
/ 24 августа 2011

Рассмотрим список

  [[],[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 Ответ

16 голосов
/ 24 августа 2011

Ваша функция выглядит нормально, но это:

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, []]'

Больше контекста для выражения с ошибкой, и здесь мы наконец можем обнаружить проблему: из-за списков, имеющих однородный тип, даны 12 и 3 типа Num a => a и [] типа [a], это унифицированные те, чтобы получить Num [a] => [a], вызывая ошибку. Исправление в этом случае - то, что я сказал выше, и [[12], [3], []] имеет (правильный) тип Num a => [[a]].

...