@@ -22,9 +22,11 @@ import Data.Maybe
22import qualified Data.Map as M
22import qualified Data.Map as M
24import Control.Applicative
24import Control.Applicative
25−import Control.Monad.Error.Class (MonadError(..))
26import Control.Monad.State
25import Control.Monad.State
27import Control.Monad.Unify
26import Control.Monad.Unify
27+import Control.Monad.Writer
28+import Control.Monad.Error.Class (MonadError(..))
29+import Control.Monad.Trans.Except
29import Language.PureScript.Environment
31import Language.PureScript.Environment
30import Language.PureScript.Errors
32import Language.PureScript.Errors
@@ -176,8 +178,8 @@ data CheckState = CheckState {
177-- The type checking monad, which provides the state of the type checker, and error reporting capabilities
179-- The type checking monad, which provides the state of the type checker, and error reporting capabilities
179−newtype Check a = Check { unCheck :: StateT CheckState (Either MultipleErrors) a }
181+newtype Check a = Check { unCheck :: StateT CheckState (ExceptT MultipleErrors (Writer MultipleErrors)) a }
180− deriving (Functor, Monad, Applicative, MonadState CheckState, MonadError MultipleErrors)
182+ deriving (Functor, Monad, Applicative, MonadState CheckState, MonadError MultipleErrors, MonadWriter MultipleErrors)
183-- Get the current @Environment@
185-- Get the current @Environment@
@@ -200,16 +202,26 @@ modifyEnv f = modify (\s -> s { checkEnv = f (checkEnv s) })
201-- Run a computation in the Check monad, starting with an empty @Environment@
203-- Run a computation in the Check monad, starting with an empty @Environment@
203−runCheck :: (MonadError MultipleErrors m) => Check a -> m (a, Environment)
205+runCheck :: (MonadError MultipleErrors m, MonadWriter MultipleErrors m) => Check a -> m (a, Environment)
204runCheck = runCheck' initEnvironment
206runCheck = runCheck' initEnvironment
207-- Run a computation in the Check monad, failing with an error, or succeeding with a return value and the final @Environment@.
209-- Run a computation in the Check monad, failing with an error, or succeeding with a return value and the final @Environment@.
209−runCheck' :: (MonadError MultipleErrors m) => Environment -> Check a -> m (a, Environment)
211+runCheck' :: (MonadError MultipleErrors m, MonadWriter MultipleErrors m) => Environment -> Check a -> m (a, Environment)
210−runCheck' env c = interpretMultipleErrors $ do
212+runCheck' env = interpretMultipleErrorsAndWarnings . unwrapCheckWithWarnings env
214+ unwrapCheckWithWarnings :: Environment -> Check a -> (Either MultipleErrors (a, Environment), MultipleErrors)
215+ unwrapCheckWithWarnings e =
216+ (\(rc, w) -> (envCheck rc, w))
211− (a, s) <- flip runStateT (CheckState env 0 0 Nothing) $ unCheck c
219+ . flip runStateT (CheckState e 0 0 Nothing)
221+ envCheck :: Either MultipleErrors (a, CheckState) -> Either MultipleErrors (a, Environment)
212− return (a, checkEnv s)
224+ return (a, checkEnv s)
215-- Make an assertion, failing with an error message
227-- Make an assertion, failing with an error message
@@ -237,8 +249,18 @@ liftCheck = UnifyT . lift
237-- Run a computation in the substitution monad, generating a return value and the final substitution.
249-- Run a computation in the substitution monad, generating a return value and the final substitution.
239liftUnify :: (Partial t) => UnifyT t Check a -> Check (a, Substitution t)
251liftUnify :: (Partial t) => UnifyT t Check a -> Check (a, Substitution t)
240−liftUnify unify = do
252+liftUnify = liftUnifyWarnings (const id)
255+-- Run a computation in the substitution monad, generating a return value, the final substitution and updating warnings values.
257+liftUnifyWarnings :: (Partial t) => (Substitution t -> ErrorMessage -> ErrorMessage) -> UnifyT t Check a -> Check (a, Substitution t)
258+liftUnifyWarnings replace unify = do
241 st <- get
259 st <- get
242− (a, ust) <- runUnify (defaultUnifyState { unifyNextVar = checkNextVar st }) unify
260+ let ru = runUnify (defaultUnifyState { unifyNextVar = checkNextVar st }) unify
261+ ((a, ust), w) <- censor (const mempty) . listen $ ru
243 modify $ \st' -> st' { checkNextVar = unifyNextVar ust }
262 modify $ \st' -> st' { checkNextVar = unifyNextVar ust }
244− return (a, unifyCurrentSubstitution ust)
263+ let uust = unifyCurrentSubstitution ust
264+ tell $ onErrorMessages (replace uust) w