@@ -22,7 +22,8 @@ module Language.PureScript.TypeChecker.Types (
2222import Data.List
2323import Data.Maybe (isNothing, isJust, fromMaybe)
2424import qualified Data.Data as D
25−import Data.Generics (everything, mkT, something, everywhere, mkQ)
25+import Data.Generics
26+ (mkM, everywhereM, everything, mkT, something, everywhere, mkQ)
2627
2728import Language.PureScript.Values
2829import Language.PureScript.Types
@@ -169,8 +170,10 @@ typesOf moduleName vals = do
169170 escapeCheck val ty
170171 return triple
171172 forM_ tys $ skolemEscapeCheck . snd . snd
172− return $ map (\(ident, (val, ty)) -> ( ident, ( overTypes (desaturateAllTypeSynonyms . setifyAll) val
173− , varIfUnknown . desaturateAllTypeSynonyms . setifyAll $ ty))) tys
173+ forM tys $ \(ident, (val, ty)) -> do
174+ val' <- replaceTypeClassDictionaries val
175+ return (ident, (overTypes (desaturateAllTypeSynonyms . setifyAll) $ val'
176+ , varIfUnknown . desaturateAllTypeSynonyms . setifyAll $ ty))
174177
175178isTyped :: (Ident, Value) -> (Ident, (Value, Maybe Type))
176179isTyped (name, TypedValue value ty) = (name, (value, Just ty))
@@ -179,6 +182,15 @@ isTyped (name, value) = (name, (value, Nothing))
179182overTypes :: (Type -> Type) -> Value -> Value
180183overTypes f = everywhere (mkT f)
181184
185+replaceTypeClassDictionaries :: Value -> Check Value
186+replaceTypeClassDictionaries = everywhereM (mkM go)
187+ where
188+ go (TypeClassDictionary constraint dicts) = entails dicts constraint
189+ go other = return other
190+
191+entails :: [(Ident, Qualified ProperName, Type)] -> (Qualified ProperName, Type) -> Check Value
192+entails _ _ = return $ Var $ Qualified Nothing $ Ident "placeholder" -- TODO
193+
182194escapeCheck :: Value -> Type -> Subst ()
183195escapeCheck value ty = do
184196 subst <- substSubst <$> getSubstState
@@ -319,7 +331,9 @@ infer' (Var var) = do
319331 ty <- lookupVariable moduleName var
320332 ty' <- replaceAllTypeSynonyms ty
321333 case ty' of
322− ConstrainedType constraints _ -> return $ TypedValue (App (Var var) [TypeClassDictionary constraints]) ty'
334+ ConstrainedType constraints _ -> do
335+ dicts <- getTypeClassDictionaries
336+ return $ TypedValue (App (Var var) (map (flip TypeClassDictionary dicts) constraints)) ty'
323337 _ -> return $ TypedValue (Var var) ty'
324338infer' (Block ss) = do
325339 ret <- fresh
@@ -597,8 +611,9 @@ check' val (ForAll idents ty) = do
597611 sk <- skolemize idents ty
598612 check val sk
599613check' val (ConstrainedType constraints ty) = do
600− val' <- check val ty
601− return $ Abs (map (\_ -> Ident "__dict") constraints) val'
614+ let dictName = Ident "__dict" -- TODO
615+ val' <- withTypeClassDictionaries (map (\(className, instanceTy) -> (dictName, className, instanceTy)) constraints) $ check val ty
616+ return $ Abs (map (\_ -> dictName) constraints) val'
602617check' val u@(TUnknown _) = do
603618 val'@(TypedValue _ ty) <- infer val
604619 -- Don't unify an unknown with an inferred polytype
@@ -737,7 +752,8 @@ checkFunctionApplication' fn (SaturatedTypeSynonym name tyArgs) args ret = do
737752 ty <- expandTypeSynonym name tyArgs
738753 checkFunctionApplication fn ty args ret
739754checkFunctionApplication' fn (ConstrainedType constraints fnTy) args ret = do
740− checkFunctionApplication' (App fn [TypeClassDictionary constraints]) fnTy args ret
755+ dicts <- getTypeClassDictionaries
756+ checkFunctionApplication' (App fn (map (flip TypeClassDictionary dicts) constraints)) fnTy args ret
741757checkFunctionApplication' _ fnTy args ret = throwError $ "Applying a function of type "
742758 ++ prettyPrintType fnTy
743759 ++ " to argument(s) " ++ intercalate ", " (map prettyPrintValue args)