/** Executes the handler if an exception is raised. */ def except(handler: Throwable => IO[A]): IO[A] = io(rw => try { Free.pure(this(rw).run) } catch { case e: Throwable => handler(e)(rw) }) /** * Executes the handler for exceptions that are raised and match the given predicate. * Other exceptions are rethrown. */ def catchSome[B](p: Throwable => Option[B], handler: B => IO[A]): IO[A] = except(e => p(e) match { case Some(z) => handler(z) case None => throw e }) /** * Returns a disjunction result which is right if no exception was raised, or left if an * exception was raised. */ def catchLeft: IO[Throwable \/ A] = map(\/.right[Throwable, A]) except (t => IO(-\/(t))) /**Like "catchLeft" but takes a predicate to select which exceptions are caught. */ def catchSomeLeft[B](p: Throwable => Option[B]): IO[B \/ A] = catchLeft map (_.leftMap(e => p(e).getOrElse(throw e))) /**Like "finally", but only performs the final action if there was an exception. */ def onException[B](action: IO[B]): IO[A] = this except (e => for { _ <- action a <- (throw e): IO[A] } yield a)
1 package demo.app 2
3 import scalaz._ 4 import Scalaz._ 5 import effect._ 6 import IO._ 7 import Free._ 8 import scala.language.higherKinds 9 import scala.language.implicitConversions 10
11 object IOMonadPrg { 12 def div(dvdn: Int, dvsor: Int): IO[Int] =
13 IO(dvdn / dvsor) 14 val ioprg: IO[Int] = for { 15 _ <- putLn("enter dividend:") 16 dvdn <- readLn 17 _ <- putLn("enter divisor:") 18 dvsor <- readLn 19 quot <- div(dvdn.toInt, dvsor.toInt) 20 _ <- putLn(s"the result:$quot") 21 } yield quot 22 //implicit def ioToOptionT[A](io: IO[A]): OptionT[IO,A] = io.liftM[OptionT]
23 val optionIOprg: OptionT[IO,Int] = for { 24 _ <- putLn("enter dividend:").liftM[OptionT] 25 dvdn <- readLn.liftM[OptionT] 26 _ <- putLn("enter divisor:").liftM[OptionT] 27 dvsor <- readLn.liftM[OptionT] 28 a <- if (dvsor.toInt == 0 ) OptionT(IO(None: Option[String])) else IO(0).liftM[OptionT] 29 quot <- div(dvdn.toInt, dvsor.toInt).liftM[OptionT] 30 _ <- putLn(s"the result:$quot").liftM[OptionT] 31 } yield quot 32 type WriterTIO[F[_],A] = WriterT[F,List[String],A] 33 val writerIOprg: WriterT[IO,List[String],Int] = for { 34 _ <- putLn("enter dividend:").liftM[WriterTIO] 35 dvdn <- readLn.liftM[WriterTIO] 36 _ <- WriterT.writerT((List(s"received dividend $dvdn;"),dvdn).point[IO]) 37 _ <- putLn("enter divisor:").liftM[WriterTIO] 38 dvsor <- readLn.liftM[Wr