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?