# Translate between `>>=` and `do`

In Haskell, `do` notation and `>>=` notation can be interchangeable ways to express the same goal.

To start, let's define example types and functions to use for illustration. The example code is adapted from the Haskell Wikibook1, § 32.3. (It is a free book, and I heartily recommend it compared to learnyouahaskell.com as a beginner's book.)

``````type Board = Int -- represents current game configuration

-- returns the possible game board configurations for the next turn.
nextConfigs :: Board -> [Board]
nextConfigs bd = [bd + 1, bd * 10]
``````

For simplicity in the example, there are always exactly two next turn configurations, and the next configurations always use the formula `[+1, *10]`.

To find the list of possible game configurations after one turn we do:

``````ghci> bd = 3 :: Board -- a sample board to work with
ghci> nextConfigs bd
[4, 30]
``````

To find the list of possible game configurations after three turns we can do:

``````ghci> nextConfigs bd >>= nextConfigs >>= nextConfigs
[6,50,41,400,32,310,301,3000]
``````

How can this be translated to `do` notation?

# Translation: Overview

Start with `>>=` notation.

``````nextConfigs bd >>= nextConfigs >>= nextConfigs
``````

This is equivalently2:

``````nextConfigs bd >>= (\x -> nextConfigs x) >>= (\y -> nextConfigs y)
``````

Now we translate to `do` notation:

``````do
x <- nextConfigs bd
y <- nextConfigs x
nextConfigs y
``````

Compare the last two code snippets visually.

The lambda argument names `x` and `y` in `>>=` notation become the assignment variable names `x` and `y` in `do` notation. The `nextConfigs` function calls in `>>=` notation are written one per line in `do` notation.

# Translation: Step-by-step

1. Start a `do` block. Begin scanning the `>>=` notation line from left to right.
``````do
``````
2. Write down the first function call you encounter.
``````do
nextConfigs bd
``````
3. Add an arrow when you encounter `>>=`.
``````do
<- nextConfigs bd
``````
4. Write the name of the lambda argument, and move to the next line.
``````do
x <- nextConfigs bd
``````
5. Repeat steps 2 through 4 until you reach the end of the `>>=` notation line.

# Side Notes

What are the types of the assignment variables `x` and `y` in `do` notation? If one thought `<-` to be similar to the assignment operator `=` in C, then one would think the types to be `[Board]` since that is the return type of `nextConfigs`.

But the types of `x` and `y` are not `[Board]`. Their types are `Board`, which is the same as the type of `x` and `y` in the lambda arguments in `>>=` notation.

To get some inuition try adding this debug line in the middle of the `do` block.

``````  traceM (show x) -- from Debug.Trace
``````

Also try the code with other monads such as `Maybe`.

``````nextConfigs :: Board -> Maybe Board
nextConfigs bd = Just (bd + 1)
``````
2. Because `(\x -> nextConfigs x)` is equivalent to `nextConfigs` ↩︎