25.10.2015 Views

Write You a Haskell Stephen Diehl

1kEcQTb

1kEcQTb

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

many_v = some_v pure []<br />

some_v = (:) v many_v<br />

-- | Zero or more.<br />

many :: f a -> f [a]<br />

many v = many_v<br />

where<br />

many_v = some_v pure []<br />

some_v = (:) v many_v<br />

On top of this we can add functionality for checking whether the current character in the stream matches<br />

a given predicate ( i.e is it a digit, is it a letter, a specific word, etc).<br />

satisfy :: (Char -> Bool) -> Parser Char<br />

satisfy p = item ‘bind‘ \c -><br />

if p c<br />

then unit c<br />

else (Parser (\cs -> []))<br />

Essentially this 50 lines code encodes the entire core of the parser combinator machinery. All higher<br />

order behavior can be written on top of just this logic. Now we can write down several higher level<br />

functions which operate over sections of the stream.<br />

chainl1 parses one or more occurrences of p, separated by op and returns a value obtained by a recursing<br />

until failure on the left hand side of the stream. is can be used to parse left-recursive grammar.<br />

oneOf :: [Char] -> Parser Char<br />

oneOf s = satisfy (flip elem s)<br />

chainl :: Parser a -> Parser (a -> a -> a) -> a -> Parser a<br />

chainl p op a = (p ‘chainl1‘ op) return a<br />

chainl1 :: Parser a -> Parser (a -> a -> a) -> Parser a<br />

p ‘chainl1‘ op = do {a

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!