Skip to main content
zio-cats

Interop

Step 10 of 15

Interop

ZIO and Cats Effect can interoperate using the zio-interop-cats library.

Adding the Dependency

// build.sbt
libraryDependencies += "dev.zio" %% "zio-interop-cats" % "23.1.0.3"

ZIO to Cats Effect

Cats Effect
import cats.effect.IO
import zio._
import zio.interop.catz._

// Use ZIO in CE context
val program: IO[Unit] = for {
  _ <- IO.println("CE start")
  // ZIO effect converted via interop
  result <- ZIO.succeed(42).toEffect[IO]
  _ <- IO.println(s"Got: $result")
} yield ()

ZIO effects can be converted to IO

ZIO
import zio._
import zio.interop.catz._

// ZIO can use Cats type classes
// The Task type works with CE libraries

val zioWithCats: Task[Int] =
  ZIO.attempt(42)

// Use in http4s, fs2, doobie, etc.

Task works with Cats ecosystem

Cats Type Classes for ZIO

Cats Effect
import cats.effect.IO
import cats.syntax.all._

// Native Cats syntax
val traversed: IO[List[Int]] =
  List(1, 2, 3).traverse(n => IO.pure(n * 2))

val parMapped: IO[Int] =
  (IO.pure(1), IO.pure(2)).parMapN(_ + _)

Native Cats syntax

ZIO
import zio._
import zio.interop.catz._
import cats.syntax.all._

// Cats syntax works with ZIO via interop
val traversed: Task[List[Int]] =
  List(1, 2, 3).traverse(n => ZIO.attempt(n * 2))

val parMapped: Task[Int] =
  (ZIO.attempt(1), ZIO.attempt(2)).parMapN(_ + _)

Cats syntax via zio-interop-cats

Using fs2 with ZIO

Cats Effect
import cats.effect.IO
import fs2.Stream

// Native fs2 usage
val stream: Stream[IO, Int] =
  Stream(1, 2, 3).evalMap(n => IO.pure(n * 2))

val result: IO[List[Int]] =
  stream.compile.toList

Native fs2 with IO

ZIO
import zio._
import zio.interop.catz._
import fs2.Stream

// fs2 works with ZIO Task
val stream: Stream[Task, Int] =
  Stream(1, 2, 3).evalMap(n => ZIO.attempt(n * 2))

val result: Task[List[Int]] =
  stream.compile.toList

fs2 with ZIO Task via interop

Using http4s with ZIO

Cats Effect
import cats.effect.IO
import org.http4s._
import org.http4s.dsl.io._

// Native http4s routes
val routes: HttpRoutes[IO] = HttpRoutes.of[IO] {
  case GET -> Root / "hello" =>
    Ok("Hello, World!")
}

Native http4s with IO

ZIO
import zio._
import zio.interop.catz._
import org.http4s._
import org.http4s.dsl.Http4sDsl

// http4s with ZIO Task
object MyDsl extends Http4sDsl[Task]
import MyDsl._

val routes: HttpRoutes[Task] = HttpRoutes.of[Task] {
  case GET -> Root / "hello" =>
    Ok("Hello, World!")
}

http4s with ZIO via interop

TIP:

The zio-interop-cats library provides instances of Cats type classes (Monad, Sync, Async, etc.) for ZIO's Task type, enabling use of the entire Cats ecosystem.

Cats Data Types

Cats Effect
import cats.effect.IO
import cats.data._

// Kleisli with IO
val kleisli: Kleisli[IO, String, Int] =
  Kleisli(s => IO.pure(s.length))

// EitherT with IO
val eitherT: EitherT[IO, String, Int] =
  EitherT.rightT[IO, String](42)

Cats data types with IO

ZIO
import zio._
import zio.interop.catz._
import cats.data._

// Kleisli with Task
val kleisli: Kleisli[Task, String, Int] =
  Kleisli(s => ZIO.attempt(s.length))

// EitherT with Task
val eitherT: EitherT[Task, String, Int] =
  EitherT.rightT[Task, String](42)

Cats data types with Task via interop

Resource Interop

Cats Effect
import cats.effect._

// Native Resource
val resource: Resource[IO, String] =
  Resource.make(
    IO.println("acquire") *> IO.pure("resource")
  )(_ => IO.println("release"))

val used: IO[Unit] =
  resource.use(r => IO.println(s"Using $r"))

Native Resource usage

ZIO
import zio._
import zio.interop.catz._
import cats.effect.Resource

// Use CE Resource with ZIO
val resource: Resource[Task, String] =
  Resource.make(
    ZIO.attempt(println("acquire")).as("resource")
  )(_ => ZIO.attempt(println("release")))

val used: Task[Unit] =
  resource.use(r => ZIO.attempt(println(s"Using $r")))

CE Resource with ZIO Task

When to Use Interop

Use Interop When:

  • Integrating with http4s, fs2, doobie, or other Cats libraries
  • Gradually migrating between effect systems
  • Working in a mixed codebase

Consider Native Alternatives:

  • ZIO HTTP instead of http4s
  • ZStream instead of fs2
  • ZIO JDBC instead of doobie

Congratulations!

You've completed the ZIO for Cats Effect Developers tutorial. You now understand:

  • Type signatures: IO[A] vs ZIO[R, E, A]
  • Effect creation and error handling
  • Resource management patterns
  • Fiber-based concurrency
  • Streaming with fs2 and ZStream
  • Application structure
  • Interoperability options

Further Learning

View Glossary →