>ghci> badAdd [100, 20]
>*** Exception: Non-exhaustive patterns in function badAdd
Это не так уж и хорошо. Если подобное случится в скомпилированной программе, то она просто вылетит.
И последнее замечание относительно сопоставления с образцами для списков: в образцах нельзя использовать операцию >++
(напомню, что это объединение двух списков). К примеру, если вы попытаетесь написать в образце >(xs++ys)
, то Haskell не сможет определить, что должно попасть в >xs
, а что в >ys
. Хотя и могут показаться логичными сопоставления типа >(xs++[x,y,z])
или даже >(xs ++ [x])
, работать это не будет – такова природа списков[7].
Ещё одна конструкция называется именованным образцом. Это удобный способ разбить что-либо в соответствии с образцом и связать результат разбиения с переменными, но в то же время сохранить ссылку на исходные данные. Такую задачу можно выполнить, поместив некий идентификатор образца и символ >@
перед образцом, описывающим структуру данных. Например, так выглядит образец >xs@(x:y:ys)
.
Подобный образец работает так же, как (>x:y:ys)
, но вы легко можете получить исходный список по имени >xs
, вместо того чтобы раз за разом печатать >x:y:ys
в теле функции. Приведу пример:
>firstLetter :: String –> String
>firstLetter "" = "Упс, пустая строка!"
>firstLetter all@(x:xs) = "Первая буква строки " ++ all ++ " это " ++ [x]
Загрузим эту функцию и посмотрим, как она работает:
>ghci> firstLetter "Дракула"
>"Первая буква строки Дракула это Д"