Question

I have a Data.Sequence which I need to iterate over. The problem is that its stateful, and the sequence may grow as a result of said iteration.

data Chart = Chart {
       charts :: M.Map Int (Seq.Seq RState), --map from position to list of chart states
       ...
} deriving (Show)


processChartSeq :: Int -> Int  -> State Chart ()
processChartSeq chtIndx stIndx = do s <- get
                                    let seq = fromJust $ M.lookup chtIndx (charts s)
                                        rstate = Seq.index seq  stIndx
                                    processState rstate
                                    when (stIndx < Seq.length seq) (processChartSeq chtIndx (stIndx+1))

So I'm doing this with explicit recursion, but it seems clunky. Furthermore, it seems like a common thing to do. What common monadic control structure did I re-invent, badly?

Was it helpful?

Solution

To answer the initial question, you "reinvented" the state monad within the state monad itself! You could move the stuff you're explicitly threading into your state to avoid passing it directly. On the other hand, for simple things like this, I have no problem passing things around explicitly, and often find it cleaner.

Finally, as Daniel Wagner notes, you should be pushing and popping from the top as much as possible, for the sake of efficiency.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top