Main parser type
- Goal: parse a string into a type
a
- We call
(a, String)
a parse (result)- First component: output of parser
- Second component: rest of string ("" is done)
- Parser: function from string to Maybe parse
Theory and Design of PL (CS 538)
February 19, 2020
shout2 :: String -> String -> String
shout2 x y = (toUpper x) ++ " " ++ (toUpper y)
-- shout2 "hello" "world" === "HELLO WORLD"
shout2Maybe :: Maybe String -> Maybe String -> Maybe String
shout2Maybe Nothing _ = Nothing
shout2Maybe _ Nothing = Nothing
shout2Maybe (Just x) (Just y) = Just (shout2 x y)
shout2
shout3Maybe
, shout100Maybe
, …?fmap
shout2Maybe :: Maybe String -> Maybe String -> Maybe String
shout2Maybe mx my = let shoutFirst = fmap shout2 mx in
-- shoutFirst :: Maybe (String -> String)
-- ... now what?
shout2Maybe
shout2Maybe :: Maybe String -> Maybe String -> Maybe String
shout2Maybe mx my = let shoutFirst = fmap shout2 mx in
shoutFirst <*> my
instance Applicative ([]) where
-- pure :: a -> [a]
pure x = [x]
-- (<*>) :: [a -> b] -> [a] -> [b]
[] <*> _ = []
(f:fs) <*> xs = fmap f xs ++ fs <*> xs
-- associates: (fmap f xs) ++ (fs <*> xs)
instance Applicative ([]) where
-- pure :: a -> [a]
pure x = x : pure x -- infinite list of x
-- (<*>) :: [a -> b] -> [a] -> [b]
fs <*> xs = zipWith ($) fs xs
HW3: Extend parser with more features
a
(a, String)
a parse (result)
Build big parsers out of simpler parsers!
charSatP :: (Char -> Bool) -> Parser Char
charSatP predicate = MkParser $ \str ->
case str of
[] -> Nothing
(c:cs) -> if predicate c then Just (c, cs) else Nothing
spaceP :: Parser Char
spaceP = charSatP isSpace
digitP :: Parser Char
digitP = charSatP isDigit
charP :: Char -> Parser Char
charP c = charSatP (== c)
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