There are multiple ways to process arrays. In a language like Haskell, where recursion is the main control mechanism, there are two ways that you should be familar with.
printEach :: Show a => Array a -> IO () -- write a contract
printEach a = -- define the wrapper
do { (low,high) <- boundsArr a -- compute the bounds
; worker (low,high) a -- call the worker
; return () -- clean up
}
worker (low,high) a | low > high = return () -- base case
worker (low,high) a = -- step case has 2 actions
do { item <- readArr a low -- 1) an action based upon low
; print item
; worker (low+1,high) a -- 2) make a recursive call
}
revIndexes :: (Int,Int) -> [(Int,Int)]
revIndexes (low,high) = zip countup countdown -- Part 1, index precalculation
where n = high - low + 1
half = n `div` 2
countup = [low..half]
countdown = [high, high -1 .. low]
rev5 :: Array a -> IO ()
rev5 a =
do { (low,high) <- boundsArr a
; let scan :: [(Int,Int)] -> IO () -- Part 2, defining scanning
scan [] = return () -- base case of scan
scan ((i,j):xs) = -- step with 2 actions
do { swap a (i,j); scan xs }
; scan (revIndexes (low,high)) -- calling the scan step
}
Back to the Daily Record.