с именем, потому что в блоке
>do
последний оператор, в отличие от предыдущих, не может быть связан с именем. Мы узнаем причины такого поведения немного позднее, когда познакомимся с миром монад. До тех пор можно считать, что блок
>do
автоматически получает результат последнего оператора и возвращает его в качестве собственного результата.
За исключением последней строчки, каждая строка в блоке >do
может быть использована для связывания. Например, >putStrLn "ЛЯ"
может быть записана как >_ <– putStrLn "ЛЯ"
. Но в этом нет никакого смысла, так что мы опускаем ><–
для действий ввода-вывода, не возвращающих значимого результата.
Иногда начинающие думают, что вызов
>myLine = getLine
считает значение со стандартного входа и затем свяжет это значение с именем >myLine
. На самом деле это не так. Такая запись даст функции >getLine
другое синонимичное имя, в данном случае – >myLine
. Запомните: чтобы получить значение из действия ввода-вывода, вы должны выполнять его внутри другого действия ввода-вывода и связывать его с именем при помощи символа ><–
.
Действие ввода-вывода будет выполнено, только если его имя >main
или если оно помещено в составное действие с помощью блока >do
. Также мы можем использовать блок >do
для того, чтобы «склеить» несколько действий ввода-вывода в одно. Затем можно будет использовать его в другом блоке >do
и т. д. В любом случае действие будет выполнено, только если оно каким-либо образом вызывается из функции >main
.
Ах, да, есть ещё один способ выполнить действие ввода-вывода! Если напечатать его в интерпретаторе GHCi и нажать клавишу Enter, действие выполнится.
>gchi> putStrLn "При-и-и-вет"
>При-и-и-вет
Даже если мы просто наберём некоторое число или вызовем некоторую функцию в GHCi и нажмём Enter, интерпретатор GHCi вычислит значение, затем вызовет для него функцию >show
, чтобы получить строку, и напечатает строку на терминале, используя функцию >putStrLn
.
Использование ключевого слова let внутри блока do
Помните связывания при помощи ключевого слова >let
? Если уже подзабыли, освежите свои знания. Связывания должны быть такого вида: >let <определения> in <выражение>
, где ><определения>
– это имена, даваемые выражениям, а ><выражение>
использует имена из ><определений>
. Также мы говорили, что в списковых выражениях часть >in
не нужна. Так вот, в блоках >do
можно использовать выражение >let
таким же образом, как и в списковых выражениях. Смотрите:
>import Data.Char
>main = do
> putStrLn "Ваше имя?"
> firstName <– getLine
> putStrLn "Ваша фамилия?"
> lastName <– getLine
> let bigFirstName = map toUpper firstName