]> git.rkrishnan.org Git - yorgey.git/blob - hw10/AParser.hs
0ee3090a2d54cb8bfd5cc67d3be0096f0a09a27e
[yorgey.git] / hw10 / AParser.hs
1 {- CIS 194 HW 10
2    due Monday, 1 April
3 -}
4
5 module AParser where
6
7 import           Control.Applicative
8
9 import           Data.Char
10
11 -- A parser for a value of type a is a function which takes a String
12 -- represnting the input to be parsed, and succeeds or fails; if it
13 -- succeeds, it returns the parsed value along with the remainder of
14 -- the input.
15 newtype Parser a = Parser { runParser :: String -> Maybe (a, String) }
16
17 -- For example, 'satisfy' takes a predicate on Char, and constructs a
18 -- parser which succeeds only if it sees a Char that satisfies the
19 -- predicate (which it then returns).  If it encounters a Char that
20 -- does not satisfy the predicate (or an empty input), it fails.
21 satisfy :: (Char -> Bool) -> Parser Char
22 satisfy p = Parser f
23   where
24     f [] = Nothing    -- fail on the empty input
25     f (x:xs)          -- check if x satisfies the predicate
26                         -- if so, return x along with the remainder
27                         -- of the input (that is, xs)
28         | p x       = Just (x, xs)
29         | otherwise = Nothing  -- otherwise, fail
30
31 -- Using satisfy, we can define the parser 'char c' which expects to
32 -- see exactly the character c, and fails otherwise.
33 char :: Char -> Parser Char
34 char c = satisfy (== c)
35
36 {- For example:
37
38 *Parser> runParser (satisfy isUpper) "ABC"
39 Just ('A',"BC")
40 *Parser> runParser (satisfy isUpper) "abc"
41 Nothing
42 *Parser> runParser (char 'x') "xyz"
43 Just ('x',"yz")
44
45 -}
46
47 -- For convenience, we've also provided a parser for positive
48 -- integers.
49 posInt :: Parser Integer
50 posInt = Parser f
51   where
52     f xs
53       | null ns   = Nothing
54       | otherwise = Just (read ns, rest)
55       where (ns, rest) = span isDigit xs
56
57 ------------------------------------------------------------
58 -- Your code goes below here
59 ------------------------------------------------------------