@@ -34,11 +34,11 @@ import Control.Monad.State
34import Control.Arrow ((***))
34import Control.Arrow ((***))
36import Data.Maybe (fromMaybe)
36import Data.Maybe (fromMaybe)
37−import Data.List (nub)
37+import Data.List (intercalate, nub)
38import Data.Generics (mkQ, everything)
38import Data.Generics (mkQ, everything)
39import Language.PureScript.CodeGen.Common (identToJs, moduleNameToJs)
39import Language.PureScript.CodeGen.Common (identToJs, moduleNameToJs)
41−type MemberMap = M.Map (ModuleName, ProperName) (String, [(String, Type)])
41+type MemberMap = M.Map (ModuleName, ProperName) ([String], [(String, Type)])
43type Desugar = StateT MemberMap (Either String)
43type Desugar = StateT MemberMap (Either String)
@@ -91,10 +91,10 @@ desugarModule (Module name decls) = Module name <$> concat <$> mapM (desugarDecl
91-- __Test_Foo_array _1 = { foo: __Test_Foo_array_foo _1 :: [a] -> [a] (unchecked) }
91-- __Test_Foo_array _1 = { foo: __Test_Foo_array_foo _1 :: [a] -> [a] (unchecked) }
93desugarDecl :: ModuleName -> Declaration -> Desugar [Declaration]
93desugarDecl :: ModuleName -> Declaration -> Desugar [Declaration]
94−desugarDecl mn d@(TypeClassDeclaration name arg members) = do
94+desugarDecl mn d@(TypeClassDeclaration name args members) = do
95 let tys = map memberToNameAndType members
95 let tys = map memberToNameAndType members
96− modify (M.insert (mn, name) (arg, tys))
96+ modify (M.insert (mn, name) (args, tys))
97− return $ d : typeClassDictionaryDeclaration name arg members : map (typeClassMemberToDictionaryAccessor name arg) members
97+ return $ d : typeClassDictionaryDeclaration name args members : map (typeClassMemberToDictionaryAccessor name args) members
98desugarDecl mn d@(TypeInstanceDeclaration deps name ty members) = do
98desugarDecl mn d@(TypeInstanceDeclaration deps name ty members) = do
99 desugared <- lift $ desugarCases members
99 desugared <- lift $ desugarCases members
100 entries <- mapM (typeInstanceDictionaryEntryDeclaration mn deps name ty) desugared
100 entries <- mapM (typeInstanceDictionaryEntryDeclaration mn deps name ty) desugared
@@ -106,50 +106,50 @@ memberToNameAndType :: Declaration -> (String, Type)
106memberToNameAndType (TypeDeclaration ident ty) = (identToJs ident, ty)
106memberToNameAndType (TypeDeclaration ident ty) = (identToJs ident, ty)
107memberToNameAndType _ = error "Invalid declaration in type class definition"
107memberToNameAndType _ = error "Invalid declaration in type class definition"
109−typeClassDictionaryDeclaration :: ProperName -> String -> [Declaration] -> Declaration
109+typeClassDictionaryDeclaration :: ProperName -> [String] -> [Declaration] -> Declaration
110−typeClassDictionaryDeclaration name arg members =
110+typeClassDictionaryDeclaration name args members =
111− TypeSynonymDeclaration name [arg] (Object $ rowFromList (map memberToNameAndType members, REmpty))
111+ TypeSynonymDeclaration name args (Object $ rowFromList (map memberToNameAndType members, REmpty))
113−typeClassMemberToDictionaryAccessor :: ProperName -> String -> Declaration -> Declaration
113+typeClassMemberToDictionaryAccessor :: ProperName -> [String] -> Declaration -> Declaration
114−typeClassMemberToDictionaryAccessor name arg (TypeDeclaration ident ty) =
114+typeClassMemberToDictionaryAccessor name args (TypeDeclaration ident ty) =
115 ExternDeclaration TypeClassAccessorImport ident
115 ExternDeclaration TypeClassAccessorImport ident
116 (Just (JSFunction (Just $ identToJs ident) ["dict"] (JSBlock [JSReturn (JSAccessor (identToJs ident) (JSVar "dict"))])))
116 (Just (JSFunction (Just $ identToJs ident) ["dict"] (JSBlock [JSReturn (JSAccessor (identToJs ident) (JSVar "dict"))])))
117− (ForAll arg (ConstrainedType [(Qualified Nothing name, TypeVar arg)] ty) Nothing)
117+ (quantify (ConstrainedType [(Qualified Nothing name, map TypeVar args)] ty))
118typeClassMemberToDictionaryAccessor _ _ _ = error "Invalid declaration in type class definition"
118typeClassMemberToDictionaryAccessor _ _ _ = error "Invalid declaration in type class definition"
120−typeInstanceDictionaryDeclaration :: ModuleName -> [(Qualified ProperName, Type)] -> Qualified ProperName -> Type -> [Declaration] -> Desugar Declaration
120+typeInstanceDictionaryDeclaration :: ModuleName -> [(Qualified ProperName, [Type])] -> Qualified ProperName -> [Type] -> [Declaration] -> Desugar Declaration
121−typeInstanceDictionaryDeclaration mn deps name ty decls = do
121+typeInstanceDictionaryDeclaration mn deps name tys decls = do
123− (arg, instanceTys) <- lift $ maybe (Left $ "Type class " ++ show name ++ " is undefined. Type class names must be qualified.") Right
123+ (args, instanceTys) <- lift $ maybe (Left $ "Type class " ++ show name ++ " is undefined. Type class names must be qualified.") Right
124 $ M.lookup (qualify mn name) m
124 $ M.lookup (qualify mn name) m
125− let memberTypes = map (id *** replaceTypeVars arg ty) instanceTys
125+ let memberTypes = map (id *** (\instanceTy -> replaceAllTypeVars (zip args tys) instanceTy)) instanceTys
126− entryName <- lift $ mkDictionaryValueName mn name ty
126+ entryName <- lift $ mkDictionaryValueName mn name tys
127 memberNames <- mapM (memberToNameAndValue memberTypes) decls
127 memberNames <- mapM (memberToNameAndValue memberTypes) decls
128 return $ ValueDeclaration entryName [] Nothing
128 return $ ValueDeclaration entryName [] Nothing
129 (TypedValue True
129 (TypedValue True
130 (foldr Abs (ObjectLiteral memberNames) (map (\n -> Left . Ident $ '_' : show n) [1..max 1 (length deps)]))
130 (foldr Abs (ObjectLiteral memberNames) (map (\n -> Left . Ident $ '_' : show n) [1..max 1 (length deps)]))
131 (quantify (if null deps then
131 (quantify (if null deps then
132− function unit (TypeApp (TypeConstructor name) ty)
132+ function unit (foldl TypeApp (TypeConstructor name) tys)
134− foldr function (TypeApp (TypeConstructor name) ty) (map (\(pn, ty') -> TypeApp (TypeConstructor pn) ty') deps)))
134+ foldr function (foldl TypeApp (TypeConstructor name) tys) (map (\(pn, tys) -> foldl TypeApp (TypeConstructor pn) tys) deps)))
137 memberToNameAndValue :: [(String, Type)] -> Declaration -> Desugar (String, Value)
137 memberToNameAndValue :: [(String, Type)] -> Declaration -> Desugar (String, Value)
138− memberToNameAndValue tys (ValueDeclaration ident _ _ _) = do
138+ memberToNameAndValue tys' (ValueDeclaration ident _ _ _) = do
139− memberType <- lift . maybe (Left "Type class member type not found") Right $ lookup (identToJs ident) tys
139+ memberType <- lift . maybe (Left "Type class member type not found") Right $ lookup (identToJs ident) tys'
140− memberName <- mkDictionaryEntryName mn name ty ident
140+ memberName <- mkDictionaryEntryName mn name tys ident
141 return (identToJs ident, TypedValue False
141 return (identToJs ident, TypedValue False
142 (foldl App (Var (Qualified Nothing memberName)) (map (\n -> Var (Qualified Nothing (Ident ('_' : show n)))) [1..length deps]))
142 (foldl App (Var (Qualified Nothing memberName)) (map (\n -> Var (Qualified Nothing (Ident ('_' : show n)))) [1..length deps]))
143 (quantify memberType))
143 (quantify memberType))
144 memberToNameAndValue _ _ = error "Invalid declaration in type instance definition"
144 memberToNameAndValue _ _ = error "Invalid declaration in type instance definition"
146−typeInstanceDictionaryEntryDeclaration :: ModuleName -> [(Qualified ProperName, Type)] -> Qualified ProperName -> Type -> Declaration -> Desugar Declaration
146+typeInstanceDictionaryEntryDeclaration :: ModuleName -> [(Qualified ProperName, [Type])] -> Qualified ProperName -> [Type] -> Declaration -> Desugar Declaration
147−typeInstanceDictionaryEntryDeclaration mn deps name ty (ValueDeclaration ident [] _ val) = do
147+typeInstanceDictionaryEntryDeclaration mn deps name tys (ValueDeclaration ident [] _ val) = do
149− valTy <- lift $ do (arg, members) <- lookupTypeClass m
149+ valTy <- lift $ do (args, members) <- lookupTypeClass m
150 ty' <- lookupIdent members
150 ty' <- lookupIdent members
151− return $ replaceTypeVars arg ty ty'
151+ return $ replaceAllTypeVars (zip args tys) ty'
152− entryName <- mkDictionaryEntryName mn name ty ident
152+ entryName <- mkDictionaryEntryName mn name tys ident
153 return $ ValueDeclaration entryName [] Nothing
153 return $ ValueDeclaration entryName [] Nothing
154 (TypedValue True val (quantify (if null deps then valTy else ConstrainedType deps valTy)))
154 (TypedValue True val (quantify (if null deps then valTy else ConstrainedType deps valTy)))
@@ -164,10 +164,10 @@ qualifiedToString _ (Qualified (Just mn) pn) = moduleNameToJs mn ++ "_" ++ runPr
165-- Generate a name for a type class dictionary, based on the module name, class name and type name
165-- Generate a name for a type class dictionary, based on the module name, class name and type name
167−mkDictionaryValueName :: ModuleName -> Qualified ProperName -> Type -> Either String Ident
167+mkDictionaryValueName :: ModuleName -> Qualified ProperName -> [Type] -> Either String Ident
168−mkDictionaryValueName mn cl ty = do
168+mkDictionaryValueName mn cl tys = do
169− tyStr <- typeToString mn ty
169+ tyStr <- mapM (typeToString mn) tys
170− return $ Ident $ "__" ++ qualifiedToString mn cl ++ "_" ++ tyStr
170+ return $ Ident $ "__" ++ qualifiedToString mn cl ++ "_" ++ intercalate "_" tyStr
172typeToString :: ModuleName -> Type -> Either String String
172typeToString :: ModuleName -> Type -> Either String String
173typeToString _ (TypeVar _) = return "var"
173typeToString _ (TypeVar _) = return "var"
@@ -179,7 +179,7 @@ typeToString _ _ = Left "Type class instance must be of the form T a1 ... an"
179-- Generate a name for a type class dictionary member, based on the module name, class name, type name and
179-- Generate a name for a type class dictionary member, based on the module name, class name, type name and
180-- member name
180-- member name
182−mkDictionaryEntryName :: ModuleName -> Qualified ProperName -> Type -> Ident -> Desugar Ident
182+mkDictionaryEntryName :: ModuleName -> Qualified ProperName -> [Type] -> Ident -> Desugar Ident
183−mkDictionaryEntryName mn name ty ident = do
183+mkDictionaryEntryName mn name tys ident = do
184− Ident dictName <- lift $ mkDictionaryValueName mn name ty
184+ Ident dictName <- lift $ mkDictionaryValueName mn name tys
185 return $ Escaped $ dictName ++ "_" ++ identToJs ident
185 return $ Escaped $ dictName ++ "_" ++ identToJs ident