AD
Size: a a a
AD
λ
P
λ
DM
Y
Y
YS
YS
YS
V
YS
type Service1Error = Forbidden :+: NotFound :+: CNil
type Service2Error = Forbidden :+: AlreadyDone :+: CNil
type DomainError = Service1Error :+: Service2Error :+: CNil
MonadError[F, Service1Error], второму, соотвественно
MonadError[F, Service2Error]
implicit def narrowMonadError[Error <: Coproduct]
(implicit basis: Basis[DomainError, Error]): MonadError[F, Error] = {
new MonadError[F, Error] {
import shapeless.Coproduct._
override def pure[A](x: A): F[A] = ME.pure(x)
override def raiseError[A](e: Error): F[A] = ME.raiseError(e.embed)
// TODO
override def handleErrorWith[A](fa: F[A])(f: Error => F[A]): F[A] = ???
override def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] = ME.flatMap(fa)(f)
override def tailRecM[A, B](a: A)(f: A => F[Either[A, B]]): F[B] = ME.tailRecM(a)(f)
}
}
Basis[DomainError, Error], чтобы скомпилилось приходится вручную делать flatten для общего типа ошибки:
type DomainErrorFlattended = Forbidden :+: AlreadyDone :+: NotFound :+: CNil
type DomainError = Service1Error :+: Service2Error :+: CNilсам выводился
Basis[DomainError, Error]
YS
KS
YS
Basis[DomainError, Error]
Basis[DomainErrorFlattended, Error]
Y
YS
Y
KS
Y