Null вместо ==
Я только начал изучать Хаскелла из интереса. Я следую learnyouahaskell.com.
Там я нашел это:
null
проверяет, пуст ли список. Если оно is, он возвращает True
, в противном случае возвращает False
. Используйте эту функцию вместо xs == []
(если у вас есть список под названием xs
)
Почему? Почему мы должны использовать null
вместо ==
, когда оба дают один и тот же результат?
Спасибо.
Ответы
Ответ 1
Сравнение списков с ==
требует, чтобы элементы были сопоставимыми (обозначались как Eq a
).
Prelude> :t (==[])
(==[]) :: (Eq a) => [a] -> Bool
Например, [sin] == []
не будет работать, поскольку вы не можете сравнивать функции. Это может показаться глупым, но система типов должна судить о типе выражения, не глядя на его значение.
Альтернативная проверка будет length xs == 0
, это не требует равенства, но не остановится, если ваш список бесконечен (попробуйте length [1..] == 0
). Вот почему есть специальная функция.
null [] = True
null _ = False
Prelude> :t null
null :: [a] -> Bool -- Notice lack of (Eq a).
Ответ 2
По-моему, null myList
читается более естественно, чем myList == []
.
Но raison d'être для null
заключается в том, что он может использоваться как функция. Например, здесь функция, которая берет список списков и возвращает только непустые:
nonemptyLists :: [[a]] -> [[a]]
nonemptyLists = filter (not . null)
Без null
это было бы более неудобно:
nonEmptyLists = filter ([] /=)
Ответ 3
Другим преимуществом использования null
является то, что многие другие контейнеры (например, Data.Sequence, Data.ByteString и т.д.) также имеют функцию null
. Это упрощает переход на другую реализацию, просто изменив ваши инструкции импорта.