I’ve been diving into functional programming for more than 3 years and I’ve been reading and understanding many articles and aspects of functional programming.
But I often stumbled into many articles about the “world” in side effect computations and also carrying and copying the “world” in IO monad samples. What does the “world” means in this context? Is this the same “world” in all side effect computation context or is it only applied in IO monads?
Also the documentation and other articles about Haskell mention the “world” many times.
Some reference about this “world”:
I expect a sample, not just explanation of the world concept. I welcome sample code in Haskell, F#, Scala, Scheme.
Practice As Follows
The “world” is just an abstract concept that captures “the state of the world”, i.e. the state of everything outside the current computation.
Take this I/O function, for example:
write : Filename -> String -> ()
This is non-functional, as it changes the file (whose content is part of the state of the world) by side effect. If, however, we modelled the world as an explicit object, we could provide this function:
write : World -> Filename -> String -> World
This takes the current world and functionally produces a “new” one, with the file modified, which you can then pass to consecutive calls. The World itself is just an abstract type, there is no way to peek at it directly, except through corresponding functions like
Now, there is one problem with the above interface: without further restrictions, it would allow a program to “duplicate” the world. For example:
w1 = write w "file" "yes" w2 = write w "file" "no"
You’ve used the same world
w twice, producing two different future worlds. Obviously, this makes no sense as a model for physical I/O. To prevent examples like that, a more fancy type system is needed that makes sure that the world is handled linearly, i.e., never used twice. The language Clean is based on a variation of this idea.
Alternatively, you can encapsulate the world such that it never becomes explicit and thereby cannot be duplicated by construction. That is what the I/O monad achieves — it can be thought of as a state monad whose state is the world, which it threads through the monadic actions implicitly.