diff --git a/datatypes/contt.html b/datatypes/contt.html index 27ca719894..b2534a5423 100644 --- a/datatypes/contt.html +++ b/datatypes/contt.html @@ -286,7 +286,7 @@

ContT

Succeeded(user.id) } } -// eval: Eval[UserUpdateResult] = cats.Later@245bacfa +// eval: Eval[UserUpdateResult] = cats.Later@55a0f7ee

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$11738/0x00007f1a8bffec90@1e2e5f80, +// f = cats.data.ContT$$Lambda$11945/0x00007fe490028988@4ae07779, // index = 0 // ) // ) @@ -319,7 +319,7 @@

Succeeded(userFields("id").toInt) } } -// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@1294f369 +// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@61ac2953 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$11738/0x00007f1a8bffec90@5c7359b6, +// f = cats.data.ContT$$Lambda$11945/0x00007fe490028988@3277a7b2, // index = 0 // ) // ) @@ -370,7 +370,7 @@

updateUserModel flatMap persistToDb flatMap publishEvent // chainOfContinuations: ContT[Eval, UserUpdateResult, UserUpdateResult] = FromFn( // runAndThen = Single( -// f = cats.data.ContT$$Lambda$11742/0x00007f1a8bfff618@3360584, +// f = cats.data.ContT$$Lambda$11949/0x00007fe490029310@24efeab2, // index = 0 // ) // ) @@ -381,7 +381,7 @@

finalResult } } -// eval: Eval[UserUpdateResult] = cats.Eval$$anon$5@6e0422de +// eval: Eval[UserUpdateResult] = cats.Eval$$anon$5@284d6da0 eval.value // Updated user model diff --git a/datatypes/eval.html b/datatypes/eval.html index 4fae2ed07b..b69f239b3b 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@14a67d74 +// lazyEval: Eval[Int] = cats.Later@2204d64b lazyEval.value // Running expensive calculation... @@ -276,7 +276,7 @@

println("Running expensive calculation...") 1 + 2 * 3 } -// always: Eval[Int] = cats.Always@603ff3da +// always: Eval[Int] = cats.Always@56abca38 always.value // Running expensive calculation... diff --git a/datatypes/freeapplicative.html b/datatypes/freeapplicative.html index 3769224702..97b8479637 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$11900/0x00007f1a8b7c43d0@5eedf3da
+// validator: FromString[Boolean] = cats.instances.Function1Instances$$anon$7$$Lambda$12107/0x00007fe48f5554f8@5497be6f
 validator("1234")
 // res0: Boolean = false
 validator("12345")
diff --git a/datatypes/freemonad.html b/datatypes/freemonad.html
index 796a607cc5..58682cbc5d 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@120fdea7 +// state: TeletypeState[Unit] = cats.data.IndexedStateT@4e2ec36f 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 250e2c6c77..5d1527d78f 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@5d463c3f

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

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@1436a3d5

+// res6: Eval[(Open.type, Unit)] = cats.Eval$$anon$1@77720b1d diff --git a/typeclasses/bifoldable.html b/typeclasses/bifoldable.html index 511a562141..5b389b350b 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@15b37347 +// right: Eval[String] = cats.Eval$$anon$1@faea376 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@624f57f9 +// reversedRight: Eval[String] = cats.Eval$$anon$1@4f53ef9f reversedRight.value === expected // res4: Boolean = false diff --git a/typeclasses/bifunctor.html b/typeclasses/bifunctor.html index dcb9b12b17..da4ba858fb 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 = 1730657387L) +// res0: Either[DomainError, Long] = Right(value = 1730734773L)

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 ad24d6bafe..ee3b9cf663 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@6b463cca +// nelBimonad: Bimonad[NonEmptyList] = repl.MdocSession$MdocApp$$anon$1@3552e98d

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 099e059051..80b7473847 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$12696/0x00007f1a8c2bd670@653c8fd6 +// showSalary: Show[Salary] = cats.Show$$anon$2$$Lambda$12903/0x00007fe4902e5210@32b3dfdd 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@7eea9e18 +// moneyOrdering: Ordering[Money] = scala.math.Ordering$$anon$5@2529aaa7 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@7ee06192 +// b: B = repl.MdocSession$MdocApp$B@59cb2024 val a: A = b -// a: A = repl.MdocSession$MdocApp$B@7ee06192 +// a: A = repl.MdocSession$MdocApp$B@59cb2024 val showA: Show[A] = Show.show(a => "a!") -// showA: Show[A] = cats.Show$$$Lambda$12695/0x00007f1a8c2bd1f8@56cfb232 +// showA: Show[A] = cats.Show$$$Lambda$12902/0x00007fe4902e4d98@164ec8b7 val showB1: Show[B] = showA.contramap(b => b: A) -// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12696/0x00007f1a8c2bd670@409e9633 +// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12903/0x00007fe4902e5210@5d33aaed val showB2: Show[B] = showA.contramap(identity[A]) -// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12696/0x00007f1a8c2bd670@2f3975d2 +// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12903/0x00007fe4902e5210@6c91a070 val showB3: Show[B] = Contravariant[Show].narrow[A, B](showA) -// showB3: Show[B] = cats.Show$$$Lambda$12695/0x00007f1a8c2bd1f8@56cfb232 +// showB3: Show[B] = cats.Show$$$Lambda$12902/0x00007fe4902e4d98@164ec8b7

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 12e8c877ae..02c0369fa4 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@3aaadd14 +// eqFoo: Eq[Foo] = cats.kernel.Eq$$anonfun$fromUniversalEquals$2@5cd5262f Foo(10, "") === Foo(10, "") diff --git a/typeclasses/semigroup.html b/typeclasses/semigroup.html index d0f45d27e5..3e8f024caf 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@1e4e672e
+// res8: Semigroup[Int] = cats.kernel.instances.IntGroup@5fec5a6c
 Semigroup[String]
-// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@38bc8ffc
+// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@24182647

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@4f84f3da
+// res10: Semigroup[List[Byte]] = cats.kernel.instances.ListMonoid@e676cec
 Semigroup[Set[Int]]
-// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@123d2470
+// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@67513b8e
 
 trait Foo
 Semigroup[List[Foo]]
-// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@4f84f3da
+// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@e676cec

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

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 f065fa231f..fec3be6fa8 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@6fe271b8"
+// res0: String = "repl.MdocSession$MdocApp$$anon$1@6048f16e"

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$12695/0x00007f1a8c2bd1f8@1f9961ee +// showPerson: Show[Person] = cats.Show$$$Lambda$12902/0x00007fe4902e4d98@4bc47dde case class Department(id: Int, name: String) implicit val showDep: Show[Department] = Show.fromToString -// showDep: Show[Department] = cats.Show$$$Lambda$11733/0x00007f1a8bfc7db8@1b00cf36 +// showDep: Show[Department] = cats.Show$$$Lambda$11940/0x00007fe48fff18d0@14a5e337

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.