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

ContT

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

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

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

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

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

println("Running expensive calculation...") 1 + 2 * 3 } -// always: Eval[Int] = cats.Always@672e8b15 +// always: Eval[Int] = cats.Always@2923d25c always.value // Running expensive calculation... diff --git a/datatypes/freeapplicative.html b/datatypes/freeapplicative.html index e4094d0eed..0e9bd55ecf 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$11820/0x00007f5d2ff73648@5492c057
+// validator: FromString[Boolean] = cats.instances.Function1Instances$$anon$7$$Lambda$11940/0x00007fe11f8573d0@75b133ef
 validator("1234")
 // res0: Boolean = false
 validator("12345")
diff --git a/datatypes/freemonad.html b/datatypes/freemonad.html
index 2dbb6f7184..2f293bb1ca 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@7cb7cc0e +// state: TeletypeState[Unit] = cats.data.IndexedStateT@2348bae2 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 ba4c2f357b..d90f3e325a 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@4e134c49

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

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@ba9d988

+// res6: Eval[(Open.type, Unit)] = cats.Eval$$anon$1@2b8687f8 diff --git a/typeclasses/bifoldable.html b/typeclasses/bifoldable.html index a51d368975..3efbd51ccd 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@6e52a71 +// right: Eval[String] = cats.Eval$$anon$1@4b0b86e0 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@4cc99b5e +// reversedRight: Eval[String] = cats.Eval$$anon$1@1a636023 reversedRight.value === expected // res4: Boolean = false diff --git a/typeclasses/bifunctor.html b/typeclasses/bifunctor.html index dff8953291..dea9f668a3 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 = 1726451601L) +// res0: Either[DomainError, Long] = Right(value = 1726929814L)

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 823da50e7d..2f4471fcd9 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@11c93402 +// nelBimonad: Bimonad[NonEmptyList] = repl.MdocSession$MdocApp$$anon$1@785bc056

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 0a9f3f9f9f..beed642afe 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$12610/0x00007f5d3028d210@17f61fe5 +// showSalary: Show[Salary] = cats.Show$$anon$2$$Lambda$12730/0x00007fe1202ac6b8@4a03a760 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@3eea772c +// moneyOrdering: Ordering[Money] = scala.math.Ordering$$anon$5@100041c2 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@1ab7ee8d +// b: B = repl.MdocSession$MdocApp$B@3abed81c val a: A = b -// a: A = repl.MdocSession$MdocApp$B@1ab7ee8d +// a: A = repl.MdocSession$MdocApp$B@3abed81c val showA: Show[A] = Show.show(a => "a!") -// showA: Show[A] = cats.Show$$$Lambda$12609/0x00007f5d3028cd98@5da074a +// showA: Show[A] = cats.Show$$$Lambda$12729/0x00007fe1202ac240@4abaeee3 val showB1: Show[B] = showA.contramap(b => b: A) -// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12610/0x00007f5d3028d210@13700fc4 +// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12730/0x00007fe1202ac6b8@7bbc383b val showB2: Show[B] = showA.contramap(identity[A]) -// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12610/0x00007f5d3028d210@51c7b76e +// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12730/0x00007fe1202ac6b8@6f0e5264 val showB3: Show[B] = Contravariant[Show].narrow[A, B](showA) -// showB3: Show[B] = cats.Show$$$Lambda$12609/0x00007f5d3028cd98@5da074a +// showB3: Show[B] = cats.Show$$$Lambda$12729/0x00007fe1202ac240@4abaeee3

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 0cc98e4ad9..630046dc75 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@59f4ecb1 +// eqFoo: Eq[Foo] = cats.kernel.Eq$$anonfun$fromUniversalEquals$2@7d967cc6 Foo(10, "") === Foo(10, "") diff --git a/typeclasses/semigroup.html b/typeclasses/semigroup.html index 767f00e42e..a687231e02 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@32509746
+// res8: Semigroup[Int] = cats.kernel.instances.IntGroup@2bd19e19
 Semigroup[String]
-// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@2f76d6f3
+// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@6badb018

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@63360dfb
+// res10: Semigroup[List[Byte]] = cats.kernel.instances.ListMonoid@7a2e9d27
 Semigroup[Set[Int]]
-// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@1bf6dc5b
+// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@5184c1f8
 
 trait Foo
 Semigroup[List[Foo]]
-// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@63360dfb
+// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@7a2e9d27

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@2d2a82c4
+// res13: Semigroup[(List[Foo], Int)] = cats.kernel.Monoid$$anon$2@7602ac87

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 e48e80340d..ee962c98e4 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@28bdb925"
+// res0: String = "repl.MdocSession$MdocApp$$anon$1@6188b8ce"

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$12609/0x00007f5d3028cd98@61e492ce +// showPerson: Show[Person] = cats.Show$$$Lambda$12729/0x00007fe1202ac240@498af097 case class Department(id: Int, name: String) implicit val showDep: Show[Department] = Show.fromToString -// showDep: Show[Department] = cats.Show$$$Lambda$11653/0x00007f5d2ffaf3b8@5c989fcf +// showDep: Show[Department] = cats.Show$$$Lambda$11773/0x00007fe11ffaf1b8@15646b26

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.