diff --git a/datatypes/contt.html b/datatypes/contt.html index 214f9bba1e..56c08f71f7 100644 --- a/datatypes/contt.html +++ b/datatypes/contt.html @@ -286,7 +286,7 @@

ContT

Succeeded(user.id) } } -// eval: Eval[UserUpdateResult] = cats.Later@6a4a4185 +// eval: Eval[UserUpdateResult] = cats.Later@18b69b8a

Finally we can run the resulting Eval to actually execute the computation:

eval.value
 // Persisting updated user to the DB: User(100,Bob,150)
@@ -308,7 +308,7 @@ 

// anotherComputation: ContT[Eval, UserUpdateResult, Map[String, String]] = FromFn( // runAndThen = Single( -// f = cats.data.ContT$$Lambda$14382/0x00007f820366c8f0@3c260a17, +// f = cats.data.ContT$$Lambda$11758/0x00007f3c22fee208@19c7874f, // index = 0 // ) // ) @@ -319,7 +319,7 @@

Succeeded(userFields("id").toInt) } } -// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@1bd9e038 +// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@1a640156 anotherEval.value // Persisting these fields to the DB: Map(id -> 100, name -> Bob, age -> 150) @@ -336,7 +336,7 @@

// updateUserModel: ContT[Eval, UserUpdateResult, User] = FromFn( // runAndThen = Single( -// f = cats.data.ContT$$Lambda$14382/0x00007f820366c8f0@1b360755, +// f = cats.data.ContT$$Lambda$11758/0x00007f3c22fee208@5904ad8c, // index = 0 // ) // ) @@ -370,7 +370,7 @@

updateUserModel flatMap persistToDb flatMap publishEvent // chainOfContinuations: ContT[Eval, UserUpdateResult, UserUpdateResult] = FromFn( // runAndThen = Single( -// f = cats.data.ContT$$Lambda$14386/0x00007f820366d278@320322d8, +// f = cats.data.ContT$$Lambda$11762/0x00007f3c22feeb90@7fb8323e, // index = 0 // ) // ) @@ -381,7 +381,7 @@

finalResult } } -// eval: Eval[UserUpdateResult] = cats.Eval$$anon$5@1c1ec9cc +// eval: Eval[UserUpdateResult] = cats.Eval$$anon$5@42acc10f eval.value // Updated user model diff --git a/datatypes/eval.html b/datatypes/eval.html index 6ddfcba1fa..f52fee517e 100644 --- a/datatypes/eval.html +++ b/datatypes/eval.html @@ -257,7 +257,7 @@

println("Running expensive calculation...") 1 + 2 * 3 } -// lazyEval: Eval[Int] = cats.Later@6c7c6ad4 +// lazyEval: Eval[Int] = cats.Later@466aa7b lazyEval.value // Running expensive calculation... @@ -276,7 +276,7 @@

println("Running expensive calculation...") 1 + 2 * 3 } -// always: Eval[Int] = cats.Always@189d51b4 +// always: Eval[Int] = cats.Always@70eff6da always.value // Running expensive calculation... diff --git a/datatypes/freeapplicative.html b/datatypes/freeapplicative.html index 69dc717c5c..7317460216 100644 --- a/datatypes/freeapplicative.html +++ b/datatypes/freeapplicative.html @@ -275,7 +275,7 @@

val validator = prog.foldMap[FromString](compiler)
-// validator: FromString[Boolean] = cats.instances.Function1Instances$$anon$7$$Lambda$14544/0x00007f82036eb188@5048ccd4
+// validator: FromString[Boolean] = cats.instances.Function1Instances$$anon$7$$Lambda$11920/0x00007f3c22878000@3214a97d
 validator("1234")
 // res0: Boolean = false
 validator("12345")
diff --git a/datatypes/freemonad.html b/datatypes/freemonad.html
index 2eabfb09a2..b07b9439e1 100644
--- a/datatypes/freemonad.html
+++ b/datatypes/freemonad.html
@@ -718,7 +718,7 @@ 

import TeletypeOps._ val state = program.foldMap(interpreter) -// state: TeletypeState[Unit] = cats.data.IndexedStateT@edd7929 +// state: TeletypeState[Unit] = cats.data.IndexedStateT@219e6e2e val initialState = Nil // initialState: Nil.type = List() val (stored, _) = state.run(initialState).value @@ -789,7 +789,7 @@

val evaluated = hoisted.foldMap(tryInterpreter) // evaluated: OptTry[Int] = OptionT(value = Success(value = Some(value = 12))) diff --git a/datatypes/state.html b/datatypes/state.html index e0b929c0b1..635d0acdba 100644 --- a/datatypes/state.html +++ b/datatypes/state.html @@ -474,7 +474,7 @@

_ <- close _ <- open } yield () -// valid: IndexedStateT[Eval, Closed.type, Open.type, Unit] = cats.data.IndexedStateT@47234f3a

