This repository has been archived by the owner on Apr 9, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathLec14Live.hs
167 lines (119 loc) · 4.19 KB
/
Lec14Live.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
module Lec14Live where
import Data.Char
import Control.Applicative
import Control.Monad
{- LECTURE 14 : MORE PARSER COMBINATORS -}
newtype Parser a = -- a parser of things 'a'
MkParser (String -> -- a function from strings to
Maybe ( String -- the possibility of pairs of strings
, a)) -- and things
runParser :: Parser a -> String -> Maybe (String, a)
runParser (MkParser p) s = p s
-- "char"
char :: Parser Char
char = MkParser (\s -> case s of
(c:rest) -> Just (rest, c)
"" -> Nothing)
-- "alter", and Functors
alter :: (a -> b) -> Parser a -> Parser b
alter f (MkParser p) =
MkParser (\s -> case p s of
Nothing -> Nothing
Just (rest, a) -> Just (rest, f a))
digit :: Parser Int
digit = alter digitToInt char
instance Functor Parser where
--fmap :: (a -> b) -> Parser a -> Parser b
fmap = alter
-- "andThen", and Applicatives
-- runParser (andThen digit digit) "12" = Just ("", (1, 2))
-- runParser (andThen digit char) "12" = Just ("", (1, '2'))
-- runParser (andThen digit char) "1" = Nothing
andThen :: Parser a -> Parser b -> Parser (a,b)
andThen (MkParser p1) (MkParser p2) =
MkParser (\s -> case p1 s of
Nothing ->
Nothing
Just (rest, a) ->
case p2 rest of
Nothing ->
Nothing
Just (rest', b) ->
Just (rest', (a,b)))
nothing :: a -> Parser a
nothing a = MkParser (\s -> Just (s, a))
instance Applicative Parser where
-- pure :: a -> Parser a
pure = nothing
-- (<*>) :: Parser (a -> b) -> Parser a -> Parser b
pf <*> pa = fmap (\(f,a) -> f a) (pf `andThen` pa)
-- fmap :: ((a -> b,a) -> b) -> Parser (a -> b,a) -> Parser b
digitAnd3Char :: Parser (((Int, Char), Char), Char)
digitAnd3Char = digit `andThen` char `andThen` char `andThen` char
digitAnd3Char' :: Parser (Int, Char, Char, Char)
digitAnd3Char' =
pure (\d c1 c2 c3 -> (d,c1,c2,c3))
<*> digit <*> char <*> char <*> char
-- postProcess(getMailFromServer(),
-- launchNuclearMissiles(),
-- learn.proper.Object.Programming.hierarchies())
-- "orElse", and Alternatives
orElse :: Parser a -> Parser a -> Parser a
orElse (MkParser p1) (MkParser p2) =
MkParser (\s -> case p1 s of
Nothing ->
p2 s
Just (rest,a) ->
Just (rest,a))
failure :: Parser a
failure = MkParser (\s -> Nothing)
twoChar :: Parser (Char, Char)
twoChar = pure (\c1 c2 -> (c1,c2)) <*> char <*> char
oneChar :: Parser (Char, Char)
oneChar = pure (\c -> (c, 'Q')) <*> char
{-
class Alternative f where
empty :: f a
(<|>) :: f a -> f a -> f a
-}
instance Alternative Parser where
empty = failure
(<|>) = orElse
-- fmap :: (a -> b) -> Parser a -> Parser b
-- (<*>) :: Parser (a -> b) -> Parser a -> Parser b
-- (>>=) :: Parser a -> (a -> Parser b) -> Parser b
-- (<|>) :: Parser a -> Parser a -> Parser a
-- "sequ", and Monads
expectAnA :: Parser ()
expectAnA = undefined -- fmap (\c -> if c == 'A' then () else failure) char
-- Parser a -> (a -> Parser b) -> Parser b
{- class Monad f where
return :: a -> f a
(>>=) :: f a -> (a -> f b) -> f b
-}
instance Monad Parser where
return = pure
(>>=) = sequ
sequ :: Parser a -> (a -> Parser b) -> Parser b
sequ (MkParser p1) f =
MkParser (\s -> case p1 s of
Nothing -> Nothing
Just (rest, a) ->
-- continue (f a) rest)
case f a of
MkParser p2 ->
p2 rest)
-- continue (MkParser p2) rest = p2 rest
expectAnAB :: Parser ()
expectAnAB = do c <- char
c' <- char
if c == 'A' && c' == 'B' then pure ()
else failure
{-
char >>= (\c ->
char >>= (\c' ->
if c == 'A' && c' == 'B' then pure () else failure))
-}
satisfies :: (Char -> Bool) -> Parser Char
satisfies = undefined
-- Higher level combinators: sepBy, etc.