Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some changes to glossary. #2636

Merged
merged 2 commits into from
Dec 3, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 55 additions & 47 deletions docs/src/main/tut/nomenclature.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,14 @@ position: 60
> - To discard the first value and keep only the first effect, is it `<*` or `*>`?
> - How do I make a computation `F[A]` fail by checking a condition on the value?

This page contains a catalogue of the major functions, type classes, and types aliases within the `cats` library. This catalogue serves, on one hand, as a bird's-eye view of the capabilities of each class. It is also intended as a go-to page for any `cats`-using developer, who may not remember the answer to any of the questions above.

Those looking for a printable version may want to check out the [cats-cheatsheet](https://arosien.github.io/cats-cheatsheets/typeclasses.pdf) file.
This is a catalogue of the major functions, type classes, and data types in `cats`. It serves as a bird's-eye view of each class capabilities. It is also intended as a go-to reference for `cats` users, who may not recall the answer to questions like the ones above.

#### Simplifications
The signatures and type-classes have been simplified, are described [below](#simplifications). If you want a printable version, you can also check out this [cats-cheatsheet](https://arosien.github.io/cats-cheatsheets/typeclasses.pdf).

Because `cats` is a library for Scala, and because Scala has many more knobs and switches, the actual definitions and implementations of some functions in the library can seem a bit too obfuscated at first sight. To alleviate this, in this glossary we focus on the plain type signatures of the method, and ignore many of the details from Scala. In particular, in our type signatures:
_WARNING_: this page is written manually, and not automatically generated, so many things may be missing. If you find a mistake, or addition, please submit a PR following the guidelines below.

- We use `A,B,C` for type variables of kind `*`, and `F, G, H` for type variables of a higher kind.
- We write type signatures in currified form: parameters are taken one at a time, and they are separated with the arrow `=>` operation. In Scala, a method's parameters may be split in several comma-separated lists.
- We do not differentiate between methods from the type-class trait (e.g. `trait Functor`), or the companion object, or the syntax companion (`implicit class`).
- For functions defined as method of the typeclass' trait, we ignore the receiver object.
- We ignore the implicit parameters. When a function requires another type-class constraint which is not the one in the section, we add the constraints on the side.
- In the parameters, we do not differentiate `Function` from `PartialFunction`. Instead, we use the arrow symbol `A => B` for both, and add a note if it is a `PartialFunction`.
- Some functions are defined through the [Partially Applied Type Params](http://typelevel.org/cats/guidelines.html#partially-applied-type-params) pattern. We ignore this.
- We ignore the distinction between by-name and by-value input parameters, so we just use the type for both. We use the notation `=> A`, without any parameters, to indicate constant functions.
- We ignore Scala variance annotations. We also ignore extra type parameters, which in some methods are added with a subtype-constraint, (e.g. `B >: A`). These are usually meant for flexibility, but we replace each one by its bound.

## Type-Classes of Kind `* -> *`
## Type-Classes over an `F[_]`

### Functor

Expand All @@ -36,6 +25,7 @@ Because `cats` is a library for Scala, and because Scala has many more knobs and
| `F[A] => F[Unit]` | `void` |
| `F[A] => B => F[B]` | `as` |
| `F[A] => (A => B) => F[B]` | `map` |
| `F[A] => (A => B) => F[(A,B)]` | `fproduct` |
| `F[A] => B => F[(B, A)]` | `tupleLeft` |
| `F[A] => B => F[(A, B)]` | `tupleRight` |
| `(A => B) => (F[A] => F[B])` | `lift` |
Expand All @@ -44,10 +34,11 @@ Because `cats` is a library for Scala, and because Scala has many more knobs and

| Type | Method Name | Symbol |
| ------------- |--------------|------------|
| `F[A] => F[A] => F[A]` | `productL` | `<*`
| `F[A] => F[B] => F[A]` | `productL` | `<*`
| `F[A] => F[B] => F[B]` | `productR` | `*>`
| `F[A] => F[B] => F[(A,B)]` | `product` |
| `F[A => B] => F[A] => F[B]` | `ap` | `<*>`
| `F[A => B => C] => F[A] => F[B] => F[C]` | `ap2` |
| `F[A] => F[B] => (A => B => C) => F[C]` | `map2` |

### Applicative
Expand All @@ -59,7 +50,7 @@ Because `cats` is a library for Scala, and because Scala has many more knobs and
| `Boolean => F[Unit] => F[Unit]` | `when` | Performs effect iff condition is true
| | `unless` | Adds effect iff condition is false

### FlatMap / Monad
### FlatMap

| Type | Method Name |
| ------------- |---------------|
Expand All @@ -69,7 +60,6 @@ Because `cats` is a library for Scala, and because Scala has many more knobs and
| `F[Boolean] => F[A] => F[A] => F[A]` | `ifM`
| `F[A] => (A => F[B]) => F[A]` | `flatTap`


### FunctorFilter

| Type | Method Name | Notes |
Expand All @@ -80,7 +70,7 @@ Because `cats` is a library for Scala, and because Scala has many more knobs and
| `F[Option[A]] => F[A]` | `flattenOption` |


### `ApplicativeError[E, F]`
### ApplicativeError

The source code of `cats` uses the `E` type variable for the error type.

Expand All @@ -96,7 +86,9 @@ The source code of `cats` uses the `E` type variable for the error type.
| `Either[E,A] => F[A]` | `fromEither` |
| `Option[A] => E => F[A]` | `liftFromOption` |

### `MonadError[E, F]`
### MonadError

Like the previous section, we use the `E` for the error parameter type.

| Type | Method Name | Notes |
| ------------- |--------------|--------|
Expand All @@ -106,7 +98,7 @@ The source code of `cats` uses the `E` type variable for the error type.
| `F[Either[E,A]] => F[A]` | `rethrow`


### `UnorderedFoldable`
### UnorderedFoldable

| Type | Method Name | Constraints
| ------------- |--------------|----------------
Expand All @@ -118,20 +110,26 @@ The source code of `cats` uses the `E` type variable for the error type.
| `F[A] => A` | `unorderedFold` | `A: CommutativeMonoid`
| `F[A] => (A => B) => B`| `unorderedFoldMap` | `B: CommutativeMonoid`


### `Foldable`
### Foldable

| Type | Method Name | Constraints
| ------------- |--------------|-----------
| `F[A] => A` | `fold` | `A: Monoid`
| `F[A] => B => ((B,A) => B) => F[B]` | `foldLeft`
| `F[A] => (A => B) => B` | `foldMap` | `B: Monoid`
| `F[A] => (A => G[B]) => G[B]` | `foldMapM` | `G: Monad` and `B: Monoid`
| `F[A] => (A => B) => Option[B]` | `collectFirst` | The `A => B` is a `PartialFunction`
| `F[A] => (A => Option[B]) => Option[B]` | `collectFirstSome` |
| `F[A] => (A => G[B]) => G[Unit]` | `traverse_` | `G: Applicative`
| `F[G[A]] => G[Unit]` | `sequence_` | `G: Applicative`
| `F[A] => (A => Either[B, C] => (F[B], F[C])` | `partitionEither` | `G: Applicative`

### Reducible

| Type | Method Name | Constraints
| ------------- |--------------|-----------
| `F[A] => ((A,A) => A) => A` | `reduceLeft` |
| `F[A] => A` | `reduce` | `A: Semigroup`
| `F[A] => ((A,A) => A) => A` | `reduceLeft` |
| `F[A] => A` | `reduce` | `A: Semigroup` |

### Traverse

Expand All @@ -143,14 +141,13 @@ The source code of `cats` uses the `E` type variable for the error type.
| `F[G[F[A]]] => G[F[A]]` | `flatSequence` | `G: Applicative` and `F: FlatMap`
| `F[A] => F[(A,Int)]` | `zipWithIndex` |
| `F[A] => ((A,Int) => B) => F[B]` | `mapWithIndex` |
| `F[A] => ((A,Int) => G[B]) => G[F[B]]` | `traverseWithIndex` | `F: Monad`


## Transformers

### Constructors and wrappers

Most monad transformers and data types come down to a

| Data Type | is an alias or wrapper of |
|------------|--------------|
| `OptionT[F[_], A]` | `F[Option[A]]`
Expand All @@ -165,7 +162,7 @@ Most monad transformers and data types come down to a
| `FunctionK[F[_], G[_]` | `F[X] => G[X]` for every `X`
| `F ~> G` | Alias of `FunctionK[F, G]`

### `OptionT`
### OptionT

For convenience, in these types we use the symbol `OT` to abbreviate `OptionT`.

Expand All @@ -185,9 +182,9 @@ For convenience, in these types we use the symbol `OT` to abbreviate `OptionT`.
| `OT[F, A] => F[A] => F[A]` | `getOrElseF` | `F: Monad` |
| `OT[F, A] => OT[F, A] => OT[F, A]` |

### `EitherT`
### EitherT

For convenience, in these types we use the symbol `ET` to abbreviate `EitherT`. In these signatures, we use the type variables `A` and `B` to indicate the left and right sides of the `Either`.
Here, we use `ET` to abbreviate `EitherT`; and we use `A` and `B` as type variables for the left and right sides of the `Either`.

| Type | Method Name | Constraints |
|----------|--------------|-------------|
Expand All @@ -205,9 +202,9 @@ For convenience, in these types we use the symbol `ET` to abbreviate `EitherT`.
| `ET[F, A, B] => ET[F, B, A]` | `swap` | `F: Functor` |
| `ET[F, A, A] => F[A]` | `merge` |

### `Kleisli`, a.k.a `ReaderT`
### Kleisli (or ReaderT)

For convenience, in this section we use the symbol `Ki` to abbreviate `Kleisli`
Here, we use `Ki` as a short-hand for `Kleisli`.

| Type | Method Name | Constraints |
|----------|--------------|-------------|
Expand All @@ -224,9 +221,7 @@ For convenience, in this section we use the symbol `Ki` to abbreviate `Kleisli`
| `Ki[F, A, B] => Ki[F, A, F[B]]` | `lower` |


## Type Classes of Kind `(*,*) => *`

For these type-classes, we sometimes use the infix type notation `A F B` instead of `F[A, B]`. The goal of this notation is to reinforce the idea that many of these type-classes represent "functions with effects".
## Type Classes for types `F[_, _]`

### Bifunctor

Expand All @@ -240,33 +235,33 @@ For these type-classes, we sometimes use the infix type notation `A F B` instead

| Type | Method Name |
--------|-------------
| `F[A,B] => (B => C) => F[A,C]` | `rmap` |
| `F[A,B] => (C => A) => F[C,B]` | `lmap` |
| `F[A,B] => (C => A) => (B => D) => F[C,D]` | `dimap` |
| `F[A, B] => (B => C) => F[A, C]` | `rmap` |
| `F[A, B] => (C => A) => F[C, B]` | `lmap` |
| `F[A, B] => (C => A) => (B => D) => F[C,D]` | `dimap` |

#### Strong Profunctor

| Type | Method Name |
--------|-------------|
| `F[A,B] => ( (A, C) F (B, C) )` | `first` |
| `F[A,B] => ( (C, A) F (C, B) )` | `second` |
| `F[A, B] => F[(A,C), (B,C)]` | `first` |
| `F[A, B] => F[(C,A), (C,B)]` | `second` |

#### Compose -- Category -- Choice
#### Compose, Category, Choice

| Type | Method Name | Symbol |
--------|-------------|--------------|
| `F[A,B] => F[C,A] => F[C,B]` | `compose` | `<<<` |
| `F[A,B] => F[B,C] => F[A,C]` | `andThen` | `>>>` |
| `F[A, B] => F[C, A] => F[C, B]` | `compose` | `<<<` |
| `F[A, B] => F[B, C] => F[A, C]` | `andThen` | `>>>` |
| `=> F[A,A]` | `id` |
| `F[A,B] => F[C,B] => F[(A|C), B]` | `choice` | `|||`
| `=> (A|A) F A` | `codiagonal` |
| `F[A, B] => F[C, B] => F[Either[A, C], B]` | `choice` | `|||`
| `=> F[ Either[A, A], A]` | `codiagonal` |

#### Arrow

| Type | Method Name | Symbol |
|----------------|--------------|--------------|
| `(A => B) => F[A,B]` | `lift` |
| `F[A,B] => F[C,D] => F[(A,C),(B,D)]` | `split` | `***` |
| `(A => B) => F[A, B]` | `lift` |
| `F[A,B] => F[C,D] => F[(A,C), (B,D)]` | `split` | `***` |
| `F[A,B] => F[A,C] => F[A, (B,C)]` | `merge` | `&&&` |

#### ArrowChoice
Expand All @@ -277,3 +272,16 @@ For these type-classes, we sometimes use the infix type notation `A F B` instead
| `F[A,B] => F[Either[A, C], Either[B, C]]` | `left` |
| `F[A,B] => F[Either[C, A], Either[C, B]]` | `right` |

## Simplifications

Because `cats` is a Scala library and Scala has many knobs and switches, the actual definitions and the implementations of the functions and type-classes in `cats` can be a bit obfuscated at first. To alleviate this, in this glossary we focus on the plain type signatures of the method, and ignore many of the details from Scala. In particular, in our type signatures:

- We use `A,B,C` for type variables of kind `*`, and `F, G, H` for type variables of a higher kind.
- We write type signatures in currified form: parameters are taken one at a time, and they are separated with the arrow `=>` operation. In Scala, a method's parameters may be split in several comma-separated lists.
- We do not differentiate between methods from the type-class trait (e.g. `trait Functor`), or the companion object, or the syntax companion (`implicit class`).
- For functions defined as method of the typeclass trait, we ignore the receiver object.
- We ignore implicit parameters that represent type-class constraints; and write them on a side column instad.
- We use `A => B` for both `Function1[A, B]` and `PartialFunction[A, B]` parameters, without distinction. We add a side note when one is a `PartialFunction`.
- Some functions are defined through the [Partially Applied Type Params](http://typelevel.org/cats/guidelines.html#partially-applied-type-params) pattern. We ignore this.
- We ignore the distinction between by-name and by-value input parameters. We use the notation `=> A`, without parameters, to indicate constant functions.
- We ignore Scala variance annotations. We also ignore extra type parameters, which in some methods are added with a subtype-constraint, (e.g. `B >: A`). These are usually meant for flexibility, but we replace each one by its bound.