+// valid: IndexedStateT[Eval, Closed.type, Open.type, Unit] = cats.data.IndexedStateT@614976c5

Note that the inferred type of valid correctly models that this computation can be executed only with an initial Closed state.

valid.run(Open)
 // error: type mismatch;
@@ -483,7 +483,7 @@ 

valid.run(Closed) -// res6: Eval[(Open.type, Unit)] = cats.Eval$$anon$1@5b5a1e1b

+// res6: Eval[(Open.type, Unit)] = cats.Eval$$anon$1@2a29821a diff --git a/typeclasses/bifoldable.html b/typeclasses/bifoldable.html index 0db2d6199d..14976092f4 100644 --- a/typeclasses/bifoldable.html +++ b/typeclasses/bifoldable.html @@ -338,7 +338,7 @@

s, acc) => acc.map(_ |+| s), (s, acc) => acc.map(_ |+| s) ) -// right: Eval[String] = cats.Eval$$anon$1@52291bef +// right: Eval[String] = cats.Eval$$anon$1@51a80682 left === expected // res2: Boolean = true @@ -354,7 +354,7 @@

s, acc) => acc.map(_ |+| s), (s, acc) => acc.map(_ |+| s) ) -// reversedRight: Eval[String] = cats.Eval$$anon$1@55e1aa8 +// reversedRight: Eval[String] = cats.Eval$$anon$1@440c495a reversedRight.value === expected // res4: Boolean = false diff --git a/typeclasses/bifunctor.html b/typeclasses/bifunctor.html index 9371908e1e..e3b93549f1 100644 --- a/typeclasses/bifunctor.html +++ b/typeclasses/bifunctor.html @@ -246,7 +246,7 @@

error => DomainError(error.getMessage), dateTime => dateTime.toEpochSecond ) -// res0: Either[DomainError, Long] = Right(value = 1722266657L) +// res0: Either[DomainError, Long] = Right(value = 1723507689L)

Bifunctor also defines a convenience function called leftMap, which is defined as follows:

def leftMap[A, B, C](fab: F[A, B])(f: A => C): F[C, B] = bimap(fab)(f, identity)

There is no rightMap however - use map instead. The reasoning behind this is that in Cats, the instances of diff --git a/typeclasses/bimonad.html b/typeclasses/bimonad.html index a064962438..594a6eaadd 100644 --- a/typeclasses/bimonad.html +++ b/typeclasses/bimonad.html @@ -263,7 +263,7 @@

override def tailRecM[A, B](a: A)(fn: A => NonEmptyList[Either[A, B]]): NonEmptyList[B] = ??? } -// nelBimonad: Bimonad[NonEmptyList] = repl.MdocSession$MdocApp$$anon$1@51a1f7e0 +// nelBimonad: Bimonad[NonEmptyList] = repl.MdocSession$MdocApp$$anon$1@39e4f338

Note the equivalence:

nelBimonad.pure(true).extract === NonEmptyList.one(true).head
 // res0: Boolean = true
diff --git a/typeclasses/contravariant.html b/typeclasses/contravariant.html index 264a45b528..30b3283928 100644 --- a/typeclasses/contravariant.html +++ b/typeclasses/contravariant.html @@ -246,7 +246,7 @@

implicit val showSalary: Show[Salary] = showMoney.contramap(_.size) -// showSalary: Show[Salary] = cats.Show$$anon$2$$Lambda$15334/0x00007f820397b928@2c5bf11c +// showSalary: Show[Salary] = cats.Show$$anon$2$$Lambda$12710/0x00007f3c2328ab60@17cb5a00 Salary(Money(1000)).show // res0: String = "$1000" @@ -266,7 +266,7 @@

import scala.math.Ordered._ implicit val moneyOrdering: Ordering[Money] = Ordering.by(_.amount) -// moneyOrdering: Ordering[Money] = scala.math.Ordering$$anon$5@7e12b3bd +// moneyOrdering: Ordering[Money] = scala.math.Ordering$$anon$5@20ced3bd Money(100) < Money(200) // res3: Boolean = true @@ -276,17 +276,17 @@

class A class B extends A val b: B = new B -// b: B = repl.MdocSession$MdocApp$B@69cc0baa +// b: B = repl.MdocSession$MdocApp$B@2e6d1583 val a: A = b -// a: A = repl.MdocSession$MdocApp$B@69cc0baa +// a: A = repl.MdocSession$MdocApp$B@2e6d1583 val showA: Show[A] = Show.show(a => "a!") -// showA: Show[A] = cats.Show$$$Lambda$15333/0x00007f820397b4b0@246a67d5 +// showA: Show[A] = cats.Show$$$Lambda$12709/0x00007f3c2328a6e8@53566c5e val showB1: Show[B] = showA.contramap(b => b: A) -// showB1: Show[B] = cats.Show$$anon$2$$Lambda$15334/0x00007f820397b928@6db18e72 +// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12710/0x00007f3c2328ab60@19a573d5 val showB2: Show[B] = showA.contramap(identity[A]) -// showB2: Show[B] = cats.Show$$anon$2$$Lambda$15334/0x00007f820397b928@2f9cc16f +// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12710/0x00007f3c2328ab60@6f1d16a8 val showB3: Show[B] = Contravariant[Show].narrow[A, B](showA) -// showB3: Show[B] = cats.Show$$$Lambda$15333/0x00007f820397b4b0@246a67d5 +// showB3: Show[B] = cats.Show$$$Lambda$12709/0x00007f3c2328a6e8@53566c5e

