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

ContT

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

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$11924/0x00007f05f300ddf0@43572fe5, +// f = cats.data.ContT$$Lambda$11759/0x00007f2099fff238@614d7b6a, // index = 0 // ) // ) @@ -319,7 +319,7 @@

Succeeded(userFields("id").toInt) } } -// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@278f100d +// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@2d23bb9e 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$11924/0x00007f05f300ddf0@1151da2f, +// f = cats.data.ContT$$Lambda$11759/0x00007f2099fff238@168d3d85, // index = 0 // ) // ) @@ -370,7 +370,7 @@

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

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

println("Running expensive calculation...") 1 + 2 * 3 } -// always: Eval[Int] = cats.Always@472efa01 +// always: Eval[Int] = cats.Always@29a60311 always.value // Running expensive calculation... diff --git a/datatypes/freeapplicative.html b/datatypes/freeapplicative.html index 81f2d35de3..52bf120daa 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$12086/0x00007f05f2654be0@667d07c7
+// validator: FromString[Boolean] = cats.instances.Function1Instances$$anon$7$$Lambda$11921/0x00007f209979ebe0@6022ffbb
 validator("1234")
 // res0: Boolean = false
 validator("12345")
diff --git a/datatypes/freemonad.html b/datatypes/freemonad.html
index 8fc548f350..d8c599a8e7 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@4e3e9dae +// state: TeletypeState[Unit] = cats.data.IndexedStateT@5fad5968 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 cd488dcd9b..14e8b5fff9 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@45e87c39

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

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@52d1ea18

+// res6: Eval[(Open.type, Unit)] = cats.Eval$$anon$1@1a7aaab2 diff --git a/typeclasses/bifoldable.html b/typeclasses/bifoldable.html index fd853e9cea..6351961b7a 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@3f676d63 +// right: Eval[String] = cats.Eval$$anon$1@1497afb6 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@43455278 +// reversedRight: Eval[String] = cats.Eval$$anon$1@69cd570e reversedRight.value === expected // res4: Boolean = false diff --git a/typeclasses/bifunctor.html b/typeclasses/bifunctor.html index c51107e593..eab69cc221 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 = 1729610415L) +// res0: Either[DomainError, Long] = Right(value = 1729832823L)

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

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 edc497e62a..569070dc4b 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$12882/0x00007f05f330c240@52612d15 +// showSalary: Show[Salary] = cats.Show$$anon$2$$Lambda$12717/0x00007f209a2ccc38@1c4e0cdb 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@6534f2b3 +// moneyOrdering: Ordering[Money] = scala.math.Ordering$$anon$5@706e9f9d 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@6e740931 +// b: B = repl.MdocSession$MdocApp$B@1f337f23 val a: A = b -// a: A = repl.MdocSession$MdocApp$B@6e740931 +// a: A = repl.MdocSession$MdocApp$B@1f337f23 val showA: Show[A] = Show.show(a => "a!") -// showA: Show[A] = cats.Show$$$Lambda$12881/0x00007f05f32d7d50@321554a7 +// showA: Show[A] = cats.Show$$$Lambda$12716/0x00007f209a2cc7c0@2c88865a val showB1: Show[B] = showA.contramap(b => b: A) -// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12882/0x00007f05f330c240@119a933a +// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12717/0x00007f209a2ccc38@1e5e44bf val showB2: Show[B] = showA.contramap(identity[A]) -// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12882/0x00007f05f330c240@5b9c138c +// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12717/0x00007f209a2ccc38@4dc362ad val showB3: Show[B] = Contravariant[Show].narrow[A, B](showA) -// showB3: Show[B] = cats.Show$$$Lambda$12881/0x00007f05f32d7d50@321554a7 +// showB3: Show[B] = cats.Show$$$Lambda$12716/0x00007f209a2cc7c0@2c88865a

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 a94e5d4f56..e82f4e4c76 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@7f468ee +// eqFoo: Eq[Foo] = cats.kernel.Eq$$anonfun$fromUniversalEquals$2@249ef2da Foo(10, "") === Foo(10, "") diff --git a/typeclasses/semigroup.html b/typeclasses/semigroup.html index 0c38912a78..603438939d 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@3dc57f8b
+// res8: Semigroup[Int] = cats.kernel.instances.IntGroup@1d038f98
 Semigroup[String]
-// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@7c072320
+// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@4da04d1a

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

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

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 45cd7f9a86..e67bb1aeec 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@4ac5002c"
+// res0: String = "repl.MdocSession$MdocApp$$anon$1@219de668"

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$12881/0x00007f05f32d7d50@248b6a3f +// showPerson: Show[Person] = cats.Show$$$Lambda$12716/0x00007f209a2cc7c0@639520f9 case class Department(id: Int, name: String) implicit val showDep: Show[Department] = Show.fromToString -// showDep: Show[Department] = cats.Show$$$Lambda$11919/0x00007f05f2fd6fb8@3e822850 +// showDep: Show[Department] = cats.Show$$$Lambda$11754/0x00007f2099fc8400@553178d9

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.