Skip to content

Commit

Permalink
Merge branch 'add-unordered-classes' of https://github.com/LukaJCB/cats
Browse files Browse the repository at this point in the history
… into add-unordered-classes
  • Loading branch information
Luka Jacobowitz committed Nov 24, 2017
2 parents 89cab23 + 11b397c commit d0ac64e
Show file tree
Hide file tree
Showing 38 changed files with 527 additions and 156 deletions.
5 changes: 4 additions & 1 deletion alleycats-core/src/main/scala/alleycats/std/iterable.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package alleycats
package std

import cats.{Eval, Foldable}
import cats.{Eval, Foldable, Monoid}
import export._

@reexports(IterableInstances)
Expand All @@ -16,6 +16,9 @@ object IterableInstances {

override def foldRight[A, B](fa: Iterable[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
Foldable.iterateRight(fa, lb)(f)

override def foldMap[A, B](fa: Iterable[A])(f: A => B)(implicit B: Monoid[B]): B =
B.combineAll(fa.iterator.map(f))
}

}
Expand Down
7 changes: 7 additions & 0 deletions alleycats-core/src/main/scala/alleycats/std/map.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,12 @@ trait MapInstances {
A.combineAll(fa.values)

override def toList[A](fa: Map[K, A]): List[A] = fa.values.toList

override def collectFirst[A, B](fa: Map[K, A])(pf: PartialFunction[A, B]): Option[B] = fa.collectFirst(new PartialFunction[(K, A), B] {
override def isDefinedAt(x: (K, A)) = pf.isDefinedAt(x._2)
override def apply(v1: (K, A)) = pf(v1._2)
})

override def collectFirstSome[A, B](fa: Map[K, A])(f: A => Option[B]): Option[B] = collectFirst(fa)(Function.unlift(f))
}
}
9 changes: 9 additions & 0 deletions alleycats-core/src/main/scala/alleycats/std/set.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ object SetInstances {
def foldRight[A, B](fa: Set[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
Foldable.iterateRight(fa, lb)(f)

override def foldMap[A, B](fa: Set[A])(f: A => B)(implicit B: Monoid[B]): B =
B.combineAll(fa.iterator.map(f))

def traverse[G[_]: Applicative, A, B](sa: Set[A])(f: A => G[B]): G[Set[B]] = {
val G = Applicative[G]
sa.foldLeft(G.pure(Set.empty[B])) { (buf, a) =>
Expand Down Expand Up @@ -106,6 +109,12 @@ object SetInstances {
fa.reduceLeftOption(f)

override def find[A](fa: Set[A])(f: A => Boolean): Option[A] = fa.find(f)

override def collectFirst[A, B](fa: Set[A])(pf: PartialFunction[A, B]): Option[B] =
fa.collectFirst(pf)

override def collectFirstSome[A, B](fa: Set[A])(f: A => Option[B]): Option[B] =
fa.collectFirst(Function.unlift(f))
}
}

Expand Down
117 changes: 17 additions & 100 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -209,115 +209,16 @@ def mimaSettings(moduleName: String) = Seq(
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable#Ops.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse#Ops.unorderedTraverse"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse#Ops.unorderedSequence"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedTraverse"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedSequence"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[UpdateForwarderBodyProblem]("cats.Foldable.size"),
exclude[ReversedMissingMethodProblem]("cats.Foldable.unorderedFold"),
exclude[ReversedMissingMethodProblem]("cats.Foldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable#Ops.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable#Ops.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable#Ops.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedTraverse"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedSequence"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedTraverse"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedSequence"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable#Ops.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable#Ops.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable#Ops.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable#Ops.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable#Ops.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable#Ops.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse#Ops.unorderedTraverse"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse#Ops.unorderedSequence"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[DirectMissingMethodProblem]("cats.Foldable#Ops.size"),
exclude[DirectMissingMethodProblem]("cats.Foldable#Ops.forall"),
exclude[DirectMissingMethodProblem]("cats.Foldable#Ops.isEmpty"),
exclude[DirectMissingMethodProblem]("cats.Foldable#Ops.nonEmpty"),
exclude[DirectMissingMethodProblem]("cats.Foldable#Ops.exists"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable#ToUnorderedFoldableOps.toUnorderedFoldableOps"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable#ToUnorderedFoldableOps.toUnorderedFoldableOps"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedTraverse"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedSequence"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedTraverse"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedSequence"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedTraverse"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedSequence"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedTraverse"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedSequence"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedTraverse"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedSequence"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedTraverse"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedSequence"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedTraverse"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedSequence"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedTraverse"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedTraverse.unorderedSequence"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.toSet"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFold"),
exclude[InheritedNewAbstractMethodProblem]("cats.UnorderedFoldable.unorderedFoldMap"),
exclude[IncompatibleResultTypeProblem]("cats.instances.SetInstances.catsStdInstancesForSet"),
exclude[ReversedMissingMethodProblem]("cats.instances.SetInstances.cats$instances$SetInstances$_setter_$catsStdInstancesForSet_="),
exclude[ReversedMissingMethodProblem]("cats.instances.SetInstances.catsStdInstancesForSet"),
Expand All @@ -327,7 +228,23 @@ def mimaSettings(moduleName: String) = Seq(
exclude[IncompatibleResultTypeProblem]("cats.instances.package#all.catsStdInstancesForSet"),
exclude[IncompatibleResultTypeProblem]("cats.instances.package#map.catsStdInstancesForMap"),
exclude[IncompatibleResultTypeProblem]("cats.instances.package#set.catsStdInstancesForSet"),
exclude[IncompatibleResultTypeProblem]("cats.instances.MapInstances.catsStdInstancesForMap")
exclude[IncompatibleResultTypeProblem]("cats.instances.MapInstances.catsStdInstancesForMap"),
exclude[DirectMissingMethodProblem]("cats.data.EitherTInstances2.catsDataMonadErrorForEitherT"),
exclude[MissingTypesProblem]("cats.data.OneAndLowPriority3"),
exclude[MissingTypesProblem]("cats.data.OneAndLowPriority2"),
exclude[MissingTypesProblem]("cats.data.OneAndLowPriority1"),
exclude[DirectMissingMethodProblem]("cats.data.OneAndLowPriority3.catsDataNonEmptyTraverseForOneAnd"),
exclude[DirectMissingMethodProblem]("cats.data.OneAndLowPriority2.catsDataTraverseForOneAnd"),
exclude[ReversedMissingMethodProblem]("cats.instances.ParallelInstances.catsStdNonEmptyParallelForZipVector"),
exclude[ReversedMissingMethodProblem]("cats.instances.ParallelInstances.catsStdParallelForZipStream"),
exclude[ReversedMissingMethodProblem]("cats.instances.ParallelInstances.catsStdNonEmptyParallelForZipList"),
exclude[ReversedMissingMethodProblem]("cats.instances.ParallelInstances.catsStdParallelForFailFastFuture"),
exclude[DirectMissingMethodProblem]("cats.data.EitherTInstances2.catsDataMonadErrorForEitherT"),
exclude[DirectMissingMethodProblem]("cats.data.EitherTInstances2.catsDataMonadErrorForEitherT"),
exclude[ReversedMissingMethodProblem]("cats.Foldable.collectFirstSome"),
exclude[ReversedMissingMethodProblem]("cats.Foldable.collectFirst"),
exclude[ReversedMissingMethodProblem]("cats.Foldable#Ops.collectFirstSome"),
exclude[ReversedMissingMethodProblem]("cats.Foldable#Ops.collectFirst")
)
}
)
Expand Down
32 changes: 32 additions & 0 deletions core/src/main/scala/cats/Foldable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import scala.collection.mutable
import cats.instances.either._
import cats.kernel.CommutativeMonoid
import simulacrum.typeclass
import Foldable.sentinel

/**
* Data structures that can be folded to a summary value.
Expand Down Expand Up @@ -206,6 +207,35 @@ import simulacrum.typeclass
case Right(_) => None
}

def collectFirst[A, B](fa: F[A])(pf: PartialFunction[A, B]): Option[B] =
foldRight(fa, Eval.now(Option.empty[B])) { (a, lb) =>
// trick from TravsersableOnce
val x = pf.applyOrElse(a, sentinel)
if (x.asInstanceOf[AnyRef] ne sentinel) Eval.now(Some(x.asInstanceOf[B]))
else lb
}.value


/**
* Like `collectFirst` from `scala.collection.Traversable` but takes `A => Option[B]`
* instead of `PartialFunction`s.
* {{{
* scala> import cats.implicits._
* scala> val keys = List(1, 2, 4, 5)
* scala> val map = Map(4 -> "Four", 5 -> "Five")
* scala> keys.collectFirstSome(map.get)
* res0: Option[String] = Some(Four)
* scala> val map2 = Map(6 -> "Six", 7 -> "Seven")
* scala> keys.collectFirstSome(map2.get)
* res1: Option[String] = None
* }}}
*/
def collectFirstSome[A, B](fa: F[A])(f: A => Option[B]): Option[B] =
foldRight(fa, Eval.now(Option.empty[B])) { (a, lb) =>
val ob = f(a)
if (ob.isDefined) Eval.now(ob) else lb
}.value

/**
* Fold implemented using the given Monoid[A] instance.
*/
Expand Down Expand Up @@ -551,6 +581,8 @@ import simulacrum.typeclass
}

object Foldable {
private val sentinel: Function1[Any, Any] = new scala.runtime.AbstractFunction1[Any, Any]{ def apply(a: Any) = this }

def iterateRight[A, B](iterable: Iterable[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = {
def loop(it: Iterator[A]): Eval[B] =
Eval.defer(if (it.hasNext) f(it.next, loop(it)) else lb)
Expand Down
40 changes: 20 additions & 20 deletions core/src/main/scala/cats/data/EitherT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -483,26 +483,6 @@ private[data] abstract class EitherTInstances1 extends EitherTInstances2 {
val F0: Traverse[F] = F
}

/** Monad error instance for recovering errors in F instead of
* the underlying Either.
*
* {{{
* scala> import cats.data.EitherT
* scala> import cats.MonadError
* scala> import cats.instances.option._
* scala> val noInt: Option[Either[String, Int]] = None
* scala> val et = EitherT[Option, String, Int](noInt)
* scala> val me = MonadError[EitherT[Option, String, ?], Unit]
* scala> me.recover(et) { case () => 1 }
* res0: cats.data.EitherT[Option,String,Int] = EitherT(Some(Right(1)))
* }}}
*/
implicit def catsDataMonadErrorFForEitherT[F[_], E, L](implicit FE0: MonadError[F, E]): MonadError[EitherT[F, L, ?], E] =
new EitherTMonadErrorF[F, E, L] { implicit val F = FE0 }
}

private[data] abstract class EitherTInstances2 extends EitherTInstances3 {

implicit def catsDataMonadErrorForEitherT[F[_], L](implicit F0: Monad[F]): MonadError[EitherT[F, L, ?], L] =
new EitherTMonadError[F, L] {
implicit val F = F0
Expand All @@ -512,6 +492,26 @@ private[data] abstract class EitherTInstances2 extends EitherTInstances3 {
override def ensureOr[A](fa: EitherT[F, L, A])(error: (A) => L)(predicate: (A) => Boolean): EitherT[F, L, A] =
fa.ensureOr(error)(predicate)(F)
}
}

private[data] abstract class EitherTInstances2 extends EitherTInstances3 {
/** Monad error instance for recovering errors in F instead of
* the underlying Either.
*
* {{{
* scala> import cats.data.EitherT
* scala> import cats.MonadError
* scala> import cats.instances.option._
* scala> val noInt: Option[Either[String, Int]] = None
* scala> val et = EitherT[Option, String, Int](noInt)
* scala> val me = MonadError[EitherT[Option, String, ?], Unit]
* scala> me.recover(et) { case () => 1 }
* res0: cats.data.EitherT[Option,String,Int] = EitherT(Some(Right(1)))
* }}}
*/
implicit def catsDataMonadErrorFForEitherT[F[_], E, L](implicit FE0: MonadError[F, E]): MonadError[EitherT[F, L, ?], E] =
new EitherTMonadErrorF[F, E, L] { implicit val F = FE0 }


implicit def catsDataSemigroupKForEitherT[F[_], L](implicit F0: Monad[F]): SemigroupK[EitherT[F, L, ?]] =
new EitherTSemigroupK[F, L] { implicit val F = F0 }
Expand Down
Loading

0 comments on commit d0ac64e

Please sign in to comment.