-
Notifications
You must be signed in to change notification settings - Fork 0
/
hw10.hs
45 lines (34 loc) · 1.34 KB
/
hw10.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import AParser
import Data.Char
import Control.Applicative
first :: (a -> b) -> Maybe (a,c) -> Maybe (b,c)
first fn Nothing = Nothing
first fn (Just (x, y)) = Just (fn x, y)
instance Functor Parser where
fmap fn parser = Parser { runParser = (first fn) . (runParser parser) }
instance Applicative Parser where
pure a = Parser { runParser = \s -> Just (a, s) }
p1 <*> p2 = Parser {
runParser = \s -> case (runParser p1 s) of
Nothing -> Nothing
Just (fn, xs) -> first fn (runParser p2 xs)
}
abParser :: Parser (Char, Char)
abParser = (,) <$> (char 'a') <*> (char 'b')
abParser_ :: Parser ()
abParser_ = (\x y -> ()) <$> (char 'a') <*> (char 'b')
ignoreParser :: Parser a -> Parser ()
ignoreParser = fmap (const ())
spaceParser :: Parser ()
spaceParser = ignoreParser (char ' ')
intPair :: Parser [Integer]
intPair = (\x _ y -> [x, y]) <$> posInt <*> spaceParser <*> posInt
instance Alternative Parser where
empty = Parser { runParser = \s -> Nothing }
p1 <|> p2 = Parser {
runParser = \s -> case (runParser p1 s) of
Nothing -> (runParser p2 s)
Just (a, xs) -> Just (a, xs)
}
intOrUppercase :: Parser ()
intOrUppercase = ignoreParser posInt <|> ignoreParser (satisfy isUpper)