diff --git a/CHANGES.md b/CHANGES.md index a8fa5d7cda..606777f024 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -69,7 +69,7 @@ This release includes some API changes: And additions: -* [#853](https://github.com/typelevel/cats/pull/853): Adds a new `LiftTrans` typeclass +* [#853](https://github.com/typelevel/cats/pull/853): Adds a new `LiftTrans` type class * [#864](https://github.com/typelevel/cats/pull/864): Add `Bifoldable` * [#875](https://github.com/typelevel/cats/pull/875): Add `.get` method to `StateT` * [#884](https://github.com/typelevel/cats/pull/884): Add `Applicative` syntax diff --git a/README.md b/README.md index e92055840c..e52f8a9145 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,6 @@ Cats will be designed to use modern *best practices*: * [scalacheck](http://scalacheck.org) for property-based testing * [discipline](https://github.com/typelevel/discipline) for encoding and testing laws * [kind-projector](https://github.com/non/kind-projector) for type lambda syntax - * [algebra](https://github.com/non/algebra) for shared algebraic structures * ...and of course a pure functional subset of the Scala language. (We also plan to support [Miniboxing](http://scala-miniboxing.org) in a branch.) diff --git a/build.sbt b/build.sbt index eeb1c8941d..75f2094622 100644 --- a/build.sbt +++ b/build.sbt @@ -4,6 +4,7 @@ import com.typesafe.sbt.SbtGhPages.GhPagesKeys._ import sbtunidoc.Plugin.UnidocKeys._ import ReleaseTransformations._ import ScoverageSbtPlugin._ +import scala.xml.transform.{RewriteRule, RuleTransformer} lazy val botBuild = settingKey[Boolean]("Build by TravisCI instead of local dev environment") @@ -11,7 +12,22 @@ lazy val scoverageSettings = Seq( ScoverageKeys.coverageMinimum := 60, ScoverageKeys.coverageFailOnMinimum := false, ScoverageKeys.coverageHighlighting := scalaBinaryVersion.value != "2.10", - ScoverageKeys.coverageExcludedPackages := "cats\\.bench\\..*" + ScoverageKeys.coverageExcludedPackages := "cats\\.bench\\..*", + // don't include scoverage as a dependency in the pom + // see issue #980 + // this code was copied from https://github.com/mongodb/mongo-spark + pomPostProcess := { (node: xml.Node) => + new RuleTransformer( + new RewriteRule { + override def transform(node: xml.Node): Seq[xml.Node] = node match { + case e: xml.Elem + if e.label == "dependency" && e.child.exists(child => child.label == "groupId" && child.text == "org.scoverage") => Nil + case _ => Seq(node) + + } + + }).transform(node).head + } ) lazy val buildSettings = Seq( diff --git a/core/src/main/scala/cats/TransLift.scala b/core/src/main/scala/cats/TransLift.scala index 7901c55925..e8addcb745 100644 --- a/core/src/main/scala/cats/TransLift.scala +++ b/core/src/main/scala/cats/TransLift.scala @@ -2,13 +2,13 @@ package cats /** - * A typeclass which abstracts over the ability to lift an M[A] into a + * A type class which abstracts over the ability to lift an M[A] into a * MonadTransformer */ trait TransLift[MT[_[_], _]] { /** - * The typeclass which constrains liftT as a function of the type + * The type class which constrains liftT as a function of the type * constructor it is given. A safe "identity" value for this type * if your transformer does not constrain its lifted effects would * be `type TC[M[_]] = Trivial`. A more common constraint might be diff --git a/core/src/main/scala/cats/Trivial.scala b/core/src/main/scala/cats/Trivial.scala index 1f8ed629c9..2a8ff9200a 100644 --- a/core/src/main/scala/cats/Trivial.scala +++ b/core/src/main/scala/cats/Trivial.scala @@ -1,11 +1,11 @@ package cats /** - * The "Unit typeclass". The only instance of `Trivial` is given by + * The "Unit type class". The only instance of `Trivial` is given by * `Trivial.manifest`, and this instance is guaranteed to be in the * implicit scope. Several convenience type aliases are provided in * companion object, covering a few common use cases and avoiding the - * need for unnecessary lambdas (e.g. if you want a trivial typeclass + * need for unnecessary lambdas (e.g. if you want a trivial type class * instance for a type constructor, you should use `Trivial.PH1`). */ sealed trait Trivial diff --git a/core/src/main/scala/cats/instances/try.scala b/core/src/main/scala/cats/instances/try.scala index 63a16e9cdb..32ee335f35 100644 --- a/core/src/main/scala/cats/instances/try.scala +++ b/core/src/main/scala/cats/instances/try.scala @@ -6,12 +6,13 @@ import TryInstances.castFailure import scala.util.control.NonFatal import scala.util.{Failure, Success, Try} +import scala.annotation.tailrec trait TryInstances extends TryInstances1 { // scalastyle:off method.length - implicit def catsStdInstancesForTry: MonadError[Try, Throwable] with CoflatMap[Try] with Traverse[Try] = - new TryCoflatMap with MonadError[Try, Throwable] with Traverse[Try] { + implicit def catsStdInstancesForTry: MonadError[Try, Throwable] with CoflatMap[Try] with Traverse[Try] with MonadRec[Try] = + new TryCoflatMap with MonadError[Try, Throwable] with Traverse[Try] with MonadRec[Try] { def pure[A](x: A): Try[A] = Success(x) override def pureEval[A](x: Eval[A]): Try[A] = x match { @@ -57,6 +58,13 @@ trait TryInstances extends TryInstances1 { case f: Failure[_] => G.pure(castFailure[B](f)) } + @tailrec final def tailRecM[B, C](b: B)(f: B => Try[(B Xor C)]): Try[C] = + f(b) match { + case f: Failure[_] => castFailure[C](f) + case Success(Xor.Left(b1)) => tailRecM(b1)(f) + case Success(Xor.Right(c)) => Success(c) + } + def handleErrorWith[A](ta: Try[A])(f: Throwable => Try[A]): Try[A] = ta.recoverWith { case t => f(t) } diff --git a/docs/src/main/tut/contravariant.md b/docs/src/main/tut/contravariant.md index 7bbb629a83..b121276a3a 100644 --- a/docs/src/main/tut/contravariant.md +++ b/docs/src/main/tut/contravariant.md @@ -20,7 +20,7 @@ but with the `f` transformation reversed. Generally speaking, if you have some context `F[A]` for type `A`, and you can get an `A` value out of a `B` value — `Contravariant` allows you to get the `F[B]` context for `B`. -Examples of `Contravariant` instances are [`Show`](show.html) and `scala.math.Ordering` (along with `algebra.Order`). +Examples of `Contravariant` instances are [`Show`](show.html) and `scala.math.Ordering` (along with `cats.kernel.Order`). ## Contravariant instance for Show. @@ -51,7 +51,7 @@ Salary(Money(1000)).show `Show` example is trivial and quite far-fetched, let's see how `Contravariant` can help with orderings. -`scala.math.Ordering` typeclass defines comparison operations, e.g. `compare`: +`scala.math.Ordering` type class defines comparison operations, e.g. `compare`: ```tut:book Ordering.Int.compare(2, 1) diff --git a/docs/src/main/tut/faq.md b/docs/src/main/tut/faq.md index f5447e5bde..8e343b9605 100644 --- a/docs/src/main/tut/faq.md +++ b/docs/src/main/tut/faq.md @@ -15,7 +15,7 @@ import cats.data._ import cats.implicits._ ``` -The `cats._` import brings in quite a few [typeclasses](http://typelevel.org/cats/typeclasses.html) (similar to interfaces) such as [Monad](http://typelevel.org/cats/tut/monad.html), [Semigroup](http://typelevel.org/cats/tut/semigroup.html), and [Foldable](http://typelevel.org/cats/tut/foldable.html). Instead of the entire `cats` package, you can import only the types that you need, for example: +The `cats._` import brings in quite a few [type classes](http://typelevel.org/cats/typeclasses.html) (similar to interfaces) such as [Monad](http://typelevel.org/cats/tut/monad.html), [Semigroup](http://typelevel.org/cats/tut/semigroup.html), and [Foldable](http://typelevel.org/cats/tut/foldable.html). Instead of the entire `cats` package, you can import only the types that you need, for example: ```tut:silent import cats.Monad diff --git a/docs/src/main/tut/freemonad.md b/docs/src/main/tut/freemonad.md index 3fc33fdd27..b9a93c8b8c 100644 --- a/docs/src/main/tut/freemonad.md +++ b/docs/src/main/tut/freemonad.md @@ -477,16 +477,12 @@ If you look at implementation in cats, you will see another member of the `Free[_]` ADT: ```scala -sealed abstract case class Gosub[S[_], B]() extends Free[S, B] { - type C - val a: () => Free[S, C] - val f: C => Free[S, B] -} +case class FlatMapped[S[_], B, C](c: Free[S, C], f: C => Free[S, B]) extends Free[S, B] ``` -`Gosub` represents a call to a subroutine `a` and when `a` is +`FlatMapped` represents a call to a subroutine `c` and when `c` is finished, it continues the computation by calling the function `f` -with the result of `a`. +with the result of `c`. It is actually an optimization of `Free` structure allowing to solve a problem of quadratic complexity implied by very deep recursive `Free` @@ -494,7 +490,7 @@ computations. It is exactly the same problem as repeatedly appending to a `List[_]`. As the sequence of operations becomes longer, the slower a `flatMap` -"through" the structure will be. With `Gosub`, `Free` becomes a +"through" the structure will be. With `FlatMapped`, `Free` becomes a right-associated structure not subject to quadratic complexity. ## Future Work (TODO) diff --git a/docs/src/main/tut/invariant.md b/docs/src/main/tut/invariant.md index cd1c4a4492..f0ce5c9529 100644 --- a/docs/src/main/tut/invariant.md +++ b/docs/src/main/tut/invariant.md @@ -30,7 +30,7 @@ timestamp. Let's say that we want to create a `Semigroup[Date]`, by ### Semigroup does not form a covariant functor If `Semigroup` had an instance for the standard covariant [`Functor`](functor.html) -typeclass, we could use `map` to apply a function `longToDate`: +type class, we could use `map` to apply a function `longToDate`: ```tut:silent import java.util.Date diff --git a/docs/src/main/tut/monoid.md b/docs/src/main/tut/monoid.md index 97a05cb2e6..a450da221d 100644 --- a/docs/src/main/tut/monoid.md +++ b/docs/src/main/tut/monoid.md @@ -2,8 +2,8 @@ layout: default title: "Monoid" section: "typeclasses" -source: "https://github.com/non/algebra/blob/master/core/src/main/scala/algebra/Monoid.scala" - +source: "kernel/src/main/scala/cats/kernel/Monoid.scala" +scaladoc: "#cats.kernel.Monoid" --- # Monoid @@ -70,10 +70,7 @@ l.foldMap(i => (i, i.toString)) // do both of the above in one pass, hurrah! ------------------------------------------------------------------------------- N.B. -Cats does not define a `Monoid` type class itself, it uses the [`Monoid` -trait](https://github.com/non/algebra/blob/master/core/src/main/scala/algebra/Monoid.scala) -which is defined in the [algebra project](https://github.com/non/algebra) on -which it depends. The [`cats` package object](https://github.com/typelevel/cats/blob/master/core/src/main/scala/cats/package.scala) -defines type aliases to the `Monoid` from algebra, so that you can -`import cats.Monoid`. Also the `Monoid` instance for tuple is also [implemented in algebra](https://github.com/non/algebra/blob/v0.4.2/project/Boilerplate.scala#L80-L217), -cats merely provides it through [inheritance](https://github.com/typelevel/cats/blob/v0.5.0/core/src/main/scala/cats/std/tuple.scala). +Cats defines the `Monoid` type class in cats-kernel. The [`cats` package object](https://github.com/typelevel/cats/blob/master/core/src/main/scala/cats/package.scala) +defines type aliases to the `Monoid` from cats-kernel, so that you can +`import cats.Monoid`. Also the `Monoid` instance for tuple is also [implemented in cats-kernel](https://github.com/typelevel/cats/blob/master/project/KernelBoiler.scala), +cats merely provides it through [inheritance](https://github.com/typelevel/cats/blob/master/core/src/main/scala/cats/std/tuple.scala). diff --git a/docs/src/main/tut/semigroup.md b/docs/src/main/tut/semigroup.md index 5b522b6fa3..811dbac3cd 100644 --- a/docs/src/main/tut/semigroup.md +++ b/docs/src/main/tut/semigroup.md @@ -2,8 +2,8 @@ layout: default title: "Semigroup" section: "typeclasses" -source: "https://github.com/non/algebra/blob/master/core/src/main/scala/algebra/Semigroup.scala" - +source: "kernel/src/main/scala/cats/kernel/Semigroup.scala" +scaladoc: "#cats.kernel.Semigroup" --- # Semigroup @@ -93,9 +93,6 @@ None |+| Some(1) ``` N.B. -Cats does not define a `Semigroup` type class itself, it uses the [`Semigroup` -trait](https://github.com/non/algebra/blob/master/core/src/main/scala/algebra/Semigroup.scala) -which is defined in the [algebra project](https://github.com/non/algebra) on -which it depends. The [`cats` package object](https://github.com/typelevel/cats/blob/master/core/src/main/scala/cats/package.scala) -defines type aliases to the `Semigroup` from algebra, so that you can +Cats defines the `Semigroup` type class in cats-kernel. The [`cats` package object](https://github.com/typelevel/cats/blob/master/core/src/main/scala/cats/package.scala) +defines type aliases to the `Semigroup` from cats-kernel, so that you can `import cats.Semigroup`. diff --git a/docs/src/main/tut/semigroupk.md b/docs/src/main/tut/semigroupk.md index 5895b481ad..4b7fdd5abc 100644 --- a/docs/src/main/tut/semigroupk.md +++ b/docs/src/main/tut/semigroupk.md @@ -7,52 +7,7 @@ scaladoc: "#cats.SemigroupK" --- # SemigroupK -Before introducing a `SemigroupK`, it makes sense to talk about what a -`Semigroup` is. A semigroup for some given type `A` has a single operation -(which we will call `combine`), which takes two values of type `A`, and -returns a value of type `A`. This operation must be guaranteed to be -associative. That is to say that: - -```scala -((a combine b) combine c) -``` - -must be the same as - -```scala -(a combine (b combine c)) -``` - -for all possible values of `a`, `b`, `c`. - -Cats does not define a `Semigroup` type class itself. Instead, we use the -[`Semigroup` -trait](https://github.com/non/algebra/blob/master/core/src/main/scala/algebra/Semigroup.scala) -which is defined in the [algebra -project](https://github.com/non/algebra). The [`cats` package -object](https://github.com/typelevel/cats/blob/master/core/src/main/scala/cats/package.scala) -defines type aliases to the `Semigroup` from algebra, so that you can -`import cats.semigroup`. - -There are instances of `Semigroup` defined for many types found in the -scala common library: - -```tut:silent -import cats._ -import cats.implicits._ -``` - -Examples. - -```tut:book -Semigroup[Int].combine(1, 2) -Semigroup[List[Int]].combine(List(1,2,3), List(4,5,6)) -Semigroup[Option[Int]].combine(Option(1), Option(2)) -Semigroup[Option[Int]].combine(Option(1), None) -Semigroup[Int => Int].combine({(x: Int) => x + 1},{(x: Int) => x * 10}).apply(6) -``` - -`SemigroupK` has a very similar structure to `Semigroup`, the difference +`SemigroupK` has a very similar structure to [`Semigroup`](semigroup.html), the difference is that `SemigroupK` operates on type constructors of one argument. So, for example, whereas you can find a `Semigroup` for types which are fully specified like `Int` or `List[Int]` or `Option[Int]`, you will find @@ -64,6 +19,13 @@ takes a concrete type, like `Int`, and returns a concrete type: *`, whereas `Int` would have kind `*` and `Map` would have kind `*,* -> *`, and, in fact, the `K` in `SemigroupK` stands for `Kind`. +First some imports. + +```tut:silent +import cats._ +import cats.implicits._ +``` + For `List`, the `Semigroup` instance's `combine` operation and the `SemigroupK` instance's `combineK` operation are both list concatenation: diff --git a/docs/src/main/tut/symbols.md b/docs/src/main/tut/symbols.md index 000f800d2a..dc84bf5792 100644 --- a/docs/src/main/tut/symbols.md +++ b/docs/src/main/tut/symbols.md @@ -8,7 +8,7 @@ All other symbols can be imported with `import cats.implicits._` A scaladoc generated list is also available on the [Scaladoc symbols page](http://typelevel.org/cats/api/#index.index-_). -| Symbol | Name | Typeclass | Definition | +| Symbol | Name | Type Class | Definition | | ---------- | ---------------------- | ---------------------------------------------------------------------------------------- |--------------------------------------- | | `fa |@| fb`| Cartesian builder | [`Cartesian[F[_]]`]({{ site.sources }}/core/src/main/scala/cats/Cartesian.scala) | `|@|(fa: F[A])(fb: F[B]): F[(A, B)]` | | `fa *> fb` | right apply | [`Cartesian[F[_]]`]({{ site.sources }}/core/src/main/scala/cats/Cartesian.scala) | `*>(fa: F[A])(fb: F[B]): F[A]` | @@ -28,4 +28,4 @@ A scaladoc generated list is also available on the [Scaladoc symbols page](http: | `F :<: G` | inject | [`Inject[F[_], G[_]]`]({{ site.sources }}/free/src/main/scala/cats/free/package.scala) | `Inject` alias | | `F :≺: G` | inject | [`Inject[F[_], G[_]]`]({{ site.sources }}/free/src/main/scala/cats/free/package.scala) | `Inject` alias | | `⊥` | bottom | [N/A]({{ site.sources }}/core/src/main/scala/cats/package.scala) | `Nothing` | -| `⊤` | top | [N/A]({{ site.sources }}/core/src/main/scala/cats/package.scala) | `Any` | \ No newline at end of file +| `⊤` | top | [N/A]({{ site.sources }}/core/src/main/scala/cats/package.scala) | `Any` | diff --git a/docs/src/site/_layouts/default.html b/docs/src/site/_layouts/default.html index f74e423785..332a901ba8 100644 --- a/docs/src/site/_layouts/default.html +++ b/docs/src/site/_layouts/default.html @@ -41,7 +41,7 @@