Skip to content

Commit

Permalink
Fix ScalaDoc, address comments
Browse files Browse the repository at this point in the history
- Remove variance workarounds since Either syntax is invariant
- Prefer pattern matching over fold for performance
- Fix ScalaDoc
- Replace ad-hoc casts with leftCast and rightCast
- Re-enable ScalaStyle after disables and disable ScalaStyle on Either.type enrichment
  • Loading branch information
adelbertc committed Aug 15, 2016
1 parent 8fc564e commit 4530d3a
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 81 deletions.
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/ApplicativeError.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ trait ApplicativeError[F[_], E] extends Applicative[F] {
/**
* Handle errors by turning them into [[scala.util.Either]] values.
*
* If there is no error, then an [[scala.util.Right]] value will be returned instead.
* If there is no error, then an `scala.util.Right` value will be returned instead.
*
* All non-fatal errors should be handled by this method.
*/
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/FlatMap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ import simulacrum.typeclass
flatMap(fa)(if (_) ifTrue else ifFalse)

/**
* Keeps calling `f` until a `[[Right]][B]` is returned.
* Keeps calling `f` until a `scala.util.Right[B]` is returned.
*
* Based on Phil Freeman's
* [[http://functorial.com/stack-safety-for-free/index.pdf Stack Safety for Free]].
Expand Down
28 changes: 14 additions & 14 deletions core/src/main/scala/cats/data/EitherT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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[BB >: B](default: => BB)(implicit F: Functor[F]): F[BB] = F.map(value)(_.getOrElse(default))
def getOrElse(default: => B)(implicit F: Functor[F]): F[B] = F.map(value)(_.getOrElse(default))

def getOrElseF[BB >: B](default: => F[BB])(implicit F: Monad[F]): F[BB] = {
def getOrElseF(default: => F[B])(implicit F: Monad[F]): F[B] = {
F.flatMap(value) {
case Left(_) => default
case Right(b) => F.pure(b)
}
}

def orElse[AA, BB >: B](default: => EitherT[F, AA, BB])(implicit F: Monad[F]): EitherT[F, AA, BB] = {
def orElse(default: => EitherT[F, A, B])(implicit F: Monad[F]): EitherT[F, A, B] = {
EitherT(F.flatMap(value) {
case Left(_) => default.value
case r @ Right(_) => F.pure(r.asInstanceOf[Either[AA, BB]])
case r @ Right(_) => F.pure(r)
})
}

Expand All @@ -46,21 +46,21 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) {
case other => F.pure(other)
})

def valueOr[BB >: B](f: A => BB)(implicit F: Functor[F]): F[BB] = fold(f, identity)
def valueOr(f: A => B)(implicit F: Functor[F]): F[B] = 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[AA >: A](onFailure: => AA)(f: B => Boolean)(implicit F: Functor[F]): EitherT[F, AA, B] = EitherT(F.map(value)(_.ensure(onFailure)(f)))
def ensure(onFailure: => A)(f: B => Boolean)(implicit F: Functor[F]): EitherT[F, A, B] = EitherT(F.map(value)(_.ensure(onFailure)(f)))

def toOption(implicit F: Functor[F]): OptionT[F, B] = OptionT(F.map(value)(_.toOption))

def to[G[_]](implicit F: Functor[F], G: Alternative[G]): F[G[B]] =
F.map(value)(_.to[G, B])
F.map(value)(_.to[G])

def collectRight(implicit F: MonadCombine[F]): F[B] =
F.flatMap(value)(_.to[F, B])
F.flatMap(value)(_.to[F])

def bimap[C, D](fa: A => C, fb: B => D)(implicit F: Functor[F]): EitherT[F, C, D] = EitherT(F.map(value)(_.bimap(fa, fb)))

Expand All @@ -70,19 +70,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[AA >: A, D](f: B => EitherT[F, AA, D])(implicit F: Monad[F]): EitherT[F, AA, D] =
def flatMap[D](f: B => EitherT[F, A, D])(implicit F: Monad[F]): EitherT[F, A, D] =
EitherT(F.flatMap(value) {
case l @ Left(_) => F.pure(l.asInstanceOf[Either[AA, D]])
case l @ Left(_) => F.pure((l: Either[A, B]).rightCast[D])
case Right(b) => f(b).value
})

def flatMapF[AA >: A, D](f: B => F[Either[AA, D]])(implicit F: Monad[F]): EitherT[F, AA, D] =
def flatMapF[D](f: B => F[Either[A, D]])(implicit F: Monad[F]): EitherT[F, A, 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[AA >: A, D](f: B => Either[AA, D])(implicit F: Functor[F]): EitherT[F, AA, D] =
def subflatMap[D](f: B => Either[A, D])(implicit F: Functor[F]): EitherT[F, A, D] =
transform(_.flatMap(f))

def map[D](f: B => D)(implicit F: Functor[F]): EitherT[F, A, D] = bimap(identity, f)
Expand Down Expand Up @@ -110,10 +110,10 @@ 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[AA >: A](implicit ev: B <:< AA, F: Functor[F]): F[AA] = F.map(value)(_.fold(identity, ev.apply))
def merge(implicit ev: B <:< A, F: Functor[F]): F[A] = F.map(value)(_.fold(identity, ev.apply))

/**
* Similar to [[Either.combine]] but mapped over an `F` context.
* Similar to `Either#combine` but mapped over an `F` context.
*
* Examples:
* {{{
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/Ior.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import scala.annotation.tailrec
*
* `A [[Ior]] B` is isomorphic to `Either[Either[A, B], (A, B)]`, but provides methods biased toward `B`
* values, regardless of whether the `B` values appear in a [[Ior.Right Right]] or a [[Ior.Both Both]].
* The isomorphic [[Either]] form can be accessed via the [[unwrap]] method.
* The isomorphic [[scala.util.Either]] form can be accessed via the [[unwrap]] method.
*/
sealed abstract class Ior[+A, +B] extends Product with Serializable {

Expand Down
1 change: 1 addition & 0 deletions core/src/main/scala/cats/instances/either.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ trait EitherInstances extends EitherInstances1 {
override def ensure[B](fab: Either[A, B])(error: => A)(predicate: B => Boolean): Either[A, B] =
fab.ensure(error)(predicate)
}
// scalastyle:on method.length

implicit def catsStdOrderForEither[A, B](implicit A: Order[A], B: Order[B]): Order[Either[A, B]] = new Order[Either[A, B]] {
def compare(x: Either[A, B], y: Either[A, B]): Int = x.fold(
Expand Down
Loading

0 comments on commit 4530d3a

Please sign in to comment.