O'Reilly logo

Real World Haskell by Donald Bruce Stewart, Bryan O'Sullivan, John Goerzen

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Desugaring of do Blocks

Haskell’s do syntax is an example of syntactic sugar: it provides an alternative way of writing monadic code, without using (>>=) and anonymous functions. Desugaring is the translation of syntactic sugar back to the core language.

The rules for desugaring a do block are easy to follow. We can think of a compiler as applying these rules mechanically and repeatedly to a do block until no more do keywords remain.

A do keyword followed by a single action is translated to that action by itself:

-- file: ch14/Do.hs            -- file: ch14/Do.hs 
doNotation1 =                  translated1 =
    do act                         act

A do keyword followed by more than one action is translated to the first action, then (>>), followed by a do keyword and the remaining actions. When we apply this rule repeatedly, the entire do block ends up chained together by applications of (>>):

-- file: ch14/Do.hs            -- file: ch14/Do.hs
doNotation2 =                  translated2 =
    do act1                        act1 >>
       act2                        do act2
       {- ... etc. -}                 {- ... etc. -}
       actN                           actN

                              finalTranslation2 =
                                  act1 >>
                                  act2 >>
                                  {- ... etc. -}
                                  actN

The <- notation has a translation that’s worth paying close attention to. On the left of the <- is a normal Haskell pattern. This can be a single variable or something more complicated, but a guard expression is not allowed:

-- file: ch14/Do.hs            -- file: ch14/Do.hs
doNotation3 =                  translated3 =
    do pattern <- act1             let f pattern = do act2
       act2                                           let f pattern = do act2
       {- ... etc. -}                                 actN
       actN                            f _     = fail "..."
                                   in act1 >>= f

This pattern is translated into a let binding that ...

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required