diff --git a/datatypes/contt.html b/datatypes/contt.html index def418595b..a58243e833 100644 --- a/datatypes/contt.html +++ b/datatypes/contt.html @@ -286,7 +286,7 @@

ContT

Succeeded(user.id) } } -// eval: Eval[UserUpdateResult] = cats.Later@68edb6dd +// eval: Eval[UserUpdateResult] = cats.Later@4cbd426f

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$14380/0x00007f397f661bb0@32a2b5ea, +// f = cats.data.ContT$$Lambda$14291/0x00007f1ed0665a60@3314d690, // index = 0 // ) // ) @@ -319,7 +319,7 @@

Succeeded(userFields("id").toInt) } } -// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@6435b180 +// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@23e959ca 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$14380/0x00007f397f661bb0@9a086f1, +// f = cats.data.ContT$$Lambda$14291/0x00007f1ed0665a60@64870a49, // index = 0 // ) // ) @@ -370,7 +370,7 @@

updateUserModel flatMap persistToDb flatMap publishEvent // chainOfContinuations: ContT[Eval, UserUpdateResult, UserUpdateResult] = FromFn( // runAndThen = Single( -// f = cats.data.ContT$$Lambda$14384/0x00007f397f662538@6c75cdce, +// f = cats.data.ContT$$Lambda$14295/0x00007f1ed06663e8@231df336, // index = 0 // ) // ) @@ -381,7 +381,7 @@

finalResult } } -// eval: Eval[UserUpdateResult] = cats.Eval$$anon$5@d9681f0 +// eval: Eval[UserUpdateResult] = cats.Eval$$anon$5@eb03d68 eval.value // Updated user model diff --git a/datatypes/eval.html b/datatypes/eval.html index 9abea75775..a6516ce6b7 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@755eab50 +// lazyEval: Eval[Int] = cats.Later@62ca7846 lazyEval.value // Running expensive calculation... @@ -276,7 +276,7 @@

println("Running expensive calculation...") 1 + 2 * 3 } -// always: Eval[Int] = cats.Always@1a6a8f7 +// always: Eval[Int] = cats.Always@1625ea44 always.value // Running expensive calculation... diff --git a/datatypes/freeapplicative.html b/datatypes/freeapplicative.html index ae667dc44e..fb2489d613 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$14542/0x00007f397f6e18c8@11120a47
+// validator: FromString[Boolean] = cats.instances.Function1Instances$$anon$7$$Lambda$14453/0x00007f1ed06e7958@6077f7ee
 validator("1234")
 // res0: Boolean = false
 validator("12345")
diff --git a/datatypes/freemonad.html b/datatypes/freemonad.html
index 0f92a65645..1b0670bfad 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@5f0dc21c +// state: TeletypeState[Unit] = cats.data.IndexedStateT@78de5324 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 5272cc476a..3e2e5f8d84 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@5264eff5

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

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@2542e677

+// res6: Eval[(Open.type, Unit)] = cats.Eval$$anon$1@5c09867f diff --git a/typeclasses/bifoldable.html b/typeclasses/bifoldable.html index 9f5fec7f7a..a43a8dfaa0 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@18c74de3 +// right: Eval[String] = cats.Eval$$anon$1@4cf4c56e 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@fdaceec +// reversedRight: Eval[String] = cats.Eval$$anon$1@68a657c1 reversedRight.value === expected // res4: Boolean = false diff --git a/typeclasses/bifunctor.html b/typeclasses/bifunctor.html index 447832ecc2..ad850d70bf 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 = 1725173999L) +// res0: Either[DomainError, Long] = Right(value = 1725412098L)

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 5da3658700..47ba9d913e 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@259adddf +// nelBimonad: Bimonad[NonEmptyList] = repl.MdocSession$MdocApp$$anon$1@4759ec16

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 11d006203b..20d9f6e42a 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$15332/0x00007f397f96ee18@5cd0a2aa +// showSalary: Show[Salary] = cats.Show$$anon$2$$Lambda$15243/0x00007f1ed0995438@1f71701f 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@257ece16 +// moneyOrdering: Ordering[Money] = scala.math.Ordering$$anon$5@47eb0df2 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@3b7e6cb8 +// b: B = repl.MdocSession$MdocApp$B@22bb5dd val a: A = b -// a: A = repl.MdocSession$MdocApp$B@3b7e6cb8 +// a: A = repl.MdocSession$MdocApp$B@22bb5dd val showA: Show[A] = Show.show(a => "a!") -// showA: Show[A] = cats.Show$$$Lambda$15331/0x00007f397f96e9a0@3b4a8a4 +// showA: Show[A] = cats.Show$$$Lambda$15242/0x00007f1ed0994fc0@456ff520 val showB1: Show[B] = showA.contramap(b => b: A) -// showB1: Show[B] = cats.Show$$anon$2$$Lambda$15332/0x00007f397f96ee18@1b612b19 +// showB1: Show[B] = cats.Show$$anon$2$$Lambda$15243/0x00007f1ed0995438@7bf135c1 val showB2: Show[B] = showA.contramap(identity[A]) -// showB2: Show[B] = cats.Show$$anon$2$$Lambda$15332/0x00007f397f96ee18@17065d9 +// showB2: Show[B] = cats.Show$$anon$2$$Lambda$15243/0x00007f1ed0995438@4ca8e67 val showB3: Show[B] = Contravariant[Show].narrow[A, B](showA) -// showB3: Show[B] = cats.Show$$$Lambda$15331/0x00007f397f96e9a0@3b4a8a4 +// showB3: Show[B] = cats.Show$$$Lambda$15242/0x00007f1ed0994fc0@456ff520

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 d629dd95a7..398bfd3c33 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@45065c48 +// eqFoo: Eq[Foo] = cats.kernel.Eq$$anonfun$fromUniversalEquals$2@3f0442c2 Foo(10, "") === Foo(10, "") diff --git a/typeclasses/semigroup.html b/typeclasses/semigroup.html index f924344fc7..7c77f99c29 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@65a94fec
+// res8: Semigroup[Int] = cats.kernel.instances.IntGroup@b58bec9
 Semigroup[String]
-// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@5e19478f
+// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@26cebeb5

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@349824d4
+// res10: Semigroup[List[Byte]] = cats.kernel.instances.ListMonoid@5a873cf3
 Semigroup[Set[Int]]
-// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@7ed5388a
+// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@2042bd73
 
 trait Foo
 Semigroup[List[Foo]]
-// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@349824d4
+// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@5a873cf3

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

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 0ba0b9e260..c698393f05 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@14fc08a0"
+// res0: String = "repl.MdocSession$MdocApp$$anon$1@34639ed1"

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$15331/0x00007f397f96e9a0@6cd97757 +// showPerson: Show[Person] = cats.Show$$$Lambda$15242/0x00007f1ed0994fc0@1036d349 case class Department(id: Int, name: String) implicit val showDep: Show[Department] = Show.fromToString -// showDep: Show[Department] = cats.Show$$$Lambda$14375/0x00007f397f626ca8@6065c432 +// showDep: Show[Department] = cats.Show$$$Lambda$14286/0x00007f1ed062eca8@405a6141

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.