-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathex1.hs
100 lines (85 loc) · 1.9 KB
/
ex1.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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import Control.Applicative
import Data.Char
newtype Parser a =
P (String -> [(a, String)])
parse :: Parser a -> String -> [(a, String)]
parse (P p) = p
item :: Parser Char
item =
P (\inp ->
case inp of
[] -> []
(x:xs) -> [(x, xs)])
instance Functor Parser
-- fmap :: (a -> b) -> Parser a -> Parser b
where
fmap g p =
P
(\inp ->
case parse p inp of
[] -> []
[(v, out)] -> [(g v, out)])
instance Applicative Parser
-- pure :: a -> Parser a
where
pure v = P (\inp -> [(v, inp)])
-- (<*>) :: Parser (a -> b) -> Parser a -> Parser b
pg <*> px =
P
(\inp ->
case parse pg inp of
[] -> []
[(g, out)] -> parse (fmap g px) out)
instance Monad Parser
-- (>>=) :: Parser a -> (a -> Parser b) -> Parser b
where
p >>= f =
P
(\inp ->
case parse p inp of
[] -> []
[(v, out)] -> parse (f v) out)
instance Alternative Parser
-- empty :: Parser a
where
empty = P (\inp -> [])
-- (<|>) :: Parser a -> Parser a -> Parser a
p <|> q =
P
(\inp ->
case parse p inp of
[] -> parse q inp
[(v, out)] -> [(v, out)])
sat :: (Char -> Bool) -> Parser Char
sat p = do
x <- item
if p x
then return x
else empty
char :: Char -> Parser Char
char x = sat (== x)
string :: String -> Parser String
string [] = return []
string (x:xs) = do
char x
string xs
return (x : xs)
space :: Parser ()
space = do
many (sat isSpace)
return ()
token :: Parser a -> Parser a
token p = do
space
v <- p
space
return v
symbol :: String -> Parser String
symbol xs = token (string xs)
eol :: Char
eol = '\n'
comment :: Parser ()
comment = do
string "--"
many (sat (/= eol))
return ()