@@ -22,9 +22,11 @@ import Data.Maybe
2222import qualified Data.Map as M
2323
2424import Control.Applicative
25−import Control.Monad.Error.Class (MonadError(..))
2625import Control.Monad.State
2726import Control.Monad.Unify
27+import Control.Monad.Writer
28+import Control.Monad.Error.Class (MonadError(..))
29+import Control.Monad.Trans.Except
2830
2931import Language.PureScript.Environment
3032import Language.PureScript.Errors
@@ -176,8 +178,8 @@ data CheckState = CheckState {
176178-- |
177179-- The type checking monad, which provides the state of the type checker, and error reporting capabilities
178180--
179−newtype Check a = Check { unCheck :: StateT CheckState (Either MultipleErrors) a }
180− deriving (Functor, Monad, Applicative, MonadState CheckState, MonadError MultipleErrors)
181+newtype Check a = Check { unCheck :: StateT CheckState (ExceptT MultipleErrors (Writer MultipleErrors)) a }
182+ deriving (Functor, Monad, Applicative, MonadState CheckState, MonadError MultipleErrors, MonadWriter MultipleErrors)
181183
182184-- |
183185-- Get the current @Environment@
@@ -200,16 +202,26 @@ modifyEnv f = modify (\s -> s { checkEnv = f (checkEnv s) })
200202-- |
201203-- Run a computation in the Check monad, starting with an empty @Environment@
202204--
203−runCheck :: (MonadError MultipleErrors m) => Check a -> m (a, Environment)
205+runCheck :: (MonadError MultipleErrors m, MonadWriter MultipleErrors m) => Check a -> m (a, Environment)
204206runCheck = runCheck' initEnvironment
205207
206208-- |
207209-- Run a computation in the Check monad, failing with an error, or succeeding with a return value and the final @Environment@.
208210--
209−runCheck' :: (MonadError MultipleErrors m) => Environment -> Check a -> m (a, Environment)
210−runCheck' env c = interpretMultipleErrors $ do
211− (a, s) <- flip runStateT (CheckState env 0 0 Nothing) $ unCheck c
212− return (a, checkEnv s)
211+runCheck' :: (MonadError MultipleErrors m, MonadWriter MultipleErrors m) => Environment -> Check a -> m (a, Environment)
212+runCheck' env = interpretMultipleErrorsAndWarnings . unwrapCheckWithWarnings env
213+ where
214+ unwrapCheckWithWarnings :: Environment -> Check a -> (Either MultipleErrors (a, Environment), MultipleErrors)
215+ unwrapCheckWithWarnings e =
216+ (\(rc, w) -> (envCheck rc, w))
217+ . runWriter
218+ . runExceptT
219+ . flip runStateT (CheckState e 0 0 Nothing)
220+ . unCheck
221+ envCheck :: Either MultipleErrors (a, CheckState) -> Either MultipleErrors (a, Environment)
222+ envCheck rc = do
223+ (a, s) <- rc
224+ return (a, checkEnv s)
213225
214226-- |
215227-- Make an assertion, failing with an error message
@@ -237,8 +249,18 @@ liftCheck = UnifyT . lift
237249-- Run a computation in the substitution monad, generating a return value and the final substitution.
238250--
239251liftUnify :: (Partial t) => UnifyT t Check a -> Check (a, Substitution t)
240−liftUnify unify = do
252+liftUnify = liftUnifyWarnings (const id)
253+
254+-- |
255+-- Run a computation in the substitution monad, generating a return value, the final substitution and updating warnings values.
256+--
257+liftUnifyWarnings :: (Partial t) => (Substitution t -> ErrorMessage -> ErrorMessage) -> UnifyT t Check a -> Check (a, Substitution t)
258+liftUnifyWarnings replace unify = do
241259 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
243262 modify $ \st' -> st' { checkNextVar = unifyNextVar ust }
244− return (a, unifyCurrentSubstitution ust)
263+ let uust = unifyCurrentSubstitution ust
264+ tell $ onErrorMessages (replace uust) w
265+ return (a, uust)
266+