printLine(message: String): Unit = println(message) def main(args: Array[String]): Unit = val name = Console.readLine("Enter your name: ") Console.printLine(s"Hello $name") > run Enter your name: World Hello World
blocking , interruptible async etc. These give hints to cats-effect runtime about how to handle threads cats-effectのコンストラクタはスレッドの扱いについてランタイ ムにヒントを与える役割がある
typelevel/cats-effect/.../IORuntime.scala final class IORuntime private[unsafe] ( val compute: ExecutionContext, private[effect] val blocking: ExecutionContext, val scheduler: Scheduler, private[effect] val fiberMonitor: FiberMonitor, val shutdown: () => Unit, val config: IORuntimeConfig )
{ while ({ Thread.sleep(100); true }) {}; "a" } val b = Future { Thread.sleep(1000); println("b"); "b" } Future.firstCompletedOf(Seq(a, b)).foreach(println) val a = IO.interruptible { while ({ Thread.sleep(100); true }) {}; "a" } val b = IO.interruptible { Thread.sleep(1000); "b" } IO.race(a, b).map(_.merge).flatMap(IO.println) キャンセルができる
case class PrintLine(message: String) extends ConsoleA[Unit] def program: Free[ConsoleA, Unit] = for name <- Free.liftF(ReadLine("Enter your name: ")) message <- Free.liftF(PrintLine(s"Hello $name")) yield ()
~> IO): def apply[A](fa: ConsoleA[A]): IO[A] = fa match case ReadLine(prompt) => IO.print(prompt) >> IO.readLine case PrintLine(message) => IO.println(message) val run = program.foldMap(interpret)
"ResultSetRead" Type class given ResultSetRead[IO, String] = ResultSetRead(RS.get[String]("hello")) // Declare a query val q: Query[IO, String] = DB.query[String](sql"select 'Hello, World!' as hello") // Execute the query transactor.readOnly.useKleisli(q) >>= IO.println // => Hello, World!
_ <- DB.update( sql"insert into person (id, name, nickname, created_at) values ($id...") result <- DB.query[Option[Person]]( sql"select id, name, nickname, created_at from person where id = $id") yield result transactor.transaction.useKelisli(insertAndFind).unsafeRunSync() Kleisliの合成によってトランザクションを表現できる