Подтвердить что ты не робот

Haskell: проверьте, равны ли два списка

Я хочу проверить, равны ли два списка A и B, т.е. a1 == b1, a2 == b2,...

У меня есть рабочее решение:

all (\x->x) zipWith $ (==) A B

Другая идея - сделать это рекурсивно: a:as, b:bs; проверьте a1==b1 и вызовите функцию с оставшимися списками as и bs. Но нет ли здесь более простого и понятного способа сделать это?

4b9b3361

Ответ 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.