diff --git a/core/src/main/scala/cats/data/WriterT.scala b/core/src/main/scala/cats/data/WriterT.scala index 69dbc5f0792..ca3816d3a8b 100644 --- a/core/src/main/scala/cats/data/WriterT.scala +++ b/core/src/main/scala/cats/data/WriterT.scala @@ -104,12 +104,20 @@ private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4 } } -private[data] sealed abstract class WriterTInstances4 { +private[data] sealed abstract class WriterTInstances4 extends WriterTInstances5 { implicit def writerTFunctor[F[_], L](implicit F: Functor[F]): Functor[WriterT[F, L, ?]] = new WriterTFunctor[F, L] { implicit val F0: Functor[F] = F } } +private[data] sealed abstract class WriterTInstances5 { + implicit def writerTMonadError[F[_], L, E](implicit F: MonadError[F, E], L: Monoid[L]): MonadError[WriterT[F, L, ?], E] = + new WriterTMonadError[F, L, E] { + implicit val F0: MonadError[F, E] = F + implicit val L0: Monoid[L] = L + } +} + private[data] sealed trait WriterTFunctor[F[_], L] extends Functor[WriterT[F, L, ?]] { implicit def F0: Functor[F] @@ -149,6 +157,15 @@ private[data] sealed trait WriterTMonad[F[_], L] extends WriterTApplicative[F, L fa.flatMap(f) } +private[data] sealed trait WriterTMonadError[F[_], L, E] extends MonadError[WriterT[F, L, ?], E] with WriterTMonad[F, L] { + override implicit def F0: MonadError[F, E] + + def raiseError[A](e: E): WriterT[F, L, A] = WriterT(F0.raiseError[(L, A)](e)) + + def handleErrorWith[A](fa: WriterT[F, L, A])(f: E => WriterT[F, L, A]): WriterT[F, L, A] = + WriterT(F0.handleErrorWith(fa.run)(e => f(e).run)) +} + trait WriterTFunctions { def putT[F[_], L, V](vf: F[V])(l: L)(implicit functorF: Functor[F]): WriterT[F, L, V] = WriterT(functorF.map(vf)(v => (l, v)))