Если вы напишите [x]
, список с одним элементом, это сокращение от (x : [])
или даже более подробный (:) x []
. Так что это «минусы» ((:)
) с x
в качестве элемента и пустой список в качестве хвоста.
Так что ваша функция f (x:xs)
действительно будет сопоставлять список с одним (или более) элементами,Для списка с одним элементом x
будет элементом, а xs
пустым списком.
не будет соответствовать, потому что шаблон (x:xs)
соответствует только при наличии большего количества элементовxs
после x
в списке, что не относится к списку [1]
.
Нет (x:xs)
совпадает с каждым непустым list, с x
первым элементом списка и xs
a (возможно, пустым) списком оставшихся элементов.
Если вы хотите сопоставлять только списки, например, с двумя или более элементами. Вы можете сопоставить это с:
-- two or more elements
f (x<sub>1</sub> : x<sub>2</sub> : xs) = …
Здесь x<sub>1</sub>
и x<sub>2</sub>
будут соответствовать первому и второму элементу списка соответственно, а xs
- список, содержащий оставшиеся элементы.
РЕДАКТИРОВАТЬ : ответить ваши комментарии :
Интересно, почему мое определение функции вообще компилируется, потому что тип функцииравно [Int] -> [Int]
, так что если я дам ему пустой список, то это не [Int]
в результате, не так ли?
Пустой список []
является одним из конструкторов данныхтип [a]
, что означает, что []
имеет тип [] :: [a]
. Он может соответствовать переменной типа a
с Int
, и, таким образом, []
может иметь тип [] :: [Int]
.
Во-вторых, как сопоставить список точно с двумя элементами? [a, b]
?
Вы можете сопоставить такой список с:
f (a : b : []) = …
или вы можете сопоставить его с:
f [a, b] = …
Оба значения эквивалентны. [a, b]
- это синтаксический сахар : он заменен компилятором на (a : b : [])
, но для людей, конечно, удобнее работать с [a, b]
.