diff --git a/datatypes/chain.html b/datatypes/chain.html index 78d34dbb03..c0b17dd5fd 100644 --- a/datatypes/chain.html +++ b/datatypes/chain.html @@ -227,7 +227,7 @@

Chain

API Documentation: Chain

Chain is an immutable sequence data structure that allows constant time prepending, appending and concatenation. This makes it especially efficient when used as a Monoid, e.g. with Validated or Writer. - As such it aims to be used where List and Vector incur a performance penalty. + As such it aims to be used where List and Vector incur a performance penalty. Cats also includes type class implementations to support using Chain as a general-purpose collection type, including Traverse, Monad, and Alternative.

Motivation

@@ -238,7 +238,7 @@

NonEmptyList semigroup), which by the nature of List is very inefficient. If you use traverse with a data structure with n elements and Writer or Validated as the Applicative type, you will end up with a runtime of O(n^2). This is because, with List, appending a single element requires iterating over the entire data structure and therefore takes linear time.

-

So List isn't all that great for this use case, so let's use Vector or NonEmptyVector` instead, right?

+

So List isn't all that great for this use case, so let's use Vector or NonEmptyVector` instead, right?

Well, Vector has its own problems and in this case it's unfortunately not that much faster than List at all. You can check this blog post by Li Haoyi for some deeper insight into Vector's issues.

Chain evolved from what used to be fs2.Catenable and Erik Osheim's Chain library. Similar to List, it is also a very simple data structure, but unlike List it supports constant O(1) time append, prepend and concat. @@ -265,7 +265,7 @@

NonEmptyChain.one(1) // res3: NonEmptyChain[Int] = Singleton(a = 1) -

You can also create an Option of NonEmptyChain from a Chain or any other collection type:

+

You can also create an Option of NonEmptyChain from a Chain or any other collection type:

import cats.data._
 
 NonEmptyChain.fromChain(Chain(1, 2, 3))
@@ -294,7 +294,7 @@ 

How it works

Chain is implemented as a simple unbalanced binary tree ADT with four cases: - an empty Chain with no elements, a singleton Chain with exactly one element, a concatenation of two chains, or a wrapper for a Seq.

+ an empty Chain with no elements, a singleton Chain with exactly one element, a concatenation of two chains, or a wrapper for a Seq.

In code it looks like this:

sealed abstract class Chain[+A]
 
diff --git a/datatypes/contt.html b/datatypes/contt.html
index 81a22c400c..d01aa94f56 100644
--- a/datatypes/contt.html
+++ b/datatypes/contt.html
@@ -286,7 +286,7 @@ 

ContT

Succeeded(user.id) } } -// eval: Eval[UserUpdateResult] = cats.Later@7cb3b8c6
+
// eval: Eval[UserUpdateResult] = cats.Later@37f9fc82

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$11729/0x00007fea8bfe5a60@5c1c43e3, +// f = cats.data.ContT$$Lambda$11795/0x00007f12bbff4168@7de4c77e, // index = 0 // ) // ) @@ -319,7 +319,7 @@

Succeeded(userFields("id").toInt) } } -// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@447e5453 +// anotherEval: Eval[UserUpdateResult] = cats.Eval$$anon$5@1ab22e3a 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$11729/0x00007fea8bfe5a60@33d5c760, +// f = cats.data.ContT$$Lambda$11795/0x00007f12bbff4168@141cb51c, // index = 0 // ) // ) @@ -370,7 +370,7 @@

updateUserModel flatMap persistToDb flatMap publishEvent // chainOfContinuations: ContT[Eval, UserUpdateResult, UserUpdateResult] = FromFn( // runAndThen = Single( -// f = cats.data.ContT$$Lambda$11733/0x00007fea8bfe63e8@2c435e49, +// f = cats.data.ContT$$Lambda$11799/0x00007f12bbff4af0@3c9a479e, // index = 0 // ) // ) @@ -381,7 +381,7 @@

finalResult } } -// eval: Eval[UserUpdateResult] = cats.Eval$$anon$5@3a9f357e +// eval: Eval[UserUpdateResult] = cats.Eval$$anon$5@14c7a16a eval.value // Updated user model diff --git a/datatypes/eval.html b/datatypes/eval.html index f4e82b143e..9444c2f86f 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@504049c6 +// lazyEval: Eval[Int] = cats.Later@45f10304 lazyEval.value // Running expensive calculation... @@ -276,7 +276,7 @@

println("Running expensive calculation...") 1 + 2 * 3 } -// always: Eval[Int] = cats.Always@241dfd26 +// always: Eval[Int] = cats.Always@313991b9 always.value // Running expensive calculation... diff --git a/datatypes/freeapplicative.html b/datatypes/freeapplicative.html index 5be77e9223..52b8a3e2f7 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$11891/0x00007fea8bd4f958@474dc89
+// validator: FromString[Boolean] = cats.instances.Function1Instances$$anon$7$$Lambda$11957/0x00007f12bb7b3648@182071b
 validator("1234")
 // res0: Boolean = false
 validator("12345")
