🎓 A1Learner
🔍
0 of 50 lessons completed

Haskell Do Notation Desugaring

Do notation desugaring is the translation of do notation into bind and return calls. The do form is shorter to read and the bind form shows what it means.

A do block chains two Maybe steps

The do block takes 2 and 3 out of Maybe. It returns their sum wrapped in Maybe.

calc :: Maybe Int
calc = do
  x <- Just 2
  y <- Just 3
  return (x + y)
main :: IO ()
main = print calc

The same block as nested bind calls

This bind chain is the desugared form of the first snippet. It prints the same wrapped sum.

calc :: Maybe Int
calc = Just 2 >>= (\x -> Just 3 >>= (\y -> return (x + y)))
main :: IO ()
main = print calc

Nothing in a do block gives Nothing

The second step gives Nothing. The whole do block therefore gives Nothing.

calc :: Maybe Int
calc = do
  x <- Just 2
  y <- Nothing
  return (x + y)
main :: IO ()
main = print calc

Example

total :: Maybe Int
total = do
  x <- Just 4
  y <- Just 5
  z <- Just 6
  return (x + y + z)
main :: IO ()
main = print total

Key points

  • Desugaring: the translation of do notation into bind calls.
  • Arrow: the <- symbol in do notation that takes a value out of its wrapper for the next lines.
  • Use do notation to write a chain of wrapped steps in reading order.
  • Last line: the final line of a do block that gives the wrapped result of the whole block.

In this example, the do block takes 4, 5 and 6 out of Maybe in order. Then it returns their sum wrapped in Maybe and the program prints Just 15.

Note

A do block with no arrow is just the last action on its own.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Haskell Playground

Exercise

Which expression is the direct desugaring of do x <- Just 2; y <- Just 3; return (x + y)?