57
задан 15 July 2019 в 12:37

4 ответа

Необходимо использовать 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] == []
66
ответ дан 1 November 2019 в 15:49

Существует различие. Для использования 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.

49
ответ дан 1 November 2019 в 15:49

В дополнение к хорошим ответам, данным до сих пор, 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

В целом, необходимо попытаться предпочесть сопоставление с образцом, если оно имеет смысл.

26
ответ дан 1 November 2019 в 15:49

Также простая функция, которые фильтруют весь пустой список, перестала бы работать:

withoutEmpty = filter (== [])

и это было бы:

withoutEmpty = filter null

уведомление, что:

withoutEmpty ls = filter (==[]) ls

будет работать просто великолепно, но важный момент - то, который в некоторых случаях как другой мог перестать работать.

Также взгляд @cole ответ, это дополняет все ответы здесь, typeclass Складное имеет эти null функция там, чтобы быть реализованным:

Для наблюдения большего количества информации Складной здесь

2
ответ дан 1 November 2019 в 15:49

Другие вопросы по тегам:

Похожие вопросы: