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 equivalently:2
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
- Start a
do
block. Begin scanning the>>=
notation line from left to right.do
- Write down the first function call you encounter.
do nextConfigs bd
- Add an arrow when you encounter
>>=
.do <- nextConfigs bd
- Write the name of the lambda argument, and move to the next line.
do x <- nextConfigs bd
- 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)