Skip to content

Edit readme to be more clear. #4

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
56 changes: 32 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,43 @@
# purescript-transformerless

## Why?
In Haskell and Purescript, the standard `Writer`, `Reader`, `State` and `RWS`
monads are implemented in terms of their monad *transformer* versions over the
`Identity` monad. Depending on how you learned about monad transformers, you might
remember reading something like the following:
Implementations of some useful types currently implemented using monad transformers, but now without using transformers.

- `Env e a`
- `Store s a`
- `Traced m a`
- `Cont r a`
- `Except e a`
- `RWS r w s a`
- `Reader r`
- `State s a`
- `Writer w a`

> The State/Reader/Writer monad is ...
>
> A monad transformer is ...
>
> The StateT/ReaderT/WriterT monad transformer is ...
>
> In fact, the State/Reader/Writer monad from section {3 lines ago} is actually
defined as StateT s Identity/ReaderT r Identity/WriterT w Identity!
## Motivation

Wow, what a plot twist!
In Haskell and PureScript, the standard `Writer`, `Reader`, `State` and `RWS`
monads are implemented in terms of their monad *transformer* versions over the
`Identity` monad. For example, `type State s = StateT s Identity`.

However, for all the theoretical cleanliness, it's "common knowledge" among
Purescripters that transformer stacks are slow and generate some funky Javascript.
While this is theoretically clean, it's "common knowledge" among
PureScripters that transformer stacks are slow and generate some funky JavaScript.
This project provides implementions of these types without using transformers.

If you want these types but don't want to wrap an existing monad, this project is for you.
Alternatively, if you want these types but need faster performance than the transformer
implementation, this project is for you.

## Usage

The same as a normal `State`, `Reader`, etc. However, you should know that
none of these types have instances for their respective transformer counterparts:
there is no instance for `..State.Class.MonadState s (..Transformerless.State s)`
or its buddies. Wouldn't it be weird for a package called "transformerless" to
depend on a package called "transformers"?
Use these exactly as you would use their transformer counterparts.

It's important to note, however, that the types in this project don't have instances of typeclasses,
like their transformer counterparts. For example, `Control.Monad.Transformerless.State s` does not
have an instance of `Control.Monad.State.Class.MonadState s`. Wouldn't it be weird for a package
called "transformerless" to depend on a package called "transformers"?

As a result, a "transformers" typeclass function is just a normal function in
the transformerless counterpart's module.
As a result, a function using a transformers typeclass is just a normal function in
the transformerless counterpart's module. For example, `get :: forall m s. MonadState s m => m s`
in transformers is `get :: forall s. State s s` in transformerless.

## Scrap Your Typeclasses

Expand All @@ -40,7 +48,7 @@ each typeclass instance in the module.
as well as infix aliases `|->, ~, >>-` for `mapR, applyR, bindR` respectively.

`Writer` and `State` are similar, but `RWS` exports `map_, apply_, pure_, bind_`.
However, the aliases are the same in each module.
While the function names in these modules are slightly different, the aliases are the same.

Using these instead of their overloaded versions avoids passing typeclass
dictionaries, and could result in a speedup.
Expand Down