Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Control.Monad.Except
- import Data.Char
- data ParseError = ParseError {location::Int, reason::String}
- type ParseMonad = Either ParseError
- parseDig :: Char -> Integer -> ParseMonad Integer
- parseDig x pos = do
- if isHexDigit x
- then return $ toInteger $ digitToInt x
- else throwError $ ParseError (fromInteger pos) (x:": Invalid digit")
- parseHex' :: String -> Integer -> Integer -> ParseMonad Integer
- parseHex' [x] pos acc = do
- b <- (parseDig x pos)
- return $ acc * 16 + b
- parseHex' (x:xs) pos acc = do
- b <- parseDig x pos
- c <- parseHex' xs (pos + 1) (acc * 16 + b)
- return c
- parseHex :: String -> ParseMonad Integer
- parseHex x = parseHex' x 1 1
- printError :: ParseError -> ParseMonad String
- printError pe = Right $ "At pos " ++ (show (location pe)) ++ ": " ++ (reason pe)
- test s = str where
- (Right str) = do
- n <- parseHex s
- return $ show n
- `catchError` printError
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement