As an exercise, I was creating a function that takes an argument n
, and asks the user for n
numbers to add up, printing the running sum as they do so, before yielding an IO Int
to the caller. This was an exercise in some tutorial, but I can’t find it anymore.
Anyway, I didn’t want to use a primitive recursive helper function, but this was the only solution I could come up with that didn’t use one.
runningSum :: Int -> IO Int
runningSum n = foldM helper 0 [1..n]
where
helper sum _ = do
result <- read <$> getLine
let sum' = sum + result
putStr "Running sum: "; print sum'
return sum'
But the only reason to write [1..n]
is to apply the function helper
n
times; the actual list elements are discarded. It could just as well be defined this way:
runningSum n = foldM helper 0 (replicate n undefined)
And it would be “fine” because no element of the list is ever accessed.
I know Haskell is lazy, but still, isn’t it inefficient to create a list solely to repeat an action n times? If so, is there a better way of achieving that? Is there some standard library function to apply a function n times, and a monadic version? I imagine the latter would have the type signature Monad m => (a -> m a) -> Int -> a -> m a
; something like foldM
without the list. I could write this function, but I wanted to know if there was a standard, better way to repeat something N times without generating an intermediate list; is there? (iterate
wouldn’t be a good suggestion, because it does generate an intermediate list).