diff --git a/datatypes/contt.html b/datatypes/contt.html index 4cda55badd..81a22c400c 100644 --- a/datatypes/contt.html +++ b/datatypes/contt.html @@ -286,7 +286,7 @@

ContT

Succeeded(user.id) } } -// eval: Eval[UserUpdateResult] = cats.Later@79118de7 +// eval: Eval[UserUpdateResult] = cats.Later@7cb3b8c6

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$11778/0x00007fe11ffe6208@4dc80a9, +// f = cats.data.ContT$$Lambda$11729/0x00007fea8bfe5a60@5c1c43e3, // index = 0 // ) // ) @@ -319,7 +319,7 @@

Succeeded(userFields("id").toInt) } } -// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@5844cffa +// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@447e5453 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$11778/0x00007fe11ffe6208@187d651, +// f = cats.data.ContT$$Lambda$11729/0x00007fea8bfe5a60@33d5c760, // index = 0 // ) // ) @@ -370,7 +370,7 @@

updateUserModel flatMap persistToDb flatMap publishEvent // chainOfContinuations: ContT[Eval, UserUpdateResult, UserUpdateResult] = FromFn( // runAndThen = Single( -// f = cats.data.ContT$$Lambda$11782/0x00007fe11ffe6b90@321f61bd, +// f = cats.data.ContT$$Lambda$11733/0x00007fea8bfe63e8@2c435e49, // index = 0 // ) // ) @@ -381,7 +381,7 @@

finalResult } } -// eval: Eval[UserUpdateResult] = cats.Eval$$anon$5@47ef4f89 +// eval: Eval[UserUpdateResult] = cats.Eval$$anon$5@3a9f357e eval.value // Updated user model diff --git a/datatypes/eval.html b/datatypes/eval.html index 31277e593f..f4e82b143e 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@5d734939 +// lazyEval: Eval[Int] = cats.Later@504049c6 lazyEval.value // Running expensive calculation... @@ -276,7 +276,7 @@

println("Running expensive calculation...") 1 + 2 * 3 } -// always: Eval[Int] = cats.Always@2923d25c +// always: Eval[Int] = cats.Always@241dfd26 always.value // Running expensive calculation... diff --git a/datatypes/freeapplicative.html b/datatypes/freeapplicative.html index 0e9bd55ecf..5be77e9223 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$11940/0x00007fe11f8573d0@75b133ef
+// validator: FromString[Boolean] = cats.instances.Function1Instances$$anon$7$$Lambda$11891/0x00007fea8bd4f958@474dc89
 validator("1234")
 // res0: Boolean = false
 validator("12345")
diff --git a/datatypes/freemonad.html b/datatypes/freemonad.html
index 2f293bb1ca..ff77091295 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@2348bae2 +// state: TeletypeState[Unit] = cats.data.IndexedStateT@17bc7a6 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 d90f3e325a..f50ab2e9f3 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@336b82c6

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

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@2b8687f8

+// res6: Eval[(Open.type, Unit)] = cats.Eval$$anon$1@4fed8034 diff --git a/typeclasses/bifoldable.html b/typeclasses/bifoldable.html index 3efbd51ccd..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@4b0b86e0 +// 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@1a636023 +// 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 dea9f668a3..bc1e2c994d 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 = 1726929814L) +// res0: Either[DomainError, Long] = Right(value = 1727292880L)

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 2f4471fcd9..925349979b 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@785bc056 +// nelBimonad: Bimonad[NonEmptyList] = repl.MdocSession$MdocApp$$anon$1@4f557406

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 beed642afe..d4ed09c16e 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$12730/0x00007fe1202ac6b8@4a03a760 +// showSalary: Show[Salary] = cats.Show$$anon$2$$Lambda$12681/0x00007fea8c29f438@6a887c18 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@100041c2 +// moneyOrdering: Ordering[Money] = scala.math.Ordering$$anon$5@25ac4f2b 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@3abed81c +// b: B = repl.MdocSession$MdocApp$B@4728e975 val a: A = b -// a: A = repl.MdocSession$MdocApp$B@3abed81c +// a: A = repl.MdocSession$MdocApp$B@4728e975 val showA: Show[A] = Show.show(a => "a!") -// showA: Show[A] = cats.Show$$$Lambda$12729/0x00007fe1202ac240@4abaeee3 +// showA: Show[A] = cats.Show$$$Lambda$12680/0x00007fea8c29efc0@16ad3e38 val showB1: Show[B] = showA.contramap(b => b: A) -// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12730/0x00007fe1202ac6b8@7bbc383b +// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12681/0x00007fea8c29f438@70d097ed val showB2: Show[B] = showA.contramap(identity[A]) -// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12730/0x00007fe1202ac6b8@6f0e5264 +// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12681/0x00007fea8c29f438@1acb64e7 val showB3: Show[B] = Contravariant[Show].narrow[A, B](showA) -// showB3: Show[B] = cats.Show$$$Lambda$12729/0x00007fe1202ac240@4abaeee3 +// showB3: Show[B] = cats.Show$$$Lambda$12680/0x00007fea8c29efc0@16ad3e38

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 630046dc75..bf0b61dcdb 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@7d967cc6 +// eqFoo: Eq[Foo] = cats.kernel.Eq$$anonfun$fromUniversalEquals$2@2d3c1d81 Foo(10, "") === Foo(10, "") diff --git a/typeclasses/semigroup.html b/typeclasses/semigroup.html index a687231e02..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@2bd19e19
+// res8: Semigroup[Int] = cats.kernel.instances.IntGroup@66e834c2
 Semigroup[String]
-// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@6badb018
+// 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@7a2e9d27
+// res10: Semigroup[List[Byte]] = cats.kernel.instances.ListMonoid@375a1e12
 Semigroup[Set[Int]]
-// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@5184c1f8
+// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@57c45c59
 
 trait Foo
 Semigroup[List[Foo]]
-// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@7a2e9d27
+// 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@7602ac87
+// 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 ee962c98e4..248277a9e1 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@6188b8ce"
+// 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$12729/0x00007fe1202ac240@498af097 +// showPerson: Show[Person] = cats.Show$$$Lambda$12680/0x00007fea8c29efc0@915edbf case class Department(id: Int, name: String) implicit val showDep: Show[Department] = Show.fromToString -// showDep: Show[Department] = cats.Show$$$Lambda$11773/0x00007fe11ffaf1b8@15646b26 +// showDep: Show[Department] = cats.Show$$$Lambda$11724/0x00007fea8bfaedb8@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.