ответ Хаммара покрыл списки, базовая схема для рекурсивных функций с использованием сопоставления с образцом:
f [] = ..
f ((a,b,c,d):xs) = ..
Таким образом, вам нужно указать базовый регистр для списка, не содержащего 4 кортежа, и рекурсивный случай, когда список состоит из 4 кортежей (a,b,c,d)
, за которым следует (возможно, пустой, возможно, непустой) список из 4-х кортежей xs
. Шаблон во второй строке представляет собой вложенный шаблон : сначала он сопоставляет список с шаблоном, например (x:xs)
, то есть элемент x
, за которым следует остаток списка xs
; а затем он сопоставляется x
со структурой с четырьмя кортежами.
Ниже я приведу несколько основных примеров. Обратите внимание, что вы также можете написать это с помощью стандартных функций высшего порядка, таких как filter
и map
, и я намеренно не упоминаю такие вещи, как @
-шаблоны и строгость. Я не рекомендую делать это так, но это просто, чтобы дать вам идею!
Если вы хотите суммировать первую часть кортежей, вы можете сделать это следующим образом:
sum4 :: [(Int,Int,Int,Int)] -> Int
sum4 [] = 0
sum4 ((a,b,c,d):xs) = a + sum4 xs
Если вы хотите отфильтровать кортежи, в которых все a
, b
, c
и d
четны:
filter4allEven :: [(Int,Int,Int,Int)] -> [(Int,Int,Int,Int)]
filter4allEven [] = []
filter4allEven ((a,b,c,d):xs)
| all even [a,b,c,d] = (a,b,c,d) : filter4AllEven xs
| otherwise = filter4AllEven xs
(Если использование all
смущает вас, просто прочитайте even a && even b && even c && even d
)
И, наконец, вот функция, которая возвращает все четные компоненты кортежей (сами кортежи не могут быть четными!) В том же порядке, в котором они отображаются в списке аргументов:
evenTupleComponents :: [(Int,Int,Int,Int)] -> [Int]
evenTupleComponents [] = []
evenTupleComponents ((a,b,c,d):xs) = [x | x <- [a,b,c,d], even x] ++ evenTupleComponents
Как только вы выполните пару подобных упражнений, вы поймете, почему использование стандартных функций является хорошей идеей, поскольку все они следуют одинаковым шаблонам, например применяют функцию к каждому кортежу отдельно, включая или исключая кортеж, когда он имеет некоторое свойство или, в более общем смысле, предоставление базового значения для пустого списка и функции объединения для рекурсивного случая. Например, я бы написал evenTupleComponents
как evenTupleComponents = filter even . concatMap (\(a,b,c,d) -> [a,b,c,d])
, но это другая история:)