
On 2008 Dec 27, at 15:16, Cristiano Paris wrote:
On Sat, Dec 27, 2008 at 4:50 PM, Hans van Thiel
wrote: However, some functions in Haskell may have side effects, like printing something on the screen, updating a database, or producing a random number. These functions are called 'actions' in Haskell.
Functions may return "actions", which are a special kind of value even though they are no different to Haskell from values of any other type.
There is another way to think about it (which happens to also be the way GHC implements it): an "action" is just a partially applied function. In the case of IO, the missing value is the state, which has the opaque internal type RealWorld# that can't normally be instantiated. (unsafePerformIO works by using an internal function which synthesizes a value of type RealWorld#. Since all the IO code *and* the code generator in GHC assume this can't be done, unsafePerformIO is capable of confusing things rather badly. In particular, you need to tell GHC to inline any code using unsafePerformIO because otherwise it can make incorrect assumptions and very strange behavior will result. UnsafeInterleaveIO is even sneakier: it clones the hidden RealWorld# value, which brings its own kinds of confusion into the mix.) In the normal course of events, your program becomes a long chain of unapplied functions (think foo. bar . baz . (...)), waiting for something to inject a RealWorld# into it. This is the value of "main". Conceptually, the runtime then injects a RealWorld# and the program runs. (In reality, GHC knows that code doesn't actually have to be generated to carry RealWorld# values around, so the generated program ends up looking more or less normal.) -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH