filter ((>4).(length snd)) lst
Похоже, у вас есть правильная идея с этим, но, как вы заметили, она не компилируется.Хотя, когда я пытаюсь это сделать, ошибка отличается от той, о которой вы упомянули, что у length
слишком много аргументов - вы указали здесь один аргумент, который является правильным числом.Тем не менее, аргумент, который вы указали, является функцией (snd
, которая дает вам второй элемент пары), и он ожидает список - поскольку нет возможности рассматривать функцию как список, компилятор отклоняетэто бессмысленно.(Даже если бы это не было проблемой, length snd
приведет к Int
, и вы не можете использовать это в качестве аргумента оператора .
, которому нужна функция с любой стороны. И это то, что GHCна самом деле жалуется, когда я пытаюсь запустить ваш код: Couldn't match expected type '([Char], [Char]) -> Integer' with actual type 'Int' In the second argument of '(.)', namely '(length snd)'
)
@ WillemVanOnsem уже показал вам, как это исправить, поэтому давайте посмотрим на это.Он действительно очень похож на ваш:
filter ((>4) . length . snd)) lst
Оператор .
, как вы, кажется, знаете, применяет сначала функцию справа, а затем функцию слева от результата.Таким образом, выражение (>4) . length . snd
означает, что для заданной пары взять второй элемент, затем взять его длину (предполагается, что это список, или он не скомпилируется), а затем проверить, больше ли полученное число больше 4 или нет.Другими словами, (>4) . length . snd)
- это предикат типа (a, [b]) -> Bool
, который сообщает вам, содержит ли список во втором слоте пары более 4 элементов или нет.[Термин «предикат» означает просто любую функцию, которая возвращает Bool
- это тест, применяемый к элементам интересующего вас типа, используемым в filter
и многих связанных функциях.] И это, конечно, точното, к чему вы стремитесь.
Итак, подведем итог: единственное различие между вашим ответом и правильным ответом состоит в том, что между length snd
(предоставление функции snd
в качестве аргумента length
, чтобессмысленно) и length . snd
(функция, заданная сначала применением snd
, затем length
к его результату).Они могут выглядеть одинаково, но на самом деле они имеют в виду совершенно разные вещи.
Я уверен, что, немного потренировавшись, вы сможете сами сделать такие вещи правильно и понять, что говорит GHCвы, когда он выдает ошибку компиляции.
(PS: ваш код на самом деле дает сбой, потому что a
, rr
и т. д. - это переменные, которые вы не привязали ни к каким значениям. I 'мы предположили, что все они должны быть строками, особенно если вы взяли длину значений r..r
- в этом случае их необходимо заключить в двойные кавычки: ("a", "rr")
и т. д.