You can make this (at least arguably) a lot prettier by skipping the for
notation and using the combinators *>
and >>=
to pipe everything together:
import scalaz._, Scalaz._, effect._, IO._
val prompt = putStrLn("Please enter a non-empty line:")
def report(line: String) = putStrLn("You entered a non-empty line: " + line)
def nonEmptyLine: IO[String] = prompt *> readLn >>= (
(line: String) => if (line.isEmpty) nonEmptyLine else line.point[IO]
)
And then:
scala> (nonEmptyLine >>= report).unsafePerformIO
Please enter a non-empty line:
You entered a non-empty line: This is a test.
In general, though, I'm not sure you should expect code written using scalaz.effect
to be more concise or easier to read than a straightforward imperative solution.