Необходимо использовать null
. В большинстве случаев это не имеет значения, но это - хорошая привычка войти так или иначе, потому что иногда можно хотеть проверить, пуст ли список несопоставимых вещей. Вот короткий, четкий пример, показывающий это различие:
> null [id]
False
> [id] == []
<interactive>:1:1: error:
• No instance for (Eq (a0 -> a0)) arising from a use of ‘==’
(maybe you haven't applied a function to enough arguments?)
• In the expression: [id] == []
In an equation for ‘it’: it = [id] == []
Существует различие. Для использования x == []
, тип элементов списка должен быть членом Eq
typeclass. Действительно, проверка равенства двух списков определяется объявлением экземпляра:
instance Eq a => Eq [a] where
[] == [] = True
(x:xs) == (y:ys) = x == y && xs == ys
_ == _ = False
, Который означает, что Вы не можете использовать x == []
, если x
, например, список IO Int
с.
null :: [a] -> Bool
, с другой стороны, сопоставление с образцом использования. Это реализовано как [1 110]:
null :: [a] -> Bool null [] = True null (_:_) = False
Таким образом независимо, что вводит элементы списка, он всегда будет typecheck.
В дополнение к хорошим ответам, данным до сих пор, null
на самом деле, имеет тип
null :: Foldable t => t a -> Bool
, который я не знаю, добрались ли Вы до typeclasses в LYAH, но за исключением него то, что null
может использоваться не только для списков, но и для любой структуры данных, которая реализует null
.
Это должно сказать, что использование null
на Map
или Set
допустимо, также.
> null Map.empty
True
> null (Map.singleton 1)
False
> null Set.empty
True
> null (Set.singleton 1)
False
> null []
True
> null [1]
False
я не думаю, что особенно распространено записать функции, которые должны быть этим генералом, но не повреждает принимать значение по умолчанию к написанию более общего кода.
стороны А Во многих случаях, Вы закончите тем, что желали использовать функцию как [1 110], чтобы сделать условное поведение в списке (или другая структура данных). Если Вы уже знаете, что Ваш вход является определенной структурой данных, это более изящно только к соответствию шаблона на его пустом ящике.
Выдерживают сравнение
myMap :: (a -> b) -> [a] -> [b]
myMap f xs
| null xs = []
myMap f (x:xs) = f x : myMap f xs
к [1 120]
myMap' :: (a -> b) -> [a] -> [b]
myMap' f [] = []
myMap' f (x:xs) = f x : myMap' f xs
В целом, необходимо попытаться предпочесть сопоставление с образцом, если оно имеет смысл.
Также простая функция, которые фильтруют весь пустой список, перестала бы работать:
withoutEmpty = filter (== [])
и это было бы:
withoutEmpty = filter null
уведомление, что:
withoutEmpty ls = filter (==[]) ls
будет работать просто великолепно, но важный момент - то, который в некоторых случаях как другой мог перестать работать.
Также взгляд @cole ответ, это дополняет все ответы здесь, typeclass Складное имеет эти null
функция там, чтобы быть реализованным:
Для наблюдения большего количества информации Складной здесь