diff --git a/datatypes/freemonad.html b/datatypes/freemonad.html
index ff77091295..41292513d5 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@17bc7a6 +// state: TeletypeState[Unit] = cats.data.IndexedStateT@373c878c 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 f50ab2e9f3..a61853cc54 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@33ebe944

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

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@4fed8034

+// res6: Eval[(Open.type, Unit)] = cats.Eval$$anon$1@25b7b00a diff --git a/typeclasses/bifoldable.html b/typeclasses/bifoldable.html index 14976092f4..16ed4380d6 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@51a80682 +// right: Eval[String] = cats.Eval$$anon$1@159db2c6 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@440c495a +// reversedRight: Eval[String] = cats.Eval$$anon$1@50702bcd reversedRight.value === expected // res4: Boolean = false diff --git a/typeclasses/bifunctor.html b/typeclasses/bifunctor.html index bc1e2c994d..7cb09914b2 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 = 1727292880L) +// res0: Either[DomainError, Long] = Right(value = 1727331748L)

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 925349979b..ef5a7eddab 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@4f557406 +// nelBimonad: Bimonad[NonEmptyList] = repl.MdocSession$MdocApp$$anon$1@4fc3b945

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 d4ed09c16e..768f0d4267 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$12681/0x00007fea8c29f438@6a887c18 +// showSalary: Show[Salary] = cats.Show$$anon$2$$Lambda$12747/0x00007f12bc2d4478@1b05484f 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@25ac4f2b +// moneyOrdering: Ordering[Money] = scala.math.Ordering$$anon$5@50d68ade 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@4728e975 +// b: B = repl.MdocSession$MdocApp$B@7556071 val a: A = b -// a: A = repl.MdocSession$MdocApp$B@4728e975 +// a: A = repl.MdocSession$MdocApp$B@7556071 val showA: Show[A] = Show.show(a => "a!") -// showA: Show[A] = cats.Show$$$Lambda$12680/0x00007fea8c29efc0@16ad3e38 +// showA: Show[A] = cats.Show$$$Lambda$12746/0x00007f12bc2d4000@443b308d val showB1: Show[B] = showA.contramap(b => b: A) -// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12681/0x00007fea8c29f438@70d097ed +// showB1: Show[B] = cats.Show$$anon$2$$Lambda$12747/0x00007f12bc2d4478@6cdd14c9 val showB2: Show[B] = showA.contramap(identity[A]) -// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12681/0x00007fea8c29f438@1acb64e7 +// showB2: Show[B] = cats.Show$$anon$2$$Lambda$12747/0x00007f12bc2d4478@3fd16a06 val showB3: Show[B] = Contravariant[Show].narrow[A, B](showA) -// showB3: Show[B] = cats.Show$$$Lambda$12680/0x00007fea8c29efc0@16ad3e38 +// showB3: Show[B] = cats.Show$$$Lambda$12746/0x00007f12bc2d4000@443b308d

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 bf0b61dcdb..fb9e59f63a 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@2d3c1d81 +// eqFoo: Eq[Foo] = cats.kernel.Eq$$anonfun$fromUniversalEquals$2@71d0a21b Foo(10, "") === Foo(10, "") diff --git a/typeclasses/semigroup.html b/typeclasses/semigroup.html index f3d2d15740..9b079d7616 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@66e834c2
+// res8: Semigroup[Int] = cats.kernel.instances.IntGroup@61a01722
 Semigroup[String]
-// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@4f5d61ad
+// res9: Semigroup[String] = cats.kernel.instances.StringMonoid@34bb1b12

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@375a1e12
+// res10: Semigroup[List[Byte]] = cats.kernel.instances.ListMonoid@30957d46
 Semigroup[Set[Int]]
-// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@57c45c59
+// res11: Semigroup[Set[Int]] = cats.kernel.instances.SetSemilattice@22c87c0d
 
 trait Foo
 Semigroup[List[Foo]]
-// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@375a1e12
+// res12: Semigroup[List[Foo]] = cats.kernel.instances.ListMonoid@30957d46

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

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 248277a9e1..22aa46e3a2 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@7b60a068"
+// res0: String = "repl.MdocSession$MdocApp$$anon$1@7805408b"

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$12680/0x00007fea8c29efc0@915edbf +// showPerson: Show[Person] = cats.Show$$$Lambda$12746/0x00007f12bc2d4000@26be9747 case class Department(id: Int, name: String) implicit val showDep: Show[Department] = Show.fromToString -// showDep: Show[Department] = cats.Show$$$Lambda$11724/0x00007fea8bfaedb8@f968a25 +// showDep: Show[Department] = cats.Show$$$Lambda$11790/0x00007f12bbfbd0a8@c709c2f

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.