Writing a counter function
John Hughes
rjmh@cs.chalmers.se
Sat, 29 Jun 2002 19:53:17 +0200 (MET DST)
On Sat, 29 Jun 2002, Shlomi Fish wrote:
>
> No. But I want to generate an irregular series, which I determine the
> intervals between two consecutive numbers myself. E.g:
>
> let (num1, next1) = (counter 5)
> (num2, next2) = (next1 100)
> (num3, next3) = (next2 50) in
> [num1,num2,num3]
>
> Will have the numbers [5, 105, 155].
>
The other answers you've received really question whether this is a good
way to use Haskell at all --- usually, if you want to generate a sequence
of values, it's a good idea just to represent them explicitly as a (lazy)
list. For example, you can compute more-or-less the same result as you
want just using standard list processing functions:
Main> scanl (+) 0 [5,100,50]
[0,5,105,155]
However, you can also do almost exactly what you suggest. Not quite
exactly, because the function you describe would have a recursive type
type Counter = Int -> (Int, Counter)
and Haskell requires that type recursion involve a data or newtype. So,
here's a solution:
newtype Counter = Counter (Int -> (Int, Counter))
count :: Counter -> Int -> (Int, Counter)
count (Counter c) = c
counter n = (n, Counter next)
where next k = counter (n+k)
xs = let (num1, next1) = (counter 5)
(num2, next2) = (next1 `count` 100)
(num3, next3) = (next2 `count` 50) in
[num1,num2,num3]
Main> xs
[5,105,155]
The only difference from your idea is that a counter is not a function; we
have to use the function count to invoke it. And that's forced on us by
the need to avoid type recursion.
John Hughes