@@ -17,6 +17,9 @@ module Language.PureScript.Sugar.TypeClasses (
19import Language.PureScript.Declarations
19import Language.PureScript.Declarations
20+import Language.PureScript.Names
21+import Language.PureScript.Types
22+import Language.PureScript.Values
21desugarTypeClasses :: [Module] -> [Module]
24desugarTypeClasses :: [Module] -> [Module]
22desugarTypeClasses = map desugarModule
25desugarTypeClasses = map desugarModule
@@ -25,4 +28,30 @@ desugarModule :: Module -> Module
25desugarModule (Module name decls) = Module name $ concatMap desugarDecl decls
28desugarModule (Module name decls) = Module name $ concatMap desugarDecl decls
27desugarDecl :: Declaration -> [Declaration]
30desugarDecl :: Declaration -> [Declaration]
31+desugarDecl (TypeClassDeclaration name arg members) = typeClassDictionaryDeclaration name arg members : map (typeClassMemberToDictionaryAccessor name arg) members
32+desugarDecl (TypeInstanceDeclaration name ty members) = []
28desugarDecl other = [other]
33desugarDecl other = [other]
35+typeClassDictionaryDeclaration :: ProperName -> String -> [Declaration] -> Declaration
36+typeClassDictionaryDeclaration name arg members = TypeSynonymDeclaration name [arg] (Object $ rowFromList (map memberToNameAndType members, REmpty))
38+ memberToNameAndType :: Declaration -> (String, Type)
39+ memberToNameAndType (TypeDeclaration ident ty) = (show ident, ty)
40+ memberToNameAndType _ = error "Invalid declaration in type class definition"
42+typeClassMemberToDictionaryAccessor :: ProperName -> String -> Declaration -> Declaration
43+typeClassMemberToDictionaryAccessor name arg (TypeDeclaration ident ty) = ExternDeclaration ident Nothing (ForAll arg (ConstrainedType [(Qualified Nothing name, TypeVar arg)] ty))
44+typeClassMemberToDictionaryAccessor _ _ _ = error "Invalid declaration in type class definition"
47+typeInstanceDictionaryDeclaration :: Qualified ProperName -> Type -> Declaration
48+typeInstanceDictionaryDeclaration name ty decls =
49+ ValueDeclaration (mkDictionaryValueName name ty) [] Nothing (TypedValue (ObjectLiteral $ map memberToNameAndValue decls) (TypeApp (TypeConstructor name) ty))
51+ memberToNameAndValue :: Declaration -> (String, Value)
52+ memberToNameAndValue (ValueDeclaration ident ty) = (show ident, ty)
53+ memberToNameAndValue _ = error "Invalid declaration in type class definition"
55+mkDictionaryValueName :: ProperName -> Type -> Ident
56+mkDictionaryValueName _ _ = Ident "__dict"