Изучай Haskell во имя добра! (Липовача) - страница 121

. Далее у нас имеется условное выражение. Запомните, что в языке Haskell каждое ключевое слово >if должно сопровождаться секцией >else, так как каждое выражение должно иметь некоторое значение. Наш оператор записан так, что если условие истинно (в нашем случае – когда введут пустую строку), мы выполним одно действие ввода-вывода; если оно ложно – выполним действие ввода-вывода из секции >else. По той же причине в блоке >do условные операторы >if должны иметь вид >if <условие> then <действие ввода-вывода> else <действие ввода-вывода>.

Вначале посмотрим, что делается в секции >else. Поскольку можно поместить только одно действие ввода-вывода после ключевого слова >else, мы используем блок >do для того, чтобы «склеить» несколько операторов в один. Эту часть можно было бы написать так:

>else (do

>    putStrLn $ reverseWords line

>    main)

Подобная запись явно показывает, что блок >do может рассматриваться как одно действие ввода-вывода, но и выглядит она не очень красиво. В любом случае внутри блока >do мы можем вызвать функцию >reverseWords со строкой – результатом действия >getLine и распечатать результат. После этого мы выполняем функцию >main. Получается, что функция >main вызывается рекурсивно, и в этом нет ничего необычного, так как сама по себе функция >main – тоже действие ввода-вывода. Таким образом, мы возвращаемся к началу программы в следующей рекурсивной итерации.

Ну а что случится, если мы получим на вход пустую строку? В этом случае выполнится часть после ключевого слова >then. То есть выполнится выражение >return (). Если вам приходилось писать на императивных языках вроде C, Java или на Python, вы наверняка уверены, что знаете, как работает функция >return – и, возможно, у вас возникнет искушение пропустить эту часть текста. Но не стоит спешить: функция >return в языке Haskell работает совершенно не так, как в большинстве других языков! Её название сбивает с толку, но на самом деле она довольно сильно отличается от своих «тёзок». В императивных языках ключевое слово >return обычно прекращает выполнение метода или процедуры и возвращает некоторое значение вызывающему коду. В языке Haskell (и особенно в действиях ввода-вывода) одноимённая функция создаёт действие ввода-вывода из чистого значения. Если продолжать аналогию с коробками, она берёт значение и помещает его в «коробочку». Получившееся в результате действие ввода-вывода на самом деле не выполняет никаких действий – оно просто инкапсулирует некоторое значение. Таким образом, в контексте системы ввода-вывода >return "ха-ха"