×
Traktatov.net » Изучай Haskell во имя добра! » Читать онлайн
Страница 8 из 245 Настройки

>478

Вы можете вызывать свои собственные функции из других созданных вами же функций. Учитывая это, можно переопределить >doubleUs следующим образом:

>doubleUs x y = doubleMe x + doubleMe y

Это очень простой пример общего подхода, применяемого во всём языке – создание простых базовых функций, корректность которых очевидна, и построение более сложных конструкций на их основе.

Кроме прочего, подобный подход позволяет избежать дублирования кода. Например, представьте себе, что какие-то «математики» решили, будто 2 – это на самом деле 3, и вам нужно изменить свою программу. Тогда вы могли бы просто переопределить >doubleMe как >x + x + x, и поскольку >doubleUs вызывает >doubleMe, данная функция автоматически работала бы в странном мире, где 2 – это 3.

Теперь давайте напишем функцию, умножающую число на два, но только при условии, что это число меньше либо равно 100 (поскольку все прочие числа и так слишком большие!):

>doubleSmallNumber x = if x > 100

>                      then x

>                      else x*2

Мы только что воспользовались условной конструкцией >if в языке Haskell. Возможно, вы уже знакомы с условными операторами из других языков. Разница между условной конструкцией >if в Haskell и операторами >if из императивных языков заключается в том, что ветвь >else в языке Haskell является обязательной. В императивных языках вы можете просто пропустить пару шагов, если условие не выполняется, а в Haskell каждое выражение или функция должны что-то возвращать[4].

Можно было бы написать конструкцию >if в одну строку, но я считаю, что это не так «читабельно». Ещё одна особенность условной конструкции в языке Haskell состоит в том, что она является выражением. Выражение – это код, возвращающий значение. >5 – это выражение, потому что возвращает 5; >4 + 8 – выражение, >x + y – тоже выражение, потому что оно возвращает сумму x и y.

Поскольку ветвь >else обязательна, конструкция >if всегда что-нибудь вернёт, ибо является выражением. Если бы мы хотели добавить единицу к любому значению, получившемуся в результате выполнения нашей предыдущей функции, то могли бы написать её тело вот так:

>doubleSmallNumber' x = (if x > 100 then x else x*2) + 1

Если опустить скобки, то единица будет добавляться только при условии, что >x не больше 100. Обратите внимание на символ апострофа (>') в конце имени функции. Он не имеет специального значения в языке Haskell. Это допустимый символ для использования в имени функции.

Обычно мы используем символ прямого апострофа >' для обозначения строгой (не ленивой) версии функции либо слегка модифицированной версии функции или переменной. Поскольку апостроф – допустимый символ в именах функций, мы можем определять такие функции:

>conanO'Brien = "Это я, Конан О'Брайен!"

Здесь следует обратить внимание на две важные особенности. Во-первых, в названии функции мы не пишем имя >conan с прописной буквы. Дело в том, что наименования функций не могут начинаться с прописной буквы – чуть позже мы разберёмся, почему. Во-вторых, данная функция не принимает никаких пара метров.

Когда функция не принимает аргументов, говорят, что это