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, …?fmapshout2Maybe :: Maybe String -> Maybe String -> Maybe String
shout2Maybe mx my = let shoutFirst = fmap shout2 mx in
                      -- shoutFirst :: Maybe (String -> String)
                      -- ... now what?shout2Maybeshout2Maybe :: Maybe String -> Maybe String -> Maybe String
shout2Maybe mx my = let shoutFirst = fmap shout2 mx in
                    shoutFirst <*> myinstance 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 xsHW3: 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 OKstr' to second parser