Subtyping relationships are "lifted backwards" by contravariant functors, such that if F is a lawful contravariant functor and B <: A then F[A] <: F[B], which is expressed by Contravariant.narrow.

diff --git a/typeclasses/eq.html b/typeclasses/eq.html index c46bedd77e..8ee7a08bfb 100644 --- a/typeclasses/eq.html +++ b/typeclasses/eq.html @@ -257,7 +257,7 @@

Eq

implicit val eqFoo: Eq[Foo] = Eq.fromUniversalEquals -// eqFoo: Eq[Foo] = cats.kernel.Eq$$anonfun$fromUniversalEquals$2@7bb0c35 +// eqFoo: Eq[Foo] = cats.kernel.Eq$$anonfun$fromUniversalEquals$2@2e96fc48 Foo(10, "") === Foo(10, "") diff --git a/typeclasses/semigroup.html b/typeclasses/semigroup.html index 2b1d36c36b..f3d2d15740 100644 --- a/typeclasses/semigroup.html +++ b/typeclasses/semigroup.html @@ -269,23 +269,23 @@

import cats.Semigroup import cats.syntax.all._
Semigroup[Int]
-// res8: Semigroup[Int] = cats.kernel.instances.IntGroup@2d60825d
+// res8: Semigroup[Int] = cats.kernel.instances.IntGroup@66e834c2
 Semigroup[String]
-// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@56780e6f
+// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@4f5d61ad

Instances for type constructors regardless of their type parameter such as List (++) and Set (union)...

Semigroup[List[Byte]]
-// res10: Semigroup[List[Byte]] = cats.kernel.instances.ListMonoid@7c1920e9
+// res10: Semigroup[List[Byte]] = cats.kernel.instances.ListMonoid@375a1e12
 Semigroup[Set[Int]]
-// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@723ab76a
+// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@57c45c59
 
 trait Foo
 Semigroup[List[Foo]]
-// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@7c1920e9
+// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@375a1e12

And instances for type constructors that depend on (one of) their type parameters having instances such as tuples (pointwise combine).

Semigroup[(List[Foo], Int)]
-// res13: Semigroup[(List[Foo], Int)] = cats.kernel.Monoid$$anon$2@5be1a11a
+// res13: Semigroup[(List[Foo], Int)] = cats.kernel.Monoid$$anon$2@70ad2c47

Example usage: Merging maps

Consider a function that merges two Maps that combines values if they share diff --git a/typeclasses/show.html b/typeclasses/show.html index 741b1851fd..413869abd6 100644 --- a/typeclasses/show.html +++ b/typeclasses/show.html @@ -229,7 +229,7 @@

Show

Most often, this is unwanted behaviour, as the standard implementation of toString on non case classes is mostly gibberish. Consider the following example:

(new {}).toString
-// res0: String = "repl.MdocSession$MdocApp$$anon$1@5ad85b41"
+// res0: String = "repl.MdocSession$MdocApp$$anon$1@7b60a068"

The fact that this code compiles is a design flaw of the Java API. We want to make things like this impossible, by offering the toString equivalent as a type class, instead of the root of the class hierarchy. In short, Show allows us to only have String-conversions defined for the data types we actually want.

@@ -245,12 +245,12 @@

Show

case class Person(name: String, age: Int) implicit val showPerson: Show[Person] = Show.show(person => person.name) -// showPerson: Show[Person] = cats.Show$$$Lambda$15333/0x00007f820397b4b0@4e2ac40c +// showPerson: Show[Person] = cats.Show$$$Lambda$12709/0x00007f3c2328a6e8@915edbf case class Department(id: Int, name: String) implicit val showDep: Show[Department] = Show.fromToString -// showDep: Show[Department] = cats.Show$$$Lambda$14377/0x00007f82036358a8@2e0ff460 +// showDep: Show[Department] = cats.Show$$$Lambda$11753/0x00007f3c22fb71b8@f968a25

This still may not seem useful to you, because case classes already automatically implement toString, while show would have to be implemented manually for each case class. Thankfully with the help of a small library called kittens a lot of type class instances including Show can be derived automatically!

Cats also offers Show syntax to make working with it easier.