Сопоставление с образцом и понимание списка в списке кортежей - PullRequest
2 голосов
/ 06 июня 2011
type a = [(Int,Int,Int,Int)]

fun:: a -> Int
func [a,b,c,d] = ?

У меня есть список таких кортежей, что мне нужно было применить list comprehensions или pattern matching .. пример, взяв сумму или фильтр, разделив только 2 числа ... я просто хочу начать с того, как для доступа к значениям и / или пониманию списка к этому списку кортежей

Ответы [ 2 ]

8 голосов
/ 06 июня 2011

Для суммирования a s используйте что-то вроде этого:

type A = [(Int, Int, Int, Int)]

func :: A -> Int
func tuples = sum [a | (a, b, c, d) <- tuples]

Также обратите внимание, что псевдоним типа должен начинаться с заглавной буквы.Строчные буквы используются для типа переменных .

3 голосов
/ 06 июня 2011

ответ Хаммара покрыл списки, базовая схема для рекурсивных функций с использованием сопоставления с образцом:

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]), но это другая история:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...