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

ContT

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

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$11945/0x00007fe490028988@4ae07779, +// f = cats.data.ContT$$Lambda$11837/0x00007f0bdeffe210@16d79f29, // index = 0 // ) // ) @@ -319,7 +319,7 @@

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

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

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

println("Running expensive calculation...") 1 + 2 * 3 } -// always: Eval[Int] = cats.Always@56abca38 +// always: Eval[Int] = cats.Always@5274e805 always.value // Running expensive calculation... diff --git a/datatypes/freeapplicative.html b/datatypes/freeapplicative.html index 97b8479637..650015349c 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$12107/0x00007fe48f5554f8@5497be6f
+// validator: FromString[Boolean] = cats.instances.Function1Instances$$anon$7$$Lambda$11999/0x00007f0bde5ac648@64d3d90c
 validator("1234")
 // res0: Boolean = false
 validator("12345")
diff --git a/datatypes/freemonad.html b/datatypes/freemonad.html
index 58682cbc5d..ec3c5109ae 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@4e2ec36f +// state: TeletypeState[Unit] = cats.data.IndexedStateT@40d9dba7 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 5d1527d78f..78012e10b8 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@78f63297

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

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@77720b1d

+// res6: Eval[(Open.type, Unit)] = cats.Eval$$anon$1@30d3517e diff --git a/typeclasses/bifoldable.html b/typeclasses/bifoldable.html index 5b389b350b..287729512f 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@faea376 +// right: Eval[String] = cats.Eval$$anon$1@164686f 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@4f53ef9f +// reversedRight: Eval[String] = cats.Eval$$anon$1@706e0475 reversedRight.value === expected // res4: Boolean = false diff --git a/typeclasses/bifunctor.html b/typeclasses/bifunctor.html index da4ba858fb..95210ec709 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 = 1730734773L) +// res0: Either[DomainError, Long] = Right(value = 1731273899L)

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

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 80b7473847..895938a8be 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$12903/0x00007fe4902e5210@32b3dfdd +// showSalary: Show[Salary] = cats.Show$$anon$2$$Lambda$12795/0x00007f0bdf2a27b8@5dcf544f 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@2529aaa7 +// moneyOrdering: Ordering[Money] = scala.math.Ordering$$anon$5@37c56c8f 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@59cb2024 +// b: B = repl.MdocSession$MdocApp$B@15ec32c7 val a: A = b -// a: A = repl.MdocSession$MdocApp$B@59cb2024 +// a: A = repl.MdocSession$MdocApp$B@15ec32c7 val showA: Show[A] = Show.show(a => "a!") -// showA: Show[A] = cats.Show$$$Lambda$12902/0x00007fe4902e4d98@164ec8b7 +// showA: Show[A] = cats.Show$$$Lambda$12794/0x00007f0bdf2a2340@647fd997 val showB1: Show[B] = showA.contramap(b => b: A) -// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12903/0x00007fe4902e5210@5d33aaed +// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12795/0x00007f0bdf2a27b8@41b820ac val showB2: Show[B] = showA.contramap(identity[A]) -// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12903/0x00007fe4902e5210@6c91a070 +// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12795/0x00007f0bdf2a27b8@7ff1e10f val showB3: Show[B] = Contravariant[Show].narrow[A, B](showA) -// showB3: Show[B] = cats.Show$$$Lambda$12902/0x00007fe4902e4d98@164ec8b7 +// showB3: Show[B] = cats.Show$$$Lambda$12794/0x00007f0bdf2a2340@647fd997

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 02c0369fa4..1574e3ea7e 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@5cd5262f +// eqFoo: Eq[Foo] = cats.kernel.Eq$$anonfun$fromUniversalEquals$2@70c60b94 Foo(10, "") === Foo(10, "") diff --git a/typeclasses/semigroup.html b/typeclasses/semigroup.html index 3e8f024caf..5e7db59bc5 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@5fec5a6c
+// res8: Semigroup[Int] = cats.kernel.instances.IntGroup@1486fd5
 Semigroup[String]
-// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@24182647
+// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@7058440e

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

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

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 fec3be6fa8..61899bb919 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@6048f16e"
+// res0: String = "repl.MdocSession$MdocApp$$anon$1@2226b8af"

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$12902/0x00007fe4902e4d98@4bc47dde +// showPerson: Show[Person] = cats.Show$$$Lambda$12794/0x00007f0bdf2a2340@39ba559f case class Department(id: Int, name: String) implicit val showDep: Show[Department] = Show.fromToString -// showDep: Show[Department] = cats.Show$$$Lambda$11940/0x00007fe48fff18d0@14a5e337 +// showDep: Show[Department] = cats.Show$$$Lambda$11832/0x00007f0bdefc73b8@56898694

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.