diff --git a/datatypes/contt.html b/datatypes/contt.html index 8446f981d1..edbd6b859a 100644 --- a/datatypes/contt.html +++ b/datatypes/contt.html @@ -286,7 +286,7 @@

ContT

Succeeded(user.id) } } -// eval: Eval[UserUpdateResult] = cats.Later@4d72ebac +// eval: Eval[UserUpdateResult] = cats.Later@7e524cde

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$11807/0x00007f1b6b001f80@2d49d1b8, +// f = cats.data.ContT$$Lambda$11825/0x00007f46ea005df0@5db6f4f6, // index = 0 // ) // ) @@ -319,7 +319,7 @@

Succeeded(userFields("id").toInt) } } -// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@7d7a9d06 +// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@1b3c0be3 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$11807/0x00007f1b6b001f80@4e313f80, +// f = cats.data.ContT$$Lambda$11825/0x00007f46ea005df0@7ba271eb, // index = 0 // ) // ) @@ -370,7 +370,7 @@

updateUserModel flatMap persistToDb flatMap publishEvent // chainOfContinuations: ContT[Eval, UserUpdateResult, UserUpdateResult] = FromFn( // runAndThen = Single( -// f = cats.data.ContT$$Lambda$11811/0x00007f1b6b002908@72bd7a03, +// f = cats.data.ContT$$Lambda$11829/0x00007f46ea006778@10168e1e, // index = 0 // ) // ) @@ -381,7 +381,7 @@

finalResult } } -// eval: Eval[UserUpdateResult] = cats.Eval$$anon$5@641d08e3 +// eval: Eval[UserUpdateResult] = cats.Eval$$anon$5@78b94ce3 eval.value // Updated user model diff --git a/datatypes/eval.html b/datatypes/eval.html index 44fa4759e2..ac11e6391d 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@49a117d0 +// lazyEval: Eval[Int] = cats.Later@53a77e1f lazyEval.value // Running expensive calculation... @@ -276,7 +276,7 @@

println("Running expensive calculation...") 1 + 2 * 3 } -// always: Eval[Int] = cats.Always@3de558b3 +// always: Eval[Int] = cats.Always@2779be53 always.value // Running expensive calculation... diff --git a/datatypes/freeapplicative.html b/datatypes/freeapplicative.html index 9b968e842d..8d22936bfe 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$11969/0x00007f1b6a5aaa80@66356aa6
+// validator: FromString[Boolean] = cats.instances.Function1Instances$$anon$7$$Lambda$11987/0x00007f46e95a8be0@3b7af86e
 validator("1234")
 // res0: Boolean = false
 validator("12345")
diff --git a/datatypes/freemonad.html b/datatypes/freemonad.html
index 75b42bc4f4..d8a8638d2e 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@3c822ae0 +// state: TeletypeState[Unit] = cats.data.IndexedStateT@6e7b55d0 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 7b870cbfcc..749a8b1a60 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@63c54fde

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

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@2df3e226

+// res6: Eval[(Open.type, Unit)] = cats.Eval$$anon$1@40f07c0f diff --git a/typeclasses/bifoldable.html b/typeclasses/bifoldable.html index a9513d7b20..ee27d3114d 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@54e4771 +// right: Eval[String] = cats.Eval$$anon$1@7d0b493a 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@10f68a17 +// reversedRight: Eval[String] = cats.Eval$$anon$1@720a6672 reversedRight.value === expected // res4: Boolean = false diff --git a/typeclasses/bifunctor.html b/typeclasses/bifunctor.html index b543b63110..bfb6dcc1b3 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 = 1735031886L) +// res0: Either[DomainError, Long] = Right(value = 1735072256L)

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 a79c59737b..b64aefe65c 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@6920793f +// nelBimonad: Bimonad[NonEmptyList] = repl.MdocSession$MdocApp$$anon$1@c8beb

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 a36ebb6da0..f146273c08 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$12765/0x00007f1b6b2aa7b8@1377ea13 +// showSalary: Show[Salary] = cats.Show$$anon$2$$Lambda$12783/0x00007f46ea2e4478@330d18b2 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@366020d5 +// moneyOrdering: Ordering[Money] = scala.math.Ordering$$anon$5@7879e2a 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@3b62ba6d +// b: B = repl.MdocSession$MdocApp$B@d65f7a val a: A = b -// a: A = repl.MdocSession$MdocApp$B@3b62ba6d +// a: A = repl.MdocSession$MdocApp$B@d65f7a val showA: Show[A] = Show.show(a => "a!") -// showA: Show[A] = cats.Show$$$Lambda$12764/0x00007f1b6b2aa340@3fa9b38 +// showA: Show[A] = cats.Show$$$Lambda$12782/0x00007f46ea2e4000@56945182 val showB1: Show[B] = showA.contramap(b => b: A) -// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12765/0x00007f1b6b2aa7b8@ba61356 +// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12783/0x00007f46ea2e4478@5aec17c0 val showB2: Show[B] = showA.contramap(identity[A]) -// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12765/0x00007f1b6b2aa7b8@686b0ba6 +// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12783/0x00007f46ea2e4478@57689f85 val showB3: Show[B] = Contravariant[Show].narrow[A, B](showA) -// showB3: Show[B] = cats.Show$$$Lambda$12764/0x00007f1b6b2aa340@3fa9b38 +// showB3: Show[B] = cats.Show$$$Lambda$12782/0x00007f46ea2e4000@56945182

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 84d26d29d2..ec5a17ccd0 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@6206ea8f +// eqFoo: Eq[Foo] = cats.kernel.Eq$$anonfun$fromUniversalEquals$2@1669afd0 Foo(10, "") === Foo(10, "") diff --git a/typeclasses/semigroup.html b/typeclasses/semigroup.html index fb840c1850..27a8dc35ce 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@1451b959
+// res8: Semigroup[Int] = cats.kernel.instances.IntGroup@2d8bec65
 Semigroup[String]
-// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@169512f8
+// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@aca3044

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@45912278
+// res10: Semigroup[List[Byte]] = cats.kernel.instances.ListMonoid@7c72ad2f
 Semigroup[Set[Int]]
-// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@2a2f5352
+// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@38470391
 
 trait Foo
 Semigroup[List[Foo]]
-// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@45912278
+// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@7c72ad2f

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

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 170f339eb1..ed38feb2a9 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@342d8331"
+// res0: String = "repl.MdocSession$MdocApp$$anon$1@1df789b1"

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$12764/0x00007f1b6b2aa340@60297254 +// showPerson: Show[Person] = cats.Show$$$Lambda$12782/0x00007f46ea2e4000@3004fc5e case class Department(id: Int, name: String) implicit val showDep: Show[Department] = Show.fromToString -// showDep: Show[Department] = cats.Show$$$Lambda$11802/0x00007f1b6afcb0a8@4094aaf3 +// showDep: Show[Department] = cats.Show$$$Lambda$11820/0x00007f46e9fcefb8@69e7de80

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.