@@ -20,7 +20,7 @@ module Language.PureScript.TypeChecker.Types (
22import Data.List
22import Data.List
23−import Data.Maybe (isNothing, isJust, fromMaybe)
23+import Data.Maybe (maybeToList, isNothing, isJust, fromMaybe)
24import qualified Data.Data as D
24import qualified Data.Data as D
25import Data.Generics
25import Data.Generics
26 (mkM, everywhereM, everything, mkT, something, everywhere, mkQ)
26 (mkM, everywhereM, everything, mkT, something, everywhere, mkQ)
@@ -188,8 +188,29 @@ replaceTypeClassDictionaries = everywhereM (mkM go)
188 go (TypeClassDictionary constraint dicts) = entails dicts constraint
188 go (TypeClassDictionary constraint dicts) = entails dicts constraint
189 go other = return other
189 go other = return other
191−entails :: [(Ident, Qualified ProperName, Type)] -> (Qualified ProperName, Type) -> Check Value
191+entails :: [(Ident, [(Qualified ProperName, Type)], Qualified ProperName, Type)] -> (Qualified ProperName, Type) -> Check Value
192−entails _ _ = return $ Var $ Qualified Nothing $ Ident "placeholder" -- TODO
192+entails context goal =
194+ [] -> throwError $ "No type class instance for " ++ show goal ++ " in context " ++ show context
195+ (dict : _) -> return dict
197+ go (className, ty) = [ App (Var (Qualified Nothing fnName)) args
198+ | (fnName, subgoals, className', ty') <- context
199+ , className == className'
200+ , subst <- maybeToList $ typeHeadsAreEqual ty ty'
201+ , args <- forM (replaceAllTypeVars subst subgoals) go ]
202+ typeHeadsAreEqual :: Type -> Type -> Maybe [(String, Type)]
203+ typeHeadsAreEqual String String = Just []
204+ typeHeadsAreEqual Number Number = Just []
205+ typeHeadsAreEqual Boolean Boolean = Just []
206+ typeHeadsAreEqual (Skolem s1) (Skolem s2) | s1 == s2 = Just []
207+ typeHeadsAreEqual (Array ty1) (Array ty2) = typeHeadsAreEqual ty1 ty2
208+ typeHeadsAreEqual (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = Just []
209+ typeHeadsAreEqual (TypeApp h1 (TypeVar v)) (TypeApp h2 arg) = do
210+ m <- typeHeadsAreEqual h1 h2
211+ return $ (v, arg) : m
212+ typeHeadsAreEqual t1@(TypeApp _ _) t2@(TypeApp _ (TypeVar _)) = typeHeadsAreEqual t2 t1
213+ typeHeadsAreEqual _ _ = Nothing
194escapeCheck :: Value -> Type -> Subst ()
215escapeCheck :: Value -> Type -> Subst ()
195escapeCheck value ty = do
216escapeCheck value ty = do
@@ -612,7 +633,7 @@ check' val (ForAll idents ty) = do
612 check val sk
633 check val sk
613check' val (ConstrainedType constraints ty) = do
634check' val (ConstrainedType constraints ty) = do
614 let dictName = Ident "__dict" -- TODO
635 let dictName = Ident "__dict" -- TODO
615− val' <- withTypeClassDictionaries (map (\(className, instanceTy) -> (dictName, className, instanceTy)) constraints) $ check val ty
636+ val' <- withTypeClassDictionaries (map (\(className, instanceTy) -> (dictName, [], className, instanceTy)) constraints) $ check val ty
616 return $ Abs (map (\_ -> dictName) constraints) val'
637 return $ Abs (map (\_ -> dictName) constraints) val'
617check' val u@(TUnknown _) = do
638check' val u@(TUnknown _) = do
618 val'@(TypedValue _ ty) <- infer val
639 val'@(TypedValue _ ty) <- infer val