Search code examples
scalafunctional-programmingeffectsside-effectszio

getStrLn in ZIO working with flatMap but not inside for comprehension


val askNameFlatMap: ZIO[Console, IOException, Unit] = putStrLn("What is your Name? ") *>
    getStrLn.flatMap(name => putStrLn(s"Hello $name"))

val askNameFor: ZIO[Console, IOException, Unit] = {
    val getName: ZIO[Console, IOException, String] = getStrLn
    for {
      _ <- putStrLn("What is your Name? ")
      name: String <- getName
      _ <- putStrLn(s"Hello $name")
    } yield ()
  }

The version using flatMap is successfully working but when I try to run the for comprehension version then I am getting this error

Pattern guards are only supported when the error type is a supertype of NoSuchElementException. However, your effect has java.io.IOException for the error type. name: String <- getName


Solution

  • You need to remove type ascription from your name argument. Type ascription has special meaning in for comprehensions. By saying

      for
        name: String <- getStrLn
    

    it translates to is something like getStrLn.withFilter(_.isInstanceOf[String])

    withFilter is provided by ZIO implicit but only if Error channel allows to signal about missing elements. Basically your E should be supertype of NoSuchElementException, i.e. Exception or Throwable. You have IOException and that's why it's not resolving properly.