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

>       bigLastName = map toUpper lastName

>   putStrLn $ "Привет, " ++ bigFirstName ++ " "

>                         ++ bigLastName

>                         ++ ", как дела?"

Видите, как выровнены операторы действий ввода-вывода в блоке >do? Обратите внимание и на то, как выровнено выражение >let по отношению к действиям ввода-вывода и как выровнены образцы внутри выражения >let. Это хороший пример, потому что выравнивание текста очень важно в языке Haskell. Далее мы записали вызов >map>toUpper>firstName, что превратит, например, >"Иван" в намного более солидное >"ИВАН". Мы связали эту строку в верхнем регистре с именем, которое использовали в дальнейшем при выводе на терминал.

Вам может быть непонятно, когда использовать символ ><–, а когда выражение >let. Запомните: символ ><– (в случае действий ввода-вывода) используется для выполнения действий ввода-вывода и связывания результатов с именами. Выражение >map toUpper firstName не является действием ввода-вывода – это чистое выражение. Соответственно, используйте символ ><– для связывания результатов действий ввода-вывода с именами, а выражение >let – для связывания имён с чистыми значениями. Если бы мы выполнили что-то вроде >let firstName = getLine, то просто создали бы синоним функции >getLine, для которого значение всё равно должно получаться с помощью символа ><–.

Обращение строк

Теперь напишем программу, которая будет считывать строки, переставлять в обратном порядке буквы в словах и распечатывать их. Выполнение программы прекращается при вводе пустой строки. Итак:

>main = do

>   line <– getLine

>   if null line

>       then return ()

>       else do

>          putStrLn $ reverseWords line

>          main


>reverseWords :: String –> String

>reverseWords = unwords . map reverse . words

Чтобы лучше понять, как работает программа, сохраните её в файле reverse.hs, скомпилируйте и запустите:

>$ ghc reverse.hs

>[1 of 1] Compiling Main ( reverse.hs, reverse.o )

>Linking reverse ...

>$ ./reverse

>уберитесь в проходе номер 9

>ьсетиребу в едохорп ремон 9

>козёл ошибки осветит твою жизнь

>лёзок икбишо титевсо юовт ьнзиж

>но это всё мечты

>он отэ ёсв ытчем

Для начала посмотрим на функцию >reverseWords. Это обычная функция, которая принимает строку, например >"эй ты мужик", и вызывает функцию >words, чтобы получить список слов >["эй", "ты","мужик"]. Затем мы применяем функцию >reverse к каждому элементу списка, получаем >["йэ","ыт","кижум"] и помещаем результат обратно в строку, используя функцию >unwords. Конечным результатом будет >"йэ ыт кижум".

Теперь посмотрим на функцию >main. Сначала мы получаем строку с терминала с помощью функции