scalaadvanced
Cats Effect IO Monad Basics
Use Cats Effect IO for pure functional effects: sequencing, error handling, resource management.
scalaPress ⌘/Ctrl + Shift + C to copy
import cats.effect.{IO, IOApp, Resource, ExitCode}
import cats.syntax.all.*
import scala.concurrent.duration.*
object MyApp extends IOApp.Simple:
// Pure IO values
val hello: IO[Unit] = IO.println("Hello, Cats Effect!")
val answer: IO[Int] = IO.pure(42)
val delayed: IO[String] = IO.sleep(100.millis) *> IO.pure("Done")
// Sequencing with flatMap
val program: IO[Unit] = for
_ <- IO.println("Starting...")
name <- IO.pure("Alice")
_ <- IO.println(s"Hello, $name!")
num <- IO.delay(scala.util.Random.nextInt(100))
_ <- IO.println(s"Random: $num")
yield ()
// Error handling
val risky: IO[Int] = IO.raiseError(RuntimeException("Boom!"))
val safe: IO[Int] = risky.handleErrorWith { e =>
IO.println(s"Caught: ${e.getMessage}") *> IO.pure(0)
}
val attempted: IO[Either[Throwable, Int]] = risky.attempt
// Resource management
def openFile(name: String): Resource[IO, String] =
Resource.make(
IO.println(s"Opening $name") *> IO.pure(s"Handle($name)")
)(
handle => IO.println(s"Closing $handle")
)
val fileProgram: IO[Unit] =
openFile("data.txt").use { handle =>
IO.println(s"Reading from $handle")
}
// Parallel execution
val task1: IO[String] = IO.sleep(100.millis) *> IO.pure("Result A")
val task2: IO[String] = IO.sleep(100.millis) *> IO.pure("Result B")
val parallel: IO[(String, String)] = (task1, task2).parTupled
// Retry
def retry[A](io: IO[A], attempts: Int, delay: FiniteDuration): IO[A] =
io.handleErrorWith { e =>
if attempts > 1 then
IO.println(s"Retrying (${attempts - 1} left)...") *>
IO.sleep(delay) *>
retry(io, attempts - 1, delay)
else IO.raiseError(e)
}
// Traverse
val ids: List[Int] = (1 to 5).toList
val fetched: IO[List[String]] = ids.traverse { id =>
IO.sleep(50.millis) *> IO.pure(s"Data-$id")
}
val parFetched: IO[List[String]] = ids.parTraverse { id =>
IO.sleep(50.millis) *> IO.pure(s"Data-$id")
}
def run: IO[Unit] = for
_ <- program
_ <- safe
r <- attempted
_ <- IO.println(s"Attempted: $r")
_ <- fileProgram
p <- parallel
_ <- IO.println(s"Parallel: $p")
d <- fetched
_ <- IO.println(s"Sequential: $d")
d <- parFetched
_ <- IO.println(s"Parallel fetch: $d")
yield ()Use Cases
- Pure functional effect management
- Safe resource acquisition and release
- Parallel and sequential effect composition
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
scalabeginner
Collections Map Filter Fold Operations
Master Scala collections: map, flatMap, filter, fold, groupBy, partition, and zip operations.
Best for: Data transformation and aggregation
#scala#collections
scalaintermediate
For-Comprehensions and Monadic Composition
Use for-comprehensions with Option, Either, Future, and custom monads for elegant composition.
Best for: Chaining optional computations
#scala#for-comprehension
scalaadvanced
Type Class Pattern Implementation
Implement the type class pattern in Scala 3: define, provide instances, and use with extension methods.
Best for: Ad-hoc polymorphism without inheritance
#scala#type-class
scalaadvanced
ZIO Effect System Basics
Build programs with ZIO: effects, error handling, layers, and concurrent operations.
Best for: Typed error handling with ZIO
#scala#zio