Carrying out some kind of home project, I came across an interesting effect, which now seems obvious to me, but still I see no way to get away from it. This is the point (I am using ScalaZ, but in haskell there will probably be the same result):
def askAndReadResponse(question: String): IO[String] = {
putStrLn(question) >> readLn
}
def core: IO[String] = {
val answer: IO[String] = askAndReadResponse("enter something")
val cond: IO[Boolean] = answer map {_.length > 2}
IO.ioMonad.ifM(cond, answer, core)
}
When I try to get input from core
, askAndReadResponse
evaluates twice - once to evaluate the condition, and then to ifM
(so I have a message and readLn
again, then necessary). What I need is only a verified value (for example, for printing later)
Is there any elegant way to do this, in particular, to pass on the I / O result without previous I / O, namely to avoid executing askAndReadResponse
twice?