Я изучаю Haskell и я наткнулся на этот пример, связанный с пониманием списков:[x | xs <- [[(3,4)],[(5,4),(3,2)]], (3,x) <- xs]
Дан ответ: [4,2]
.
Почему нет ответа [(3,4),(3,2)]
?
Сопоставление (3,x)
с (3,4)
дает x = 4
. Если вы хотели (3,4)
, вам следует написать [(3,x) | ...]
.
Я только что дал один; это неясно? Почему вы ожидаете, что x
будет (3,4)
вообще?
Э-э, нет. Я получил спасибо! Я просто жду тайм-аута «Принять ответ». Хотя синтаксис (3,x) <- xs
для меня немного новый.
Левая часть <-
всегда соответствует шаблону; в случае xs <- ...
, xs
— это неопровержимый шаблон, который просто присваивает x
значение из правой части. (3, x)
— это опровержимый шаблон: не все значения представляют собой 2-кортежи с 3
и другим значением, но те, которые есть, имеют другое значение, присвоенное x
. (Это точно такой же тип сопоставления с образцом, который используется в определениях функций, например, f (3, x) = x
вызывает f (3, 5) == 5
.)
@kesarling При использовании списков pat <- list
элементы list
сопоставляются с шаблоном pat
. Те, которые не совпадают, молча отбрасываются. Те, которые совпадают, определяют значения переменных в pat
. Итак, (3,x) <- xs
означает «для всех элементов xs
, имеющих форму (3,x)
(для некоторых x
), ...». Обратите внимание, что x
привязан ко второму компоненту пары, а не ко всей паре.
Почему нет ответа
[(3,4),(3,2)]
?
Понимание списка:
[x | xs <- [[(3,4)],[(5,4),(3,2)]], (3,x) <- xs]
означает, что xs
будет «присвоен» каждому элементу списка [[(3, 4)], [(5, 4), (3, 2)]]
, то есть в первой «итерации» xs
есть [(3,4)]
, а во второй — [(5, 4), (3, 2)]
.
Затем тот же трюк происходит с частью (3, x) <- xs
: она перебирает элементы в xs
и пытается сопоставить их с (3, x)
, поэтому первым «кандидатом» является (3, 4)
, и он соответствует, поэтому x = 4
даст результат; Далее идет (5, 4)
, но это не работает, потому что первый элемент 2-кортежа равен 5
, а не 3
. И, наконец, делается попытка с помощью (3, 2)
, поэтому x
даётся x = 2
.
В результате мы получаем список с 4
и 2
, то есть [4, 2]
.
Хм, не хочу
(3,4)
. Я просто хочу объяснить, как обрабатывается понимание. Текст книги, которую я использую, не дает никакого объяснения приведенному примеру.