Давайте анализировать capMarks
функции:
capMarks :: [StudentMark] -> [StudentMark]
capMarks [cMarks] = [(st, mk) | (st, mk) <- [capMark cMarks]]
Прежде всего capMarks [cMarks] = ...
является сопоставлением с образцом. Это соответствует списку, содержащему один элемент. Я предполагаю, что вы хотите сделать что-то с целым списком, так это изменить, чтобы capMarks cMarks = ...
Следующая ... [(st, mk) | (st, mk) <- [capMark cMarks]]
будет применить функцию capMark
к единственному элементу в исходной картины, соответствующей схеме, а затем поместить результат как единственный элемент список. По-видимому, вы хотите применить capMark
к каждому элементу списка. Поэтому, если следовать предыдущему предложению, вам нужно сделать что-то вроде ... [capMark mark | mark <- cMarks]
. Это делается точно так, как указано выше: примените capMark
к каждому элементу списка cMarks
.
Окончательный вариант:
capMarks :: [StudentMark] -> [StudentMark]
capMarks cMarks = [capMark mark | mark <- cMarks]
В качестве альтернативы, вы можете также использовать поиск по шаблону и явной рекурсии:
capMarks [] = []
capMarks (x:xs) = capMark x : capMarks xs
Первая строка говорит, что capMarks
применяется к пустому списку является пустым списком. Во второй строке указано, что capMarks
применяется к списку, по крайней мере, с одним элементом будет применяться capMark
к первому элементу, а затем рекурсивно применить capMarks
к остальной части списка.
Это такая распространенная картина в Haskell, что существует функция, называемая map
, которая ее обобщает. Использование map
невероятно просто:
capMarks cMarks = map capMark cMarks
map
имеет тип (a -> b) -> [a] -> [b]
, который означает, что он принимает функцию и список и возвращает список. (a
и b
просто укажите компилятору, какие типы должны быть одинаковыми.) map
затем применяет функцию к каждому элементу в списке ввода.
В конце концов вы узнаете о применении частичных функций и беспутном стиле. С этими двумя понятиями, версия с использованием map
может быть упрощена немного:
capMarks = map capMark
Не слишком беспокоиться об этом еще. Я просто добавляю его здесь для полноты.
Если какая-либо из моих терминов отключена, пожалуйста, воздержитесь от меня, поскольку я новичок и для Haskell, и для stackoverflow. – MichaelAS
Давайте сделаем шаг назад. Что вы пытаетесь выполнить с помощью этих функций? Какова цель этого кода? Какую проблему вы пытаетесь решить с помощью этого кода? –
Предполагается вернуть кортежи, в которых значения целых чисел более 40 будут возвращены как 40 в соответствии с функцией capMark. т. е. 'capMark (« Steve », 100)' будет возвращать '(« Steve », 40)', поэтому функция capMarks должна делать это, используя функцию capMark, чтобы сделать это для списка кортежей, используя понимание списка. – MichaelAS