I'll just leave this here.. ``` scala /** Laws? */ trait SumElim[F[_, _], G[_], A] { def elim[B, C](f: F[A, B])(left: A => C, right: B => C): G[C] } object SumElim { implicit def either[A]: SumElim[Either, Id, A] = new SumElim[Either, Id, A] { def elim[B, C](f: Either[A, B])(left: A => C, right: B => C): C = f.fold(left, right) } implicit def disjunction[A]: SumElim[Disjunction, Id, A] = new SumElim[Disjunction, Id, A] { def elim[B, C](f: Disjunction[A, B])(left: A => C, right: B => C): C = f.fold(left, right) } implicit def disjunctionT[G[_] : Functor, A]: SumElim[DisjunctionT[G, ?, ?], G, A] = new SumElim[DisjunctionT[G, ?, ?], G, A] { def elim[B, C](f: DisjunctionT[G, A, B])(left: A => C, right: B => C): G[C] = f.fold(left, right) } implicit val future: SumElim[({type l[e, a] = Future[a]})#l, Future, Throwable] = new SumElim[({type l[e, a] = Future[a]})#l, Future, Throwable] { def elim[B, C](f: Future[B])(left: Throwable => C, right: B => C): Future[C] = f.map(right).recover(left) } } ```
Activity