Search code examples
scalascala-catscats-effect

How to create cats IO monad from cats State


I am working with cats and I want to transform my val x: State[A, B] to StateT[IO, A, B]. Note: IO is from cats-effects.
How to do this elegantly?


Solution

  • Try mapK in combination with cats.arrow.FunctionK.lift:

    x.mapK(lift(IO.eval))
    

    Full compilable code snippet:

    import cats.effect.IO
    import cats.data.{State, StateT}
    import cats.arrow.FunctionK.lift
    
    object InjectIdIO {
      def i[S, V](x: State[S, V]): StateT[IO, S, V] = x.mapK(lift(IO.eval))
    }
    

    This works because State[S, A] is actually StateT[Eval, S, A], and you want to replace the Eval by IO - this is what the mapK is usually for.


    Another alternative with kind-projector:

    x.mapK(Lambda[Eval ~> IO](IO.eval(_)))