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

Documentation refresh for monad transformers #4724

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

reardonj
Copy link
Contributor

@reardonj reardonj commented Mar 4, 2025

This PR came out of a discussion in the Typelevel discord with @djspiewak and @armanbilge regarding unexpected interactions with monad transformers and Cats Effect.

This PR moves around monad transformer documentation to better reflect that it is a more advanced topic:

  • updates the monad transformer documentation
    • to move the overview to a separate section instead of the jump start guide
    • change uses of Future to Try to avoid suggesting developers use the deprecated Future instances
    • add a Pitfalls section to warn users about unfortunate interactions with CE and direct users to Cats MTL as an alternative.
  • moves the Monad Transformer documentation pages out of Data Types to their own section.

I also made a few related changes for consistency:

  • remove the pointless Datatypes index pages that just listed all the datatype page links
  • move the Typeclass page to and Overview page under the Typeclasses section.
  • fix a broken link in guidelines.md

image
image

Copy link
Member

@valencik valencik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NICE!!! 🎉
Thanks so much for putting in this effort, I'm really excited about it.

I think this is a good organizational change, I like the reduced Future usage, and less transformers in the return types.
I think we can go a little bit further calling out the pitfalls. Namely, let's repeat them on their respective transformer pages.
And let's call out the return types advice more prominently.

@@ -3,7 +3,7 @@
API Documentation: @:api(cats.data.EitherT)

`Either` can be used for error handling in most situations. However, when
`Either` is placed into effectful types such as `Option` or`Future`, a large
`Either` is placed into effectful types such as `Option`, a large
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's still an example using Future below this, but I think if we change that it should happen in another PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya. Examples are awkward since one of the big motivations is IO, but we can't depend on CE here.

The above `map` will return a value of type `OptionT[Try, String]`.

To get the underlying `Try[Option[String]]` value, simply call `.value` on the `OptionT` instance.
In practice, you should not include monad transformers in function signatures, and only use them as locally-scoped utilities to reduce boilerplate so that calling code is not required to care about the composition.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence is kind of buried here, but I think it was a key point of the recent discussion about transformers.
Can we perhaps highlight this in a section of its own?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

class Account { /* ... */ }
class Money { /* ... */ }

def findUserById(userId: Long): Try[Option[User]] = { /* ... */ ??? }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just want to note that these have changed from
OptionT[Future, User] to Try[Option[User]]

I think this is a good improvement if we're trying to recommend that folks don't use transformers in return types.

While powerful, this can lead to unwieldy type signatures and poor type inference.
The [Cats MTL](https://typelevel.org/cats-mtl/) project provides a capability based approach to extend effect types without requiring as much boilerplate.

Some monad transformers can also interact poorly with more powerful effect types that provide concurrent computation, such as Cats Effect's `IO` or fs2's `Stream`. You should avoid `StateT` and `WriterT` and use the concurrent data types provided by those libraries instead. Because `IO` already provides its own error channel, `EitherT[IO, Throwable]` can also lead to confusing behavior; prefer `IO`'s own error channel instead.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this warning should definitely be repeated on the EitherT, StateT, and WriterT, pages.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

image
image
image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the screenshots.
I think these are good.
The warning on EitherT is a little too up top front and center, but I don't think that's a blocker.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't identify a nice place to put that one, EitherT doesn't have a convenient intro like the other ones.

@reardonj reardonj force-pushed the documentation-refresh-monad-transformers branch from 518bcd6 to 9264f63 Compare March 5, 2025 03:10
- add warnings to specific transformer pages
- call out recommended usage more specifically
- add CE link
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants