I’m porting some code to Haskell that extensively uses the concept of
a peeking iterator. It essentially wraps a collection and provides two
functions, “next” and “peek”. The “next” function advances the
iterator and returns the head element, while the “peek” function
returns the head element without advancing the iterator. What would be
an elegant way to translate this concept to Haskell? My best idea so
far is to basically use the State monad to keep track of the current
position of the iterator. Is there a cleaner way?
(I posted this on beginners@ too, but didn’t get any answers)
The idea of a side-effecting iterator is antithetical to the Haskell Way. You could certainly whip up a monad, but at that point you’re using Haskell as (to quote Simon PJ) the world’s finest imperative language.
Without knowing more about the code you’re trying to port, I can’t give very specific advice, but here are my general thoughts:
Implement your iteration using some kind of fold.
The function that you pass to your fold operation should be composed of other functions. Probably a composition of zero or more ‘peeking’ operations plus one ‘nexting’ operation.
If your fold expects something of type
a -> b -> a, yourpeekandnextversions probably both have this type, and you compose them like this:You’ll see that both the
peekandnextarguments look at the sameb, but thepeekaccumulates information intoa'which is then seen by thenextoperation.You compose as many of these as you like, then pass the composition to
foldlor something similar.