Skip to content

Commit

Permalink
Add an explanation for the missing Applicative instances for monad
Browse files Browse the repository at this point in the history
transformers
  • Loading branch information
kubukoz committed Dec 18, 2018
1 parent b329cf1 commit 37b7fa7
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 0 deletions.
7 changes: 7 additions & 0 deletions docs/src/main/tut/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ position: 40
* [Why is some example code not compiling for me?](#example-compile)
* [How can I turn my List of `<something>` into a `<something>` of a list?](#traverse)
* [Where is `ListT`?](#listt)
* [Where are `Applicative`s for monad transformers?(#applicative-monad-transformers)
* [Where is `IO`/`Task`?](#task)
* [What does `@typeclass` mean?](#simulacrum)
* [What do types like `?` and `λ` mean?](#kind-projector)
Expand Down Expand Up @@ -124,6 +125,12 @@ def even(i: Int): ErrorsOr[Int] = if (i % 2 == 0) i.validNel else s"$i is odd".i
nl.traverse(even)
```

## <a id="applicative-monad-transformers" href="#applicative-monad-transformers">Where are `Applicative`s for monad transformers?</a>

An `Applicative` instance for `OptionT[F, ?]`/`EitherT[F, E, ?]`, built without a corresponding `Monad` instance for `F`, would be unlawful, so it's not included. See [https://typelevel.org/cats/guidelines.html#applicative-monad-transformers](the guidelines) for a more detailed explanation.

As an alternative, using `.toNested` on the monad transformer is recommended, although its `ap` will still be inconsistent with the Monad instance's.`.

## <a id="task" href="#task"></a>Where is IO/Task?

In purely functional programming, a monadic `IO` or `Task` type is often used to handle side effects such as file/network IO. In some languages and frameworks, such a type also serves as the primary abstraction through which parallelism is achieved. Nearly every real-world purely functional application or service is going to require such a data type, and this gives rise to an obvious question: why doesn't cats include such a type?
Expand Down
6 changes: 6 additions & 0 deletions docs/src/main/tut/guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ abstract class KleisliInstance1 {
We can introduce new type classes for the sake of adding laws that don't apply to the parent type class, e.g. `CommutativeSemigroup` and
`CommutativeArrow`.

### <a id="applicative-monad-transformers" href="#applicative-monad-transformers">Applicative instances for monad transformers</a>

We explicitly don't provide an instance of `Applicative` for e.g. `OptionT[F, ?]` given an `Applicative[F]`.
An attempt to construct one without a proper `Monad[F]` instance would be inconsistent in `ap` with the provided `Monad` instance
for `OptionT[F, ?]`. See [#1467](https://github.com/typelevel/cats/issues/1467) for the discussion.

#### TODO:

Once we drop 2.10 support, AnyVal-extending class constructor parameters can be marked as private.

0 comments on commit 37b7fa7

Please sign in to comment.