Hello, 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. How can I achieve this? Thank you
Jose Morais 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. Unlike many other languages, Haskell's "functions" really are functions, not value-returning procedures (which is what most other languages seem to mean by "function").
How can I achieve this?
You can't. At least, not without using unsafePerformIO, which:
a) isn't in the Haskell 98 standard, and
b) is more likely to result in confusion than in working code (some
uses of unsafePerformIO are easy to get right; this isn't one of
them).
A more realistic approach is to use a monad which supports mutable
references, e.g. the ST monad with STRefs or the IO monad with IORefs.
See:
http://www.haskell.org/ghc/docs/latest/html/base/Data.STRef.html
http://www.haskell.org/ghc/docs/latest/html/base/Data.IORef.html
BTW, you will probably need to be familiar with state monads (e.g.
Haskell I/O) in order to make any sense of that.
--
Glynn Clements
On Sun, 12 Oct 2003 19:32:14 +0100, Glynn Clements
Jose Morais 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? Does Haskell support recursion? Just a learner's ignorant questions. Regards, -- Chris Johansen {johansen at main dot nc dot us}
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
participants (3)
-
Chris Johansen -
Glynn Clements -
Jose Morais