I'm writing a parser and a type checker in Haskell starting from BNFC. The main function of the type checker is implemented as follows:
typecheck :: Program -> Err ()
typecheck (PDefs ds) = do
env <- foldM (\env (DFun typ id args _ _) ->
updateFun env id (argTypes args,typ) ) (emptyEnv) (ds)
mapM_ (checkDef env) ds
where argTypes = map (\(ADecl _ typ _) -> typ)
where PDefs ,DFun, and ADecl are constructrors of algebraic data types defined in the abstract syntax of the language and checkDef and updateFun are functions. Program is the "starting point" of the grammar.
The monad used is the monad Err:
data Err a = Ok a | Bad String
deriving (Read, Show, Eq, Ord)
instance Monad Err where
return = Ok
fail = Bad
Ok a >>= f = f a
Bad s >>= f = Bad s
The typechecker function is called in the "main" module (where before the type check there are the lexical and the sintax analysis):
check :: String -> IO ()
check s = do
case pProgram (myLexer s) of
Bad err -> do
putStrLn "SYNTAX ERROR"
putStrLn err
exitFailure
Ok tree -> do
case typecheck tree of
Bad err -> do
putStrLn "TYPE ERROR"
putStrLn err
exitFailure
Ok _ -> do
putStrLn "\nParsing e checking ok!"
showTree tree
(tree is the abstract syntax tree build by the parser)
If there's a type error in the program passed as input the type checker returns an error saying what is wrong and it doesn't continue. Is there a way to allow the type checker to list all the errors in the input in a single execution?