В Haskell существует концепция, называемая чистым кодом. Чистый код не имеет ничего из следующего: вводимые пользователем значения, системные вызовы, генерация псевдослучайных чисел, вызовы нечистого кода и т. Д.
Гарантируется, что чистые функции всегда всегда будут иметь одинаковое поведение в зависимости от лексического содержания вашей программы (например, они могут возвращать разные значения, но причина, по которой они возвращают разные значения, не может зависеть от "мира").
Это очень мощная политика в функциональных языках, которая допускает очень мощный код. Например, вы знаете, что вызов функции не изменит какую-либо несвязанную глобальную переменную или состояние какой-либо другой структуры данных. Я часто применяю эту политику к коду Python.
То, как Хаскелл навязывает чистоту-примесь, - это монада IO.
Все, что касается "мира", заключено в монаду IO, которая представляла, что значения были "испорчены". Если что-либо касается этих «испорченных» значений, возвращаемые ими значения также должны быть испорчены.
Вам нужно будет запустить чистый код в монаде ввода-вывода, если вы хотите, чтобы он имел доступ к этим значениям. Оказавшись внутри монады ввода-вывода, вы можете «развернуть» прочитанное вами значение и передать его в ваш чистый код, затем ваш чистый код возвращает значение, а затем вы можете напечатать свое значение. Все работает как положено, но вы должны сделать это в монаде IO.
Обратите внимание, что хорошо бы убедиться, что большая часть вашего кода написана в чистой, функциональной форме, кроме монады ввода-вывода. например чистая doStuffWithRectangles
функция, которая затем вызывается из монады IO.
Прекрасно то, что вашему чистому коду не нужно знать, что значение Rectangle
было испорчено типом IO Rectangle
. Пока вы работаете в монаде IO, ваш чистый код будет думать, что это просто обычный Rectangle
.
И просто, чтобы сделать этот ответ более явным: readFile
возвращает вещи, завернутые в монаду ввода / вывода, потому что эти вещи происходят из "мира" (файловой системы) и, например, если вы изменили файл во время выполнения программы, он может вернуть другое значение.
--db = loadFile "db.txt" REMOVED--
main = do --within the IO monad
putStrLn "Choose option:"
n <- getLine
**DB <- LOADFILE "db.txt"** --db is now a pure value
case n of
"1" -> do menuRectangles db; main
"2" -> putStrLn "bye, bye"
otherwise -> do putStrLn "Bad option"; main
Дополнительная информация: http://www.haskell.org/tutorial/io.html
Хорошее онлайн / прочтение: http://learnyouahaskell.com/
Также хорошо читать онлайн / оффлайн: http://book.realworldhaskell.org/