Хорошо. Давайте пройдемся по различным синтаксическим элементам здесь.
Строка 1
select :: Ord a => a -> [a] -> [a]
Это объявление типа. Это объявление функции (так как она имеет ->
типов).
Функция имеет два аргумента.
- Первое - это одиночное значение любого типа, обозначаемое
a
(нижний регистр означает, что это полиморфный тип).
- Второй аргумент - это список любого типа, который совпадает с первым аргументом.
Возвращаемое значение представляет собой список любого типа, такой же, как типы аргументов.
Компонент Ord a
является ограничением класса типов, в котором говорится, что любой тип, который дается этой функции, также должен быть экземпляром класса Ord
. Это класс типов, которые можно сравнивать.
Строка 2
Теперь мы смотрим на строку 2:
select y [] = []
Это одно из определений самой функции select
. Это очень просто, содержит шаблоны для двух аргументов и спецификацию результата. Читается:
если первым аргументом является какое-либо значение (которое мы назовем y
), а вторым аргументом является пустой список (обозначаемый шаблоном []
), то select
оценивается как пустой список.
Строка 3
Строка 3 содержит другой регистр для списков:
select y (x:xs)
Опять же, это часть определения функции select
, для случая, когда вторым аргументом является , а не пустой список. Если это не пустой список, то это список с заголовком x
и хвостом xs
. Конструктор "cons" (:)
объединяет начало и конец списка. Это также, как мы сопоставляем образец по списку, чтобы извлечь голову и хвост.
Путем сопоставления с образцом в начале и в конце списка, с помощью (x:xs)
мы привязываем новую переменную x
к значению заголовка списка и xs
к значению хвоста список.
Строки 4 и 5
Последние две строки - это дополнительные охранники , которые проверяют и разветвляют на основе дополнительных проверок, если второй аргумент будет непустым списком:
| x < y = x : select y xs
| otherwise = select y xs
Первый охранник срабатывает, когда x
меньше первого аргумента y
. Если это так, мы возвращаем новый список с x
в заголовке и select
, примененным снова к хвосту.
Если это не так, то мы удаляем x
из списка и возвращаем только то, что происходит, когда tail вызывается рекурсивно.
Для получения дополнительной информации о том, как работает Haskell, я рекомендую вводные тексты, такие как:
это будет стоить вашего времени.