Search code examples
scalascala-catscats-effect

How to attach effects to the F in Resource[F, A] without using A?


Given a Resource[F, A], what is the most idiomatic way to attach effects (e.g. metrics, logging errors) to F without using A (i.e. .use)?

I can easily do that with a F[A] but I depend on an API that specifically returns a Resource[F, A] to make sure that A will be released correctly.


Solution

  • If I understand the question correctly, I'd use Resource.liftF and <*. For example:

    import cats.effect.{ IO, Resource }
    import cats.syntax.apply._
    import scala.io.Source
    
    val src = Resource.fromAutoCloseable(IO(Source.fromFile("build.sbt")))
    val log = IO(println("opening file"))
    
    val loggedSrc = src <* Resource.liftF(log)
    

    And then:

    scala> val program = loggedSrc.use(s => IO(println(s.mkString)))
    program: cats.effect.IO[Unit] = IO$201584418
    
    scala> program.unsafeRunSync
    opening file
    scalaVersion := "2.12.8"
    
    scalacOptions += "-Ypartial-unification"
    
    libraryDependencies += "org.typelevel" %% "cats-effect" % "1.2.0"
    

    In general you'd have the same approach you'd use in F, but lifted into Resource[F, _] with Resource.liftF.