Кроме того, разве нельзя описать какую-либо непростую функцию, например, функцию реального мира? Например, разве мы не можем думать о, скажем, malloc C как о функции, которая принимает RealWorld и Int и возвращает указатель и RealWorld, только так же, как в IO-монаде, неявный RealWorld?
Точно ...
Вся идея функционального программирования состоит в том, чтобы описать программы как комбинацию небольших независимых вычислений построения больших вычислений.
Имея эти независимые вычисления, вы получите множество преимуществ - от кратких программ до эффективных и действенно распараллеливаемых кодов, от лени до строгой гарантии того, что управление передается по назначению - без шансов на вмешательство или искажение произвольных данных.
Теперь - в некоторых случаях (например, IO) нам нужен нечистый код. Вычисления, включающие такие операции , не могут быть независимыми - они могут изменять произвольные данные другого вычисления.
Дело в том, что Haskell всегда чист , IO
не меняет этого.
Итак, наши нечистые, независимые коды должны получить общую зависимость - мы должны передать RealWorld
. Поэтому, какие бы вычисления с состоянием мы ни хотели выполнить, мы должны передать эту вещь RealWorld
, чтобы применить наши изменения - и что бы другие вычисления с состоянием не хотели увидеть или внести изменения, они должны знать также RealWorld
.
Неважно, делается ли это явно или неявно через монаду IO
. Вы создаете программу на Haskell как гигантские вычисления, которые преобразуют данные, и одна часть этих данных - RealWorld
.
Как только начальный main :: IO ()
вызывается, когда ваша программа запускается с текущим реальным миром в качестве параметра, этот реальный мир переносится через все нечистые вычисления, как и данные в State
. Вот о чем заботится монадический >>=
(bind).
И там, где RealWorld
не получается (как в чистых вычислениях или без >>=
-ing до main
), нет никаких шансов что-либо сделать с ним. И где он получает , что произошло путем чисто функциональной передачи (неявного) параметра. Вот почему
let foo = putStrLn "AAARGH" in 42
абсолютно ничего не делает - и почему монада IO
- как и все остальное - чиста. То, что происходит внутри этого кода, конечно, может быть нечистым, но все это поймано внутри, без возможности вмешательства в несвязанные вычисления.