diff --git a/core/src/main/scala/cats/data/EitherT.scala b/core/src/main/scala/cats/data/EitherT.scala index d558ff8752..ba59b02163 100644 --- a/core/src/main/scala/cats/data/EitherT.scala +++ b/core/src/main/scala/cats/data/EitherT.scala @@ -21,19 +21,19 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { def swap(implicit F: Functor[F]): EitherT[F, B, A] = EitherT(F.map(value)(_.swap)) - def getOrElse(default: => B)(implicit F: Functor[F]): F[B] = F.map(value)(_.getOrElse(default)) + def getOrElse[BB >: B](default: => BB)(implicit F: Functor[F]): F[BB] = F.map(value)(_.getOrElse(default)) - def getOrElseF(default: => F[B])(implicit F: Monad[F]): F[B] = { + def getOrElseF[BB >: B](default: => F[BB])(implicit F: Monad[F]): F[BB] = { F.flatMap(value) { case Left(_) => default case Right(b) => F.pure(b) } } - def orElse(default: => EitherT[F, A, B])(implicit F: Monad[F]): EitherT[F, A, B] = { + def orElse[AA, BB >: B](default: => EitherT[F, AA, BB])(implicit F: Monad[F]): EitherT[F, AA, BB] = { EitherT(F.flatMap(value) { case Left(_) => default.value - case r @ Right(_) => F.pure(r) + case r @ Right(_) => F.pure(r.leftCast) }) } @@ -46,13 +46,14 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { case other => F.pure(other) }) - def valueOr(f: A => B)(implicit F: Functor[F]): F[B] = fold(f, identity) + def valueOr[BB >: B](f: A => BB)(implicit F: Functor[F]): F[BB] = fold(f, identity) def forall(f: B => Boolean)(implicit F: Functor[F]): F[Boolean] = F.map(value)(_.forall(f)) def exists(f: B => Boolean)(implicit F: Functor[F]): F[Boolean] = F.map(value)(_.exists(f)) - def ensure(onFailure: => A)(f: B => Boolean)(implicit F: Functor[F]): EitherT[F, A, B] = EitherT(F.map(value)(_.ensure(onFailure)(f))) + def ensure[AA >: A](onFailure: => AA)(f: B => Boolean)(implicit F: Functor[F]): EitherT[F, AA, B] = + EitherT(F.map(value)(_.ensure(onFailure)(f))) def toOption(implicit F: Functor[F]): OptionT[F, B] = OptionT(F.map(value)(_.toOption)) @@ -70,19 +71,19 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { def applyAlt[D](ff: EitherT[F, A, B => D])(implicit F: Apply[F]): EitherT[F, A, D] = EitherT[F, A, D](F.map2(this.value, ff.value)((xb, xbd) => Apply[Either[A, ?]].ap(xbd)(xb))) - def flatMap[D](f: B => EitherT[F, A, D])(implicit F: Monad[F]): EitherT[F, A, D] = + def flatMap[AA >: A, D](f: B => EitherT[F, AA, D])(implicit F: Monad[F]): EitherT[F, AA, D] = EitherT(F.flatMap(value) { case l @ Left(_) => F.pure(l.rightCast) case Right(b) => f(b).value }) - def flatMapF[D](f: B => F[Either[A, D]])(implicit F: Monad[F]): EitherT[F, A, D] = + def flatMapF[AA >: A, D](f: B => F[Either[AA, D]])(implicit F: Monad[F]): EitherT[F, AA, D] = flatMap(f andThen EitherT.apply) def transform[C, D](f: Either[A, B] => Either[C, D])(implicit F: Functor[F]): EitherT[F, C, D] = EitherT(F.map(value)(f)) - def subflatMap[D](f: B => Either[A, D])(implicit F: Functor[F]): EitherT[F, A, D] = + def subflatMap[AA >: A, D](f: B => Either[AA, D])(implicit F: Functor[F]): EitherT[F, AA, D] = transform(_.flatMap(f)) def map[D](f: B => D)(implicit F: Functor[F]): EitherT[F, A, D] = bimap(identity, f) @@ -110,7 +111,7 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { def foldRight[C](lc: Eval[C])(f: (B, Eval[C]) => Eval[C])(implicit F: Foldable[F]): Eval[C] = F.foldRight(value, lc)((axb, lc) => axb.foldRight(lc)(f)) - def merge(implicit ev: B <:< A, F: Functor[F]): F[A] = F.map(value)(_.fold(identity, ev.apply)) + def merge[AA >: A](implicit ev: B <:< AA, F: Functor[F]): F[AA] = F.map(value)(_.fold(identity, ev.apply)) /** * Similar to `Either#combine` but mapped over an `F` context. diff --git a/core/src/main/scala/cats/syntax/either.scala b/core/src/main/scala/cats/syntax/either.scala index 4845b24069..906ba49f2b 100644 --- a/core/src/main/scala/cats/syntax/either.scala +++ b/core/src/main/scala/cats/syntax/either.scala @@ -23,27 +23,27 @@ final class EitherOps[A, B](val eab: Either[A, B]) extends AnyVal { case Right(b) => f(b) } - def getOrElse(default: => B): B = eab match { + def getOrElse[BB >: B](default: => BB): BB = eab match { case Left(_) => default case Right(b) => b } - def orElse[C](fallback: => Either[C, B]): Either[C, B] = eab match { + def orElse[C, BB >: B](fallback: => Either[C, BB]): Either[C, BB] = eab match { case Left(_) => fallback case r @ Right(_) => EitherUtil.leftCast(r) } - def recover(pf: PartialFunction[A, B]): Either[A, B] = eab match { + def recover[BB >: B](pf: PartialFunction[A, BB]): Either[A, BB] = eab match { case Left(a) if pf.isDefinedAt(a) => Right(pf(a)) case _ => eab } - def recoverWith(pf: PartialFunction[A, Either[A, B]]): Either[A, B] = eab match { + def recoverWith[AA >: A, BB >: B](pf: PartialFunction[A, Either[AA, BB]]): Either[AA, BB] = eab match { case Left(a) if pf.isDefinedAt(a) => pf(a) case _ => eab } - def valueOr(f: A => B): B = eab match { + def valueOr[BB >: B](f: A => BB): BB = eab match { case Left(a) => f(a) case Right(b) => b } @@ -58,7 +58,7 @@ final class EitherOps[A, B](val eab: Either[A, B]) extends AnyVal { case Right(b) => f(b) } - def ensure(onFailure: => A)(f: B => Boolean): Either[A, B] = eab match { + def ensure[AA >: A](onFailure: => AA)(f: B => Boolean): Either[AA, B] = eab match { case Left(_) => eab case Right(b) => if (f(b)) eab else Left(onFailure) } @@ -90,7 +90,7 @@ final class EitherOps[A, B](val eab: Either[A, B]) extends AnyVal { /** Returns a [[cats.data.ValidatedNel]] representation of this disjunction with the `Left` value * as a single element on the `Invalid` side of the [[cats.data.NonEmptyList]]. */ - def toValidatedNel: ValidatedNel[A, B] = eab match { + def toValidatedNel[AA >: A]: ValidatedNel[AA, B] = eab match { case Left(a) => Validated.invalidNel(a) case Right(b) => Validated.valid(b) } @@ -113,7 +113,7 @@ final class EitherOps[A, B](val eab: Either[A, B]) extends AnyVal { case Right(b) => Right(f(b)) } - def map2Eval[C, Z](fc: Eval[Either[A, C]])(f: (B, C) => Z): Eval[Either[A, Z]] = + def map2Eval[AA >: A, C, Z](fc: Eval[Either[AA, C]])(f: (B, C) => Z): Eval[Either[AA, Z]] = eab match { case l @ Left(_) => Now(EitherUtil.rightCast(l)) case Right(b) => fc.map(either => new EitherOps(either).map(f(b, _))) @@ -124,51 +124,51 @@ final class EitherOps[A, B](val eab: Either[A, B]) extends AnyVal { case r @ Right(_) => EitherUtil.leftCast(r) } - def flatMap[D](f: B => Either[A, D]): Either[A, D] = eab match { + def flatMap[AA >: A, D](f: B => Either[AA, D]): Either[AA, D] = eab match { case l @ Left(_) => EitherUtil.rightCast(l) case Right(b) => f(b) } - def compare(that: Either[A, B])(implicit A: Order[A], B: Order[B]): Int = eab match { + def compare[AA >: A, BB >: B](that: Either[AA, BB])(implicit AA: Order[AA], BB: Order[BB]): Int = eab match { case Left(a1) => that match { - case Left(a2) => A.compare(a1, a2) + case Left(a2) => AA.compare(a1, a2) case Right(_) => -1 } case Right(b1) => that match { case Left(_) => 1 - case Right(b2) => B.compare(b1, b2) + case Right(b2) => BB.compare(b1, b2) } } - def partialCompare(that: Either[A, B])(implicit A: PartialOrder[A], B: PartialOrder[B]): Double = eab match { + def partialCompare[AA >: A, BB >: B](that: Either[AA, BB])(implicit AA: PartialOrder[AA], BB: PartialOrder[BB]): Double = eab match { case Left(a1) => that match { - case Left(a2) => A.partialCompare(a1, a2) + case Left(a2) => AA.partialCompare(a1, a2) case Right(_) => -1 } case Right(b1) => that match { case Left(_) => 1 - case Right(b2) => B.partialCompare(b1, b2) + case Right(b2) => BB.partialCompare(b1, b2) } } - def ===(that: Either[A, B])(implicit A: Eq[A], B: Eq[B]): Boolean = eab match { + def ===[AA >: A, BB >: B](that: Either[AA, BB])(implicit AA: Eq[AA], BB: Eq[BB]): Boolean = eab match { case Left(a1) => that match { - case Left(a2) => A.eqv(a1, a2) + case Left(a2) => AA.eqv(a1, a2) case Right(_) => false } case Right(b1) => that match { case Left(_) => false - case Right(b2) => B.eqv(b1, b2) + case Right(b2) => BB.eqv(b1, b2) } } - def traverse[F[_], D](f: B => F[D])(implicit F: Applicative[F]): F[Either[A, D]] = eab match { + def traverse[F[_], AA >: A, D](f: B => F[D])(implicit F: Applicative[F]): F[Either[AA, D]] = eab match { case l @ Left(_) => F.pure(EitherUtil.rightCast(l)) case Right(b) => F.map(f(b))(Right(_)) } @@ -215,20 +215,20 @@ final class EitherOps[A, B](val eab: Either[A, B]) extends AnyVal { * res3: Either[String, Int] = Right(7) * }}} */ - final def combine(that: Either[A, B])(implicit B: Semigroup[B]): Either[A, B] = eab match { + final def combine[AA >: A, BB >: B](that: Either[AA, BB])(implicit BB: Semigroup[BB]): Either[AA, BB] = eab match { case left @ Left(_) => left case Right(b1) => that match { case left @ Left(_) => left - case Right(b2) => Right(B.combine(b1, b2)) + case Right(b2) => Right(BB.combine(b1, b2)) } } - def show(implicit A: Show[A], B: Show[B]): String = eab match { - case Left(a) => s"Left(${A.show(a)})" - case Right(b) => s"Right(${B.show(b)})" + def show[AA >: A, BB >: B](implicit AA: Show[AA], BB: Show[BB]): String = eab match { + case Left(a) => s"Left(${AA.show(a)})" + case Right(b) => s"Right(${BB.show(b)})" } - def ap[C](that: Either[A, B => C]): Either[A, C] = (new EitherOps(that)).flatMap(this.map) + def ap[AA >: A, BB >: B, C](that: Either[AA, BB => C]): Either[AA, C] = new EitherOps(that).flatMap(this.map) /** * Transform the `Either` into a [[cats.data.EitherT]] while lifting it into the specified Applicative.