Skip to content

Commit

Permalink
Merge pull request #4613 from performantdata/documentation
Browse files Browse the repository at this point in the history
correct & add documentation links
  • Loading branch information
rossabaker authored Jun 10, 2024
2 parents 17d7e95 + 531ed53 commit 1a0d029
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 36 deletions.
50 changes: 27 additions & 23 deletions core/src/main/scala/cats/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,36 @@ import cats.data.Ior
* The `cats` root package contains all the trait signatures of most Scala type classes.
*
* Cats type classes are implemented using the approach from the
* [[https://ropas.snu.ac.kr/~bruno/papers/TypeClasses.pdf Type classes as objects and implicits]] article.
* "[[https://i.cs.hku.hk/~bruno/papers/TypeClasses.pdf Type classes as objects and implicits]]" article.
*
* For each type class, `cats` provides three pieces:
* - Its '''signature''': a trait that is polymorphic on a type parameter.
* Type class traits inherit from other type classes to indicate that any implementation of the lower type class (e.g. `Applicative`)
* can also serve as an instance for the higher type class (e.g. `Functor`).
* - Type class ''''instances''', which are classes and objects that implement one or more type class signatures for some specific types.
* Type class instances for several data types from the Java or Scala standard libraries are declared in the subpackage `cats.instances`.
* - '''Syntax extensions''', each of which provides the methods of the type class defines as extension methods
* (which in Scala 2 are encoded as implicit classes) for values of any type `F`; given that an instance of the type class
* for the receiver type (`this`) is in the implicit scope.
* Syntax extensions are declared in the `cats.syntax` package.
* - A set of '''laws''', that are also generic on the type of the class, and are only defined on the operations of the type class.
* The purpose of these laws is to declare some algebraic relations (equations) between Scala expressions involving the operations
* of the type class, and test (but not verify) that implemented instances satisfy those equations.
* Laws are defined in the `cats-laws` package.
* For each type class, `cats` provides four pieces:
* - Its '''signature''': a trait that is polymorphic on a type parameter.
* Type class traits inherit from other type classes to indicate that any implementation of the lower type class
* (e.g. [[Applicative `Applicative`]])
* can also serve as an instance for the higher type class (e.g. [[Functor `Functor`]]).
* - Type class '''instances''', which are classes and objects that implement one or more type class signatures for some specific types.
* Type class instances for several data types from the Java or Scala standard libraries are declared
* in the subpackage [[cats.instances `cats.instances`]].
* - '''Syntax extensions''', each of which provides the methods of the type class defined as extension methods
* (which in Scala 2 are encoded as implicit classes) for values of any type `F`; given that an instance of the type class
* for the receiver type (`this`) is in the implicit scope.
* Syntax extensions are declared in the [[cats.syntax `cats.syntax`]] package.
* - A set of '''laws''', that are also generic on the type of the class, and are only defined on the operations of the type class.
* The purpose of these laws is to declare some algebraic relations (equations) between Scala expressions involving the operations
* of the type class, and test (but not verify) that implemented instances satisfy those equations.
* Laws are defined in the [[cats.laws `cats.laws`]] package.
*
* Although most of cats type classes are declared in this package, some are declared in other packages:
* - type classes that operate on base types (kind `*`), and their implementations for standard library types,
* are contained in `cats.kernel`, which is a different SBT project. However, they are re-exported from this package.
* - type classes of kind `F[_, _]`, such as [[cats.arrow.Profunctor]]" or [[cats.arrow.Arrow]], which are relevant for
* Functional Reactive Programming or optics, are declared in the `cats.arrow` package.
* - Also, those type classes that abstract over (pure or impure) functional runtime effects are declared
* in the [[https://typelevel.org/cats-effect/ cats-effect library]].
* - Some type classes for which no laws can be provided are left out of the main road, in a small and dirty alley.
* These are the `alleycats`.
* - type classes that operate on base types (kind `*`), and their implementations for standard library types,
* are contained in [[cats.kernel `cats.kernel`]], which is a different SBT project. However, they are re-exported from this package.
* - type classes of kind `F[_, _]`,
* such as [[cats.arrow.Profunctor `cats.arrow.Profunctor`]] or [[cats.arrow.Arrow `cats.arrow.Arrow`]],
* which are relevant for
* Functional Reactive Programming or optics, are declared in the [[cats.arrow `cats.arrow`]] package.
* - Also, those type classes that abstract over (pure or impure) functional runtime effects are declared
* in the [[https://typelevel.org/cats-effect/ cats-effect library]].
* - Some type classes for which no laws can be provided are left out of the main road, in a small and dirty alley.
* These are the [[alleycats `alleycats`]].
*/
package object cats {

Expand Down
23 changes: 10 additions & 13 deletions docs/typeclasses/applicativemonaderror.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,16 +261,16 @@ With the methods that we will compose in place let's create a method that will
compose the above methods using a for comprehension which
interprets to a `flatMap`-`map` combination.

`getTemperatureFromByCoordinates` parameterized type
`[F[_]:MonadError[*[_], String]` injects `F[_]` into `MonadError[*[_], String]`
`getTemperatureByCoordinates`'s parameterized type
`[F[_]:MonadError[*[_], String]` injects `F[_]` into `MonadError[*[_], String]`;
thus if the "error type" you wish to use is `Either[String, *]`, the `Either`
would be placed in the hole of `MonadError`, in this case,
`MonadError[Either[String, *], String]`

`getTemperatureFromByCoordinates` accepts a `Tuple2` of `Int` and `Int`, and we
return `F` which represents our `MonadError` which can be a type like `Either` or
`Validated`. In the method, since either `getCityClosestToCoordinate` and
`getTemperatureByCity` both return potential error types and they are monadic we can
`getTemperatureByCoordinates` accepts a `Tuple2` of `Int` and `Int` and
returns `F`, which represents our `MonadError`, which can be a type like `Either` or
`Validated`. In the method, since `getCityClosestToCoordinate` and
`getTemperatureByCity` both return potential error types and they are monadic, we can
compose them with a for comprehension.

```scala mdoc:silent
Expand All @@ -280,17 +280,14 @@ def getTemperatureByCoordinates[F[_]: MonadError[*[_], String]](x: (Int, Int)):
}
```

Invoking `getTemperatureByCoordinates` we can call it with the following sample,
which will return `78`.

NOTE: infix `->` creates a `Tuple2`. `1 -> "Bob"` is the same as `(1, "Bob")`
We can call `getTemperatureByCoordinates` with the following sample, which will return `78`.

```scala mdoc:silent
type MyEither[A] = Either[String, A]
getTemperatureByCoordinates[MyEither](44 -> 93)
getTemperatureByCoordinates[MyEither]((44, 93))
```

With TypeLevel Cats, how you structure your methods is up to you, if you wanted to
With TypeLevel Cats, how you structure your methods is up to you: if you wanted to
create `getTemperatureByCoordinates` without a Scala
[context bound](https://docs.scala-lang.org/tutorials/FAQ/context-bounds.html) for `MonadError`,
but create an `implicit` parameter for your `MonadError` you can have access to some
Expand All @@ -302,7 +299,7 @@ specialized methods, like `raiseError`, to raise an error representation
when things go wrong.

```scala mdoc:silent
def getTemperatureFromByCoordinatesAlternate[F[_]](x: (Int, Int))(implicit me: MonadError[F, String]): F[Int] = {
def getTemperatureByCoordinatesAlternate[F[_]](x: (Int, Int))(implicit me: MonadError[F, String]): F[Int] = {
if (x._1 < 0 || x._2 < 0) me.raiseError("Invalid Coordinates")
else for { c <- getCityClosestToCoordinate[F](x)
t <- getTemperatureByCity[F](c) } yield t
Expand Down

0 comments on commit 1a0d029

Please sign in to comment.