Skip to content

Commit 53114e5

Browse files
klaeuferCopilot
andcommitted
Replace scalaz references with cats; expand Monoid and Monad sections
- 40-functional.rst (Monoid): replace dead scalaz link with cats-based inline example showing Monoid[Int], Monoid[String], |+| syntax, combineAll, and the typeclass pattern with a generic sum function. - 40-functional.rst (Monad): rewrite section with a summary table mapping each wrapper type (Option, Try, Either, List, Future, Id) to its context and what flatMap does; add cats-based code example showing Monad[Option], generic addIfPresent[F[_]: Monad], and how for-comprehensions work uniformly across monads. - 40-functional.rst (Observations): update to reference Cats as the primary library; remove scalaz reference. - 83-resources.rst: replace scalaz API + cheat-sheet links with Cats documentation and Cats Cheat Sheet. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d271112 commit 53114e5

2 files changed

Lines changed: 89 additions & 18 deletions

File tree

source/40-functional.rst

Lines changed: 87 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,34 +1091,105 @@ Examples include:
10911091

10921092
The *monoid laws* arise from the monoid's definition: the operation must be associative, and the identity element must be a left and right identity.
10931093

1094-
Examples of monoids using the Scalaz library are available `here <https://github.com/lucproglangcourse/scalaz-explorations-scala/tree/master/monoid.sc>`_
1094+
The `Cats <https://typelevel.org/cats/>`_ library provides a ``Monoid`` typeclass along with instances for common types:
1095+
1096+
.. code-block:: scala
1097+
1098+
import cats.Monoid
1099+
import cats.syntax.semigroup.* // enables |+| operator
1100+
1101+
// Monoid[Int] uses addition; empty = 0
1102+
Monoid[Int].combine(3, 4) // 7
1103+
Monoid[Int].empty // 0
1104+
Monoid[Int].combineAll(List(1, 2, 3)) // 6
1105+
1106+
// Monoid[String] uses concatenation; empty = ""
1107+
Monoid[String].combine("hello", " world") // "hello world"
1108+
1109+
// |+| is the infix alias for combine
1110+
"foo" |+| "bar" // "foobar"
1111+
List(1, 2) |+| List(3) // List(1, 2, 3)
1112+
1113+
// Any type with a Monoid can be folded for free
1114+
def sum[A: Monoid](xs: List[A]): A = xs.foldLeft(Monoid[A].empty)(_ |+| _)
1115+
sum(List("a", "b", "c")) // "abc"
1116+
sum(List(1, 2, 3)) // 6
1117+
1118+
The ``[A: Monoid]`` context bound in ``sum`` above is the *typeclass pattern*: the function works for any type ``A`` as long as a ``Monoid[A]`` instance is available.
10951119

10961120

