Advertisement
Guest User

Untitled

a guest
Mar 24th, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module Block3
  2.   ( Parser (..)
  3.   , element
  4.   , eof
  5.   , ok
  6.   , parseCBS
  7.   , parseInteger
  8.   , parser
  9.   , satisfy
  10.   , stream
  11.   ) where
  12.  
  13. import Control.Applicative (Alternative, empty, some, (<|>))
  14. import Data.Char (isDigit)
  15.  
  16. -- task1
  17. newtype Parser s a = Parser { runParser :: ([s] -> Maybe (a, [s])) }
  18.  
  19. parser :: ([s] -> Maybe (a, [s])) -> Parser s a
  20. parser p = Parser { runParser = p }
  21.  
  22. instance Functor (Parser s) where
  23.   fmap f (Parser p)  = parser $ \input -> do
  24.     (a, rest) <- p input
  25.     return (f a, rest)
  26.  
  27. instance Applicative (Parser s) where
  28.   pure a = Parser $ \input -> return (a, input)
  29.  
  30.   Parser pAB <*> Parser pA = parser $ \input -> do
  31.     (ab, s1) <- pAB input
  32.     (a, s2) <- pA s1
  33.     return (ab a, s2)
  34.  
  35. instance Monad (Parser s) where
  36.   return = pure
  37.  
  38.   Parser pA >>= f = parser $ \input -> do
  39.     (a, s1) <- pA input
  40.     let pB = f a
  41.     runParser pB s1
  42.  
  43. instance Alternative (Parser s) where
  44.   empty = parser $ const Nothing
  45.  
  46.   Parser f <|> Parser g = parser $ \input -> f input <|> g input
  47.  
  48. -- task2
  49. ok :: Parser s ()
  50. ok = parser $ \input -> return ((), input)
  51.  
  52. eof :: Parser s ()
  53. eof = parser $ \input -> if null input
  54.                          then return ((), input)
  55.                          else Nothing
  56.  
  57. satisfy :: (s -> Bool) -> Parser s s
  58. satisfy p = parser $ \input -> case input of
  59.                                  []   -> Nothing
  60.                                  x:xs -> if p x
  61.                                          then return (x, xs)
  62.                                          else Nothing
  63.  
  64. element :: Eq s => s -> Parser s s
  65. element e = satisfy (== e)
  66.  
  67. stream :: Eq s => [s] -> Parser s [s]
  68. stream es = traverse element es
  69.  
  70. -- task3
  71. parseCBS :: Parser Char ()
  72. parseCBS = s <* eof
  73.   where
  74.     s = (element '(' *> s *> element ')' *> s) <|> ok
  75.  
  76. parseInteger :: Parser Char Integer
  77. parseInteger = read <$> (parseIntegerText <* eof)
  78.   where
  79.     elemToList c = pure <$> element c
  80.     discardElem c = const [] <$> element c
  81.     parseIntegerText = (++) <$> (discardElem '+' <|> elemToList '-' <|> return []) <*> (some $ satisfy isDigit)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement