global variable

Glynn Clements glynn.clements at virgin.net
Thu Oct 23 05:48:31 EDT 2003


Chris Johansen wrote:

> >> 	I need a function called, say, newItem :: Int,
> >> that when first called returns 1, the next time it
> >> is called it would return 2, then 3 and so
> >> on.
> >
> > That isn't a function. A function is a mapping from
> > argument values to result values; the result depends
> > solely upon the argument.
> 
> Why isn't newItem a function that maps an argument (say lastValue) to the 
> same argument (lastValue) incremented by one?

The problem with that approach is that you have to "thread" the
current value through the execution path. E.g. each function which
might use newItem (or which might eventually call some other function
which does so) has to take an extra argument and return an extra
result. Suppose that you had:

	foo :: a -> b
	...
	
	bar :: a -> c
	...
	
	baz :: a -> (b, c)
	baz x = (foo x, bar x)

and both foo and bar might need to use newItem, you would have to
convert this to:

	foo :: a -> Int -> (b, Int)
	...

	bar :: a -> Int -> (c, Int)
	...

	baz :: a -> Int -> ((b, c), Int)
	baz x curItem =
		let (y, curItem1) = foo x curItem
		    (z, curItem2) = bar x curItem1
		in ((y, z), curItem2)

Similarly throughout any parts of the program where newItem might be
used.

Not only does this result in ugly code, but it can become very easy to
get the different "versions" of the variable confused; this would
typically result in the same "item" being allocated multiple times.

The normal solution to this problem is to use some form of state
transformer monad. For more details, see:

	http://www.abercrombiegroup.co.uk/~noel/research/monads.html

> Does Haskell support recursion?

Yes.

-- 
Glynn Clements <glynn.clements at virgin.net>


More information about the Hugs-Users mailing list