Haskell: проверьте, равны ли два списка
Я хочу проверить, равны ли два списка A
и B
, т.е. a1 == b1, a2 == b2
,...
У меня есть рабочее решение:
all (\x->x) zipWith $ (==) A B
Другая идея - сделать это рекурсивно: a:as, b:bs
; проверьте a1==b1
и вызовите функцию с оставшимися списками as
и bs
. Но нет ли здесь более простого и понятного способа сделать это?
Ответы
Ответ 1
Вы можете просто использовать ==
для них непосредственно.
> [1, 2, 3] == [1, 2, 3]
True
> [1, 2, 3] == [1, 2]
False
Это связано с тем, что ==
является частью класса типа Eq
, и есть экземпляр Eq
для списков, который выглядит примерно так:
instance Eq a => Eq [a]
Это означает, что перечисляет экземпляр Eq
, пока тип элемента также создает экземпляр Eq
, что имеет место для всех типов, определенных в стандартных прелюдиях, кроме функций и IO
.
Ответ 2
Во-первых, ответ хаммера правильный, поэтому примите его ответ, пожалуйста. (Редактирование: что вы сделали, спасибо.)
listA == listB
(Я собираюсь рассказать о мелких деталях в вашем вопросе, в основном для будущих начинающих, которые найдут эту страницу в Google.)
Во-вторых, A
и B
не являются списками: они начинаются с букв верхнего регистра, поэтому они не могут быть переменными. Я назову их listA
и listB
.
В-третьих, в вашем рабочем решении есть опечатка: $
должен быть до zipWith
, а не после. То, как оно появляется в вашем вопросе, приводит к ошибке компиляции. Я думаю, вы имели в виду это:
all (\x->x) $ zipWith (==) listA listB
В-четвертых, (\x->x)
лучше известен как функция id
.
all id $ zipWith (==) listA listB
В-пятых, как указывает Матвей, all id
совпадает с and
.
and $ zipWith (==) listA listB
В-шестых, они делают разные вещи, когда списки имеют разную длину. Использование (==)
непосредственно в списках приведет к False
, тогда как zipWith
будет игнорировать лишние элементы. То есть:
[1,2,3] == [1,2] -- False
and $ zipWith (==) [1,2,3] [1,2] -- True
Теперь есть ситуации, когда вам нужно второе поведение. Но вы почти наверняка хотите первое поведение.
Наконец, чтобы подчеркнуть, просто используйте (==)
непосредственно в списках:
listA == listB
Ответ 3
Вы можете заменить all (\x -> x)
на and
.