Haskell puts all side effects in the IO
monad, which passes around the
RealWorld
. This is unsatisfactory for a number of reasons, and Haskellers have spilled much ink on effects systems.
As I recently noted, there are
distinctions in how one handles effects at the logical level: in particular,
randomness is different from array writes.
In Haskell, the IO
type is defined as:
newtype IO a = IO (RealWorld -> (a, RealWorld))
One can imagine a monad for randomness which carries around the seed for a generator:
newtype Rand a = Rand (Seed -> (a, Seed))
These rhyme but there is a moral difference between RealWorld
and Seed
: the RealWorld
cannot be duplicated (or discarded), while pseudorandom number generators split:
split : Seed -> (Seed, Seed)
In the language of Girard, this is object vs. object factory: a RealWorld
is
an object, and a Seed
begets a Seed
factory.
Intriguingly, Verse (a functional language) makes this distinction. Established functional programming languages lack facilities to handle linearity; there is a need to adopt modern ideas from logic in order to clarify various problems in the field.