Skip to content

Commit 3d0af7e

Browse files
committed
add MonadTrans overview and MaybeT example
1 parent 1c333f5 commit 3d0af7e

File tree

1 file changed

+47
-3
lines changed

1 file changed

+47
-3
lines changed

content/monad-transformers.md

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,65 @@ The following is a list of some basic transformers:
1515

1616
### MaybeT
1717

18-
A `Maybe a` wrapped in any other monad, i.e. `m (Maybe a)
18+
A `Maybe a` wrapped in any other monad, i.e. `m (Maybe a)`
1919

2020
### ReaderT
2121

2222
A `Reader r a` in which the resulting `a` is wrapped in any other monad, i.e. `r -> m a`
2323

2424
### StateT
2525

26-
A `State s a` in which the return value `a` and state `s` are wrapped in any other monad, i.e. `s -> m (a, s)`
26+
A `State s a` in which the return value and state, namely `(a, s)`, are wrapped in any other monad, i.e. `s -> m (a, s)`
2727

2828
### EitherT
2929

3030
An `Either e a` wrapped in any other monad, i.e. `m (Either e a)`
3131

32-
* Simple examples of usage
32+
## Simple examples of usage
33+
34+
### MonadTrans
35+
36+
[transformers](https://www.stackage.org/lts-3.20/package/transformers-0.4.2.0) is a widely used package which provides transformer versions of various monads.
37+
38+
It also provides a `MonadTrans` class which makes it easy to embed one monad into another. All of the transformers defined in the `transformers` package are instances `MonadTrans`.
39+
40+
`MonadTrans` defines one method, `lift`, the signature of which is
41+
42+
```haskell
43+
lift :: Monad m => m a -> t m a
44+
```
45+
46+
Given a monad `m`, we can "lift" into a constructed monad transformer `t` so long as `t` is an instance of `MonadTrans`
47+
48+
Examples:
49+
50+
### MaybeT
51+
52+
```haskell
53+
import Control.Monad
54+
import Control.Monad.Trans.Maybe
55+
import Control.Monad.Trans.Class
56+
57+
main = do
58+
password <- runMaybeT getPassword
59+
case password of
60+
Just p -> putStrLn "valid password!"
61+
Nothing -> putStrLn "invalid password!"
62+
63+
isValid :: String -> Bool
64+
isValid = (>= 10) . length
65+
66+
getPassword :: MaybeT IO String
67+
getPassword = do
68+
password <- lift getLine
69+
guard (isValid password)
70+
return password
71+
```
72+
73+
In this example, we combine the `IO` and `Maybe` monads. `lift getLine` allows us to embed the `IO` action into the `MaybeT` transformer, yielding a value of type `MaybeT IO String`.
74+
75+
76+
* More transformer usage examples
3377
* Pitfalls of Writer laziness
3478
* Dealing with exceptions and control structures (monad-control and exceptions packages), and losing state
3579
* Monad transformers: [EitherT vs IO](http://stackoverflow.com/questions/25752900/exceptions-and-monad-transformers/25753497#25753497)

0 commit comments

Comments
 (0)