Каноническое объяснение этого заключается в том, что вы хотите сформировать новое монадическое значение из двух существующих.Давайте посмотрим на тип putStr,
IO ()
Это означает, что это какой-то черный ящик, который при выполнении будет «возвращать» (единственное) значение типа блока.Основная идея монадических вычислений заключается в том, что у вас есть комбинатор >>=
, который объединит два монадических выражения, передавая результат одного в другое (точнее, функцию, которая создает следующее).Одним из важных моментов является то, что библиотека IO
предоставляет этот комбинатор , что означает, что
- Это [IO в этом случае] может пропускать второе монадическое значение, например, когдапервый вызывает исключение.
- Может передавать другие данные, в случае
IO
a RealWorld
состояния, содержащего дескрипторы открытого файла и т. д. - Он может «гарантировать», чтопервый оценивает первый, в отличие от большинства вычислений лямбда-выражений, где самые внешние («последние») термины расширяются первыми.Это важно для печати, где первый отпечаток должен изменить мир первым.
В вашем случае используйте его следующим образом:
putStr "0" >>= (\c -> putStr "0")
Есть, конечно, ярлык,
putStr "0" >> putStr "0"
и примечание do, как упомянуто другим автором, которое является еще более синтаксическим сахаром,
do
putStr "0"
putStr "0"