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

ContT

Succeeded(user.id) } } -// eval: Eval[UserUpdateResult] = cats.Later@5154051a +// eval: Eval[UserUpdateResult] = cats.Later@1cebf4fa

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$11759/0x00007f2099fff238@614d7b6a, +// f = cats.data.ContT$$Lambda$14320/0x00007f42e4655a68@6096e9d6, // index = 0 // ) // ) @@ -319,7 +319,7 @@

Succeeded(userFields("id").toInt) } } -// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@2d23bb9e +// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@1795c4ec 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$11759/0x00007f2099fff238@168d3d85, +// f = cats.data.ContT$$Lambda$14320/0x00007f42e4655a68@54d4cb92, // index = 0 // ) // ) @@ -370,7 +370,7 @@

updateUserModel flatMap persistToDb flatMap publishEvent // chainOfContinuations: ContT[Eval, UserUpdateResult, UserUpdateResult] = FromFn( // runAndThen = Single( -// f = cats.data.ContT$$Lambda$11763/0x00007f2099fffbc0@ad185b5, +// f = cats.data.ContT$$Lambda$14324/0x00007f42e46563f0@18683977, // index = 0 // ) // ) @@ -381,7 +381,7 @@

finalResult } } -// eval: Eval[UserUpdateResult] = cats.Eval$$anon$5@3c96864a +// eval: Eval[UserUpdateResult] = cats.Eval$$anon$5@770b19ba eval.value // Updated user model diff --git a/datatypes/eval.html b/datatypes/eval.html index ac529c9dd1..fcd9468e9f 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@5df61db5 +// lazyEval: Eval[Int] = cats.Later@1bb13422 lazyEval.value // Running expensive calculation... @@ -276,7 +276,7 @@

println("Running expensive calculation...") 1 + 2 * 3 } -// always: Eval[Int] = cats.Always@29a60311 +// always: Eval[Int] = cats.Always@6fa72320 always.value // Running expensive calculation... diff --git a/datatypes/freeapplicative.html b/datatypes/freeapplicative.html index 52bf120daa..ff62e78347 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$11921/0x00007f209979ebe0@6022ffbb
+// validator: FromString[Boolean] = cats.instances.Function1Instances$$anon$7$$Lambda$14482/0x00007f42e46d2000@4d94e091
 validator("1234")
 // res0: Boolean = false
 validator("12345")
diff --git a/datatypes/freemonad.html b/datatypes/freemonad.html
index d8c599a8e7..b95d2f01b8 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@5fad5968 +// state: TeletypeState[Unit] = cats.data.IndexedStateT@4ba7f240 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 14e8b5fff9..a30caf272b 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@4d48b22e

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

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@1a7aaab2

+// res6: Eval[(Open.type, Unit)] = cats.Eval$$anon$1@4c8cfc12 diff --git a/typeclasses/bifoldable.html b/typeclasses/bifoldable.html index 6351961b7a..7032c5a548 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@1497afb6 +// right: Eval[String] = cats.Eval$$anon$1@74c58b4d 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@69cd570e +// reversedRight: Eval[String] = cats.Eval$$anon$1@7fce4ec9 reversedRight.value === expected // res4: Boolean = false diff --git a/typeclasses/bifunctor.html b/typeclasses/bifunctor.html index eab69cc221..72f0bbdd4f 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 = 1729832823L) +// res0: Either[DomainError, Long] = Right(value = 1730181034L)

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 bc25ec469c..f57e51690f 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@44611e7a +// nelBimonad: Bimonad[NonEmptyList] = repl.MdocSession$MdocApp$$anon$1@159bd5f9

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 569070dc4b..e3a8cd3769 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$12717/0x00007f209a2ccc38@1c4e0cdb +// showSalary: Show[Salary] = cats.Show$$anon$2$$Lambda$15278/0x00007f42e49aab60@308e68cd 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@706e9f9d +// moneyOrdering: Ordering[Money] = scala.math.Ordering$$anon$5@22010a55 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@1f337f23 +// b: B = repl.MdocSession$MdocApp$B@654131ec val a: A = b -// a: A = repl.MdocSession$MdocApp$B@1f337f23 +// a: A = repl.MdocSession$MdocApp$B@654131ec val showA: Show[A] = Show.show(a => "a!") -// showA: Show[A] = cats.Show$$$Lambda$12716/0x00007f209a2cc7c0@2c88865a +// showA: Show[A] = cats.Show$$$Lambda$15277/0x00007f42e49aa6e8@f789c2 val showB1: Show[B] = showA.contramap(b => b: A) -// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12717/0x00007f209a2ccc38@1e5e44bf +// showB1: Show[B] = cats.Show$$anon$2$$Lambda$15278/0x00007f42e49aab60@6641955f val showB2: Show[B] = showA.contramap(identity[A]) -// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12717/0x00007f209a2ccc38@4dc362ad +// showB2: Show[B] = cats.Show$$anon$2$$Lambda$15278/0x00007f42e49aab60@3bfc2008 val showB3: Show[B] = Contravariant[Show].narrow[A, B](showA) -// showB3: Show[B] = cats.Show$$$Lambda$12716/0x00007f209a2cc7c0@2c88865a +// showB3: Show[B] = cats.Show$$$Lambda$15277/0x00007f42e49aa6e8@f789c2

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 e82f4e4c76..d038a41f3c 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@249ef2da +// eqFoo: Eq[Foo] = cats.kernel.Eq$$anonfun$fromUniversalEquals$2@64ac6b96 Foo(10, "") === Foo(10, "") diff --git a/typeclasses/semigroup.html b/typeclasses/semigroup.html index 603438939d..ce3d89b392 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@1d038f98
+// res8: Semigroup[Int] = cats.kernel.instances.IntGroup@7057800c
 Semigroup[String]
-// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@4da04d1a
+// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@718aad6

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@4cca5e87
+// res10: Semigroup[List[Byte]] = cats.kernel.instances.ListMonoid@21f31d7c
 Semigroup[Set[Int]]
-// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@18dd41a6
+// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@120b5c8f
 
 trait Foo
 Semigroup[List[Foo]]
-// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@4cca5e87
+// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@21f31d7c

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

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 e67bb1aeec..1377fb7575 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@219de668"
+// res0: String = "repl.MdocSession$MdocApp$$anon$1@7e8ee579"

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$12716/0x00007f209a2cc7c0@639520f9 +// showPerson: Show[Person] = cats.Show$$$Lambda$15277/0x00007f42e49aa6e8@7bcaa372 case class Department(id: Int, name: String) implicit val showDep: Show[Department] = Show.fromToString -// showDep: Show[Department] = cats.Show$$$Lambda$11754/0x00007f2099fc8400@553178d9 +// showDep: Show[Department] = cats.Show$$$Lambda$14315/0x00007f42e461edb8@afdbc2a

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.