10971121
Monad
10981122
`````
10991123

1100-
A `Monad <https://en.wikipedia.org/wiki/Monad_(functional_programming)>`_ is a type constructor (generic collection) with two operations, ``point`` (also called ``return`` or ``unit``) and ``flatMap`` (also called ``bind``).
1101-
Monads are an effective way to represent the *context* of a computation in which the computation is "wrapped".
1102-
The monad abstraction thereby enables one to separate the concerns of the computation itself and its context.
1103-
Examples include:
1124+
A `Monad <https://en.wikipedia.org/wiki/Monad_(functional_programming)>`_ is a type constructor (generic container) with two operations:
1125+
1126+
- ``pure`` (also called ``point``, ``return``, or ``unit``): lifts a plain value into the context — e.g., ``Some(x)``, ``List(x)``.
1127+
- ``flatMap`` (also called ``bind``): sequences a context-aware computation — i.e., applies a function that itself returns a wrapped value.
1128+
1129+
Monads represent the *context* in which a computation runs, allowing the concern of context management to be separated from the computation itself. The wrapper types introduced earlier in this chapter are all monads:
1130+
1131+
.. list-table::
1132+
:header-rows: 1
1133+
:widths: 20 40 40
1134+
1135+
* - Type
1136+
- Context
1137+
- What ``flatMap`` does
1138+
* - ``Option[A]``
1139+
- Possible absence of a value
1140+
- Short-circuits to ``None`` if any step is absent
1141+
* - ``Try[A]``
1142+
- Possible failure with an exception
1143+
- Short-circuits to ``Failure`` if any step throws
1144+
* - ``Either[E, A]``
1145+
- Possible failure with an error value
1146+
- Short-circuits to ``Left`` if any step fails
1147+
* - ``List[A]``
1148+
- Nondeterminism (multiple possible results)
1149+
- Applies the function to every element and concatenates results
1150+
* - ``Future[A]``
1151+
- Asynchronous (background) computation
1152+
- Sequences the next step to run after this one completes
1153+
* - ``Id[A]``
1154+
- No context (identity)
1155+
- Equivalent to plain function application
1156+
1157+
The Scala standard library does not define a unified ``Monad`` abstraction — it simply provides ``flatMap`` and ``map`` on each type individually. Cats provides the abstraction explicitly, allowing generic code to work with any monad:
1158+
1159+
.. code-block:: scala
1160+
1161+
import cats.Monad
1162+
import cats.syntax.flatMap.* // enables >>= / flatMap syntax
1163+
import cats.syntax.functor.* // enables map syntax
1164+
1165+
// Option as a Monad
1166+
val m = Monad[Option]
1167+
m.pure(42) // Some(42)
1168+
m.flatMap(Some(3))(x => Some(x * 2)) // Some(6)
1169+
m.flatMap(None: Option[Int])(_ => Some(0)) // None
1170+
1171+
// for-comprehension desugars to flatMap + map (works for any Monad)
1172+
def addIfPresent[F[_]: Monad](fa: F[Int], fb: F[Int]): F[Int] =
1173+
for
1174+
a <- fa
1175+
b <- fb
1176+
yield a + b
11041177
1105-
- ``Option`` and ``Try``: potential failure in a computation
1106-
- ``List``: nondeterminism in a computation, meaning that the computation might have multiple results
1107-
- ``Id``: the identity monad, a wrapper that doesn't actually do anything
1108-
- ``Future``: the computation takes place asynchronously (in the background)
1178+
addIfPresent(Some(3), Some(4)) // Some(7)
1179+
addIfPresent(Some(3), None) // None
1180+
addIfPresent(List(1, 2), List(10, 20))
1181+
// List(11, 21, 12, 22) — all combinations (nondeterminism)
11091182
1110-
Examples of monads using the Scalaz library are available `here <https://github.com/lucproglangcourse/scalaz-explorations-scala/tree/master/monad.sc>`_.
1183+
The ``[F[_]: Monad]`` context bound makes ``addIfPresent`` work for *any* monad — ``Option``, ``List``, ``Either``, ``Future``, or a custom type — without changing the implementation.
11111184

11121185

11131186
Observations
11141187
````````````
11151188

1116-
- The Scala library includes various structures that are effectively monads, especially those just mentioned.
1117-
What Scala does not define is a monad abstraction itself.
1118-
- This is where libraries like Scalaz or Cats come in:
1119-
They define these abstractions in such a way that we can retrofit existing types or our own types to become instances of the desired abstractions, using the *Typeclass pattern*, a technique for representing Haskell-style typeclasses.
1120-
- Examples of the Typeclass pattern are the ``Functor`` and ``Traverse`` instances in our expressions and shapes examples.
1121-
- A good reference for learning Scalaz, a library that defines these various abstractions, is available `here <http://eed3si9n.com/learning-scalaz>`_.
1189+
- The Scala standard library provides ``flatMap`` and ``map`` on many types, making ``for`` comprehensions work uniformly. What it does not define is a common ``Monad`` abstraction across those types.
1190+
- The `Cats <https://typelevel.org/cats/>`_ library fills this gap using the *typeclass pattern*: it defines ``Monad[F[_]]`` as a typeclass and provides instances for ``Option``, ``List``, ``Either``, ``Future``, ``Id``, and many others, as well as tools for defining your own instances.
1191+
- Examples of the typeclass pattern we have already seen in this chapter are the ``Functor`` and ``Traverse`` instances in the expressions and shapes examples.
1192+
- The `Cats documentation <https://typelevel.org/cats/>`_ is the primary reference for these abstractions.
11221193

11231194

11241195
References

source/83-resources.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ Online Scala resources
115115
- `Scala style guide <http://docs.scala-lang.org/style>`_
116116
- `Scala Cookbook (recommended) <http://scalacookbook.com/>`_
117117
- `parboiled2 parser generator <https://github.com/sirthias/parboiled2>`_
118-
- `scalaz API documentation (advanced) <http://docs.typelevel.org/api/scalaz/stable/7.1.0-M3/doc>`_
119-
- `scalaz cheat sheet (advanced) <http://eed3si9n.com/scalaz-cheat-sheet>`_
118+
- `Cats documentation <https://typelevel.org/cats/>`_ — typeclass abstractions (Functor, Monoid, Monad, etc.) for Scala (advanced)
119+
- `Cats Cheat Sheet <https://typelevel.org/cats/cheatsheet.html>`_ — quick reference for Cats typeclasses and combinators (advanced)
120120

121121
Resources on program representation and interpretation
122122
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

0 commit comments

Comments
 (0)