Parsing
Algorithms
Strings
Monads
Data Structures
Functional Programming
Code
Diff
  • {-# LANGUAGE DeriveFunctor, TupleSections, LambdaCase #-}
    module MonadicParsing where
    
    import Control.Applicative
    import Control.Monad
    
    newtype Parser a = Parser { runParser :: String -> [(a, String)] }
        deriving Functor
    
    instance Applicative Parser where
        pure a = Parser $ pure . (a,)
        (<*>) = ap
    
    instance Monad Parser where
        return = pure
        Parser p >>= f = Parser $ \s -> concatMap (uncurry (runParser.f)) $ p s
    
    instance Alternative Parser where
        empty = Parser $ pure []
        Parser p <|> Parser q = Parser $ liftA2 (++) p q
    
    
    pred1 :: (Char -> Bool) -> Parser Char
    pred1 p = Parser $ \case c:cs | p c -> [(c, cs)]; _ -> []
    
    char :: Char -> Parser Char
    char = pred1 . (==)
    
    str :: String -> Parser String
    str = mapM char
    
  • 1
    {-# LANGUAGE DeriveFunctor, TupleSections #-}
    
    1+
    {-# LANGUAGE DeriveFunctor, TupleSections, LambdaCase #-}
    
    22
    module MonadicParsing where
    
    33
    4+
    import Control.Applicative
    
    5+
    import Control.Monad
    
    6+
    44
    newtype Parser a = Parser { runParser :: String -> [(a, String)] }
    
    55
        deriving Functor
    
    6
        
    
    9+
    10+
    instance Applicative Parser where
    
    11+
        pure a = Parser $ pure . (a,)
    
    12+
        (<*>) = ap
    
    13+
    77
    instance Monad Parser where
    
    8
        return a = Parser $ return . (a,)
    
    15+
        return = pure
    
    99
        Parser p >>= f = Parser $ \s -> concatMap (uncurry (runParser.f)) $ p s
    
    17+
    18+
    instance Alternative Parser where
    
    19+
        empty = Parser $ pure []
    
    20+
        Parser p <|> Parser q = Parser $ liftA2 (++) p q
    
    21+
    22+
    23+
    pred1 :: (Char -> Bool) -> Parser Char
    
    24+
    pred1 p = Parser $ \case c:cs | p c -> [(c, cs)]; _ -> []
    
    25+
    26+
    char :: Char -> Parser Char
    
    27+
    char = pred1 . (==)
    
    28+
    29+
    str :: String -> Parser String
    
    30+
    str = mapM char