I have been trying to figure out how to do recursion within an IO monad. I am familiar with doing recursion with pure functions, but have not been able to transfer this knowledge to IO monads.
Recursion with pure functions
I'm comfortable with doing recursion with pure functions such as the foo
function below.
foo (x:y:ys) = foo' x y ++ foo ys
A function with IO [String] output
I made a function like goo
below that does what I need and has an IO output.
goo :: String -> String -> IO [String]
goo xs ys = goo' xs ys
Trying to get recursion inside an IO monad
When I try to do recursion within an IO monad (e.g., a "main" function) I cannot. I've looked up liftM
, replicateM
, and the undo-the-IO <-
operator or function. I want an IO monad like hoo
or hoo'
(apologies for the gibberish that follows).
hoo :: [String] -> IO [String]
hoo (xs:ys:yss) = do
let rs = goo xs ys ++ hoo yss
return rs
or
hoo' :: [String] -> IO [String]
hoo' (xs:ys:yss) = do
rs <- goo xs ys
let gs = rs ++ hoo' yss
return gs
(BTW, in case you are wondering what my project is, I'm writing a Genetic Algorithm program from scratch for a course. My goo
function takes two parents and breeds two offspring, which are returned as an IO because goo
uses a random number generator. What I need to do is to to use a recursive hoo
function to use goo
to breed 20 offspring from a list of 20 parents. The idea I have is to take the first two parents in the list, breed two offspring, take the next two parents on the list, breed another pair of offspring, so on and so forth.)