Latest revision as of 01:25, 17 September 2010

Contents

(Perhaps annoyingly) the answer to this question, like so many other
frequently asked questions, is a question. "What are you trying to do?"

The reason for this is that haskell's abstractions are different from
those of the mainstream imperative languages, and the mapping isn't 1-1.
So for a particular 'C' feature, there may be 3 or 4 haskell features
which achieve similar effects, and the correct choice depends on the
detailed context.

So, in particular, all those tasks which you use global variables for in
C, can be achieved in haskell, but which solution depends what you are
trying to do:

If you have some globals which are constant, then just define them at the top level. No problem.

pi=3.14

progname ="MyCoolApp"

If you have a global environment, which various functions read from (and you might, for example, initialise from a configuration file) then you should thread that as a parameter to your functions (after having, very likely, set it up in your 'main' action). If the explicit parameter passing annoys you, then you can 'hide' it with a Monad.

If you have a need to store some global state which various of your functions modify, then you have a design issue. This style of design is frowned upon in C as well! The correct solution in C is to pass a 'bundle' of appropriate parameters (you might call it an environment) to those functions which need it. In C++, perl or python you'd very likely make this bundle an object. In haskell this bundle will be a data value in some custom type; and using Monads you can 'hide the details' of passing it around, if you wish.

John Hughes has a Functional Pearl which advocates the use of implicit parameters for global variables. He also mentions the unsafePerformIO hack and the use of a Reader monad transformer, none of which are totally satisfactory: Global Variables in Haskell (2004)