Theory and Design of PL (CS 538)
February 24, 2020
Start early!!!
Eval.hs
)Parser.hs
)Main.hs
)Tests.hs
)instance Applicative Parser where
-- pure :: a -> Parser a
pure x = MkParser $ \str -> Just (x, str)
-- (<*>) :: Parser (a -> b) -> Parser a -> Parser b
parF <*> parA = MkParser $ \str ->
case runParser parF str of -- run first
Nothing -> Nothing -- first failed
Just (f, str') -> -- first OK
case runParser parA str' of -- run second
Nothing -> Nothing -- second failed
Just (v, str'') -> Just (f v, str'') -- second OK
str'
to second parser-- Mapping a two-argument function (shout2 to shout2Maybe)
-- Or: sequence two things, then apply function to results
liftA2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c
liftA2 fun x y = fun <$> x <*> y
-- Sequence two things, keep first result, forget second result
(<*) :: (Applicative f) => f a -> f b - > f a
(<*) = liftA2 (\x y -> x)
-- Sequence two things, forget first result, keep second result
(*>) :: (Applicative f) => f a -> f b - > f b
(*>) = liftA2 (\x y -> y)
instance Alternative Parser where
-- (<|>) :: Parser a -> Parser a -> Parser a
(<|>) = orElseP
-- empty :: Parser a
empty = failP
failP = MkParser $ \_ -> Nothing -- Always fails (not emptyP!)
empty <|> p === p <|> empty === p
manyP :: Parser a -> Parser [a] -- zero-or-more times
manyP par = (manyP1 par) <|> emptyP
-- ^ ^ ^------- zero times
-- | +------------- or
-- +---------------------- one-or-more times
manyP1 :: Parser a -> Parser [a] -- one-or-more times
manyP1 par = (:) <$> par <*> manyP par
-- ^ ^ ^-------- zero or more times
-- | +----------------- parse one time
-- +------------------------- gather results
list = item {sep item}
term = atom "+" term | atom "-" term | atom ;
atom = num | "(" term ")" ;