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

ContT

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

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$11837/0x00007f0bdeffe210@16d79f29, +// f = cats.data.ContT$$Lambda$14430/0x00007f6330685398@32a2b5ea, // index = 0 // ) // ) @@ -319,7 +319,7 @@

Succeeded(userFields("id").toInt) } } -// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@7298fc1 +// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@6435b180 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$11837/0x00007f0bdeffe210@7eb39743, +// f = cats.data.ContT$$Lambda$14430/0x00007f6330685398@9a086f1, // index = 0 // ) // ) @@ -370,7 +370,7 @@

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

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

println("Running expensive calculation...") 1 + 2 * 3 } -// always: Eval[Int] = cats.Always@5274e805 +// always: Eval[Int] = cats.Always@6d1e4aaf always.value // Running expensive calculation... diff --git a/datatypes/freeapplicative.html b/datatypes/freeapplicative.html index 650015349c..0bb56e8d0e 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$11999/0x00007f0bde5ac648@64d3d90c
+// validator: FromString[Boolean] = cats.instances.Function1Instances$$anon$7$$Lambda$14592/0x00007f6330747958@2ed270c6
 validator("1234")
 // res0: Boolean = false
 validator("12345")
diff --git a/datatypes/freemonad.html b/datatypes/freemonad.html
index ec3c5109ae..720431e16a 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@40d9dba7 +// state: TeletypeState[Unit] = cats.data.IndexedStateT@654b3f57 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 78012e10b8..ca01c94344 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@4ef11db

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

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@30d3517e

+// res6: Eval[(Open.type, Unit)] = cats.Eval$$anon$1@3549b089 diff --git a/typeclasses/bifoldable.html b/typeclasses/bifoldable.html index 287729512f..61515d607f 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@164686f +// right: Eval[String] = cats.Eval$$anon$1@1e6233e8 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@706e0475 +// reversedRight: Eval[String] = cats.Eval$$anon$1@bd84e09 reversedRight.value === expected // res4: Boolean = false diff --git a/typeclasses/bifunctor.html b/typeclasses/bifunctor.html index 95210ec709..75bf71135b 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 = 1731273899L) +// res0: Either[DomainError, Long] = Right(value = 1731756269L)

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

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 895938a8be..3e87d210f4 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$12795/0x00007f0bdf2a27b8@5dcf544f +// showSalary: Show[Salary] = cats.Show$$anon$2$$Lambda$15388/0x00007f63309f5210@5045fb72 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@37c56c8f +// moneyOrdering: Ordering[Money] = scala.math.Ordering$$anon$5@7da963f1 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@15ec32c7 +// b: B = repl.MdocSession$MdocApp$B@2e6ceb8a val a: A = b -// a: A = repl.MdocSession$MdocApp$B@15ec32c7 +// a: A = repl.MdocSession$MdocApp$B@2e6ceb8a val showA: Show[A] = Show.show(a => "a!") -// showA: Show[A] = cats.Show$$$Lambda$12794/0x00007f0bdf2a2340@647fd997 +// showA: Show[A] = cats.Show$$$Lambda$15387/0x00007f63309f4d98@1abcc77a val showB1: Show[B] = showA.contramap(b => b: A) -// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12795/0x00007f0bdf2a27b8@41b820ac +// showB1: Show[B] = cats.Show$$anon$2$$Lambda$15388/0x00007f63309f5210@394d0914 val showB2: Show[B] = showA.contramap(identity[A]) -// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12795/0x00007f0bdf2a27b8@7ff1e10f +// showB2: Show[B] = cats.Show$$anon$2$$Lambda$15388/0x00007f63309f5210@1ad64254 val showB3: Show[B] = Contravariant[Show].narrow[A, B](showA) -// showB3: Show[B] = cats.Show$$$Lambda$12794/0x00007f0bdf2a2340@647fd997 +// showB3: Show[B] = cats.Show$$$Lambda$15387/0x00007f63309f4d98@1abcc77a

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 1574e3ea7e..867a057180 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@70c60b94 +// eqFoo: Eq[Foo] = cats.kernel.Eq$$anonfun$fromUniversalEquals$2@6a23956e Foo(10, "") === Foo(10, "") diff --git a/typeclasses/semigroup.html b/typeclasses/semigroup.html index 5e7db59bc5..32514aa9a8 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@1486fd5
+// res8: Semigroup[Int] = cats.kernel.instances.IntGroup@68cad8c3
 Semigroup[String]
-// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@7058440e
+// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@290266b0

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

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

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

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$12794/0x00007f0bdf2a2340@39ba559f +// showPerson: Show[Person] = cats.Show$$$Lambda$15387/0x00007f63309f4d98@51e64d28 case class Department(id: Int, name: String) implicit val showDep: Show[Department] = Show.fromToString -// showDep: Show[Department] = cats.Show$$$Lambda$11832/0x00007f0bdefc73b8@56898694 +// showDep: Show[Department] = cats.Show$$$Lambda$14425/0x00007f633064e6a8@1f0d0c52

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.