| | 19 | |
| | 20 | As an example, a part of the expression parser (src/Source/Parser/Exp.hs) used to look like this |
| | 21 | |
| | 22 | {{{ |
| | 23 | <|> -- \ case { ALT .. } |
| | 24 | -- overlaps with the nexta lambda form |
| | 25 | (Parsec.try $ do |
| | 26 | tok <- pTok K.BackSlash |
| | 27 | pTok K.Case |
| | 28 | alts <- pCParen (Parsec.sepEndBy1 pCaseAlt pSemis) |
| | 29 | return $ XLambdaCase (spTP tok) alts) |
| | 30 | |
| | 31 | <|> -- \ PAT .. -> EXP |
| | 32 | do tok1 <- pTok K.BackSlash |
| | 33 | pats <- Parsec.many1 pPat1 |
| | 34 | pTok <- pTok K.RightArrow |
| | 35 | exp <- pExp |
| | 36 | return $ XLambdaPats (spTP tok1) pats exp |
| | 37 | |
| | 38 | }}} |
| | 39 | |
| | 40 | Both of these combinators start with a K.Backslash token, with the first being wrapped in a Parsec.try. In the case of the first one failing, the second combinator, also starting with a K.Backslash token will be tried. |
| | 41 | |
| | 42 | Removing the Parsec.try in this instance involves replacing the above two combinators with: |
| | 43 | |
| | 44 | {{{ |
| | 45 | <|> do tok <- pTok K.BackSlash |
| | 46 | exp <- pBackslashExp (spTP tok) |
| | 47 | return $ exp |
| | 48 | }}} |
| | 49 | |
| | 50 | which uses a new combinator pBackslashExp defined as: |
| | 51 | |
| | 52 | {{{ |
| | 53 | pBackslashExp :: SP -> Parser (Exp SP) |
| | 54 | pBackslashExp startPos = |
| | 55 | do pTok K.Case |
| | 56 | alts <- pCParen (Parsec.sepEndBy1 pCaseAlt pSemis) |
| | 57 | return $ XLambdaCase startPos alts |
| | 58 | |
| | 59 | <|> do pats <- Parsec.many1 pPat1 |
| | 60 | pTok <- pTok K.RightArrow |
| | 61 | exp <- pExp |
| | 62 | return $ XLambdaPats startPos pats exp |
| | 63 | |
| | 64 | }}} |
| | 65 | |
| | 66 | Notice that the call to pBackslashExp passes in the position of the K.Backslash token to be used in the return value. |
| | 67 | |