mkSelId :: String -> Int -> Int -> Id
mkSelId str n m = mkId [mkSimpleId (str ++ "_" ++ show n ++ "_" ++ show m)]
mkSelVar :: Int -> Int -> Type -> VarDecl
mkSelVar n m ty = VarDecl (mkSelId "x" n m) ty Other []
genTuple :: Int -> Int -> [Selector] -> [VarDecl]
genTuple n m (Select _ ty _ : sels) =
mkSelVar n m ty : genTuple n (m + 1) sels
genSelVars :: Int -> [[Selector]] -> [[VarDecl]]
genTuple n 1 ts : genSelVars (n + 1) sels
makeSelTupleEqs :: DataPat -> Term -> Int -> Int -> [Selector] -> [Named Term]
makeSelTupleEqs dt ct n m (Select mi ty p : sels) =
let Result _ msc = getSelType dt p ty in
vt = QualVar $ mkSelVar n m ty
eq = mkEqTerm eqId [] (mkApplTerm (mkOpTerm i sc) [ct]) vt
in [NamedSen ("ga_select_" ++ show i) eq]
++ makeSelTupleEqs dt ct n (m + 1) sels
makeSelTupleEqs _ _ _ _ [] = []
makeSelEqs :: DataPat -> Term -> Int -> [[Selector]] -> [Named Term]
makeSelEqs dt ct n (sel:sels) =
makeSelTupleEqs dt ct n 1 sel
++ makeSelEqs dt ct (n + 1) sels
makeAltSelEqs :: DataPat -> AltDefn -> [Named Term]
makeAltSelEqs dt@(_, args, _) (Construct mc ts p sels) =
Just c -> let sc = TypeScheme args ([] :=> getConstrType dt p ts) []
Result _ msc = generalize sc
as = map ( \ vs -> mkTupleTerm (map QualVar vs) []) vars
ct = mkApplTerm (mkOpTerm c newSc) as
in map (mapNamed (mkForall (map GenTypeVarDecl args
++ map GenVarDecl (concat vars))))
$ makeSelEqs dt ct 1 sels
makeDataSelEqs :: DataEntry -> Kind -> [Named Sentence]
makeDataSelEqs (DataEntry _ i _ args alts) k =
concatMap (makeAltSelEqs(i, args, k)) alts
anaAlts :: [DataPat] -> DataPat -> [Alternative] -> TypeMap -> Result [AltDefn]
do l <- mapM (anaAlt tys dt tm) alts
Result (checkUniqueness $ catMaybes $
map ( \ (Construct i _ _ _) -> i) l) $ Just ()
anaAlt :: [DataPat] -> DataPat -> TypeMap -> Alternative -> Result AltDefn
anaAlt _ _ tm (Subtype ts _) =
do l <- mapM ( \ t -> anaType (Just star, t) tm) ts
return $ Construct Nothing (map snd l) Partial []
anaAlt tys dt tm (Constructor i cs p _) =
do newCs <- mapM (anaComps tys dt tm) cs
Result (checkUniqueness $ catMaybes $
map ( \ (Select s _ _) -> s ) $ concat sels) $ Just ()
return $ Construct (Just i) (map fst newCs) p sels
anaComps :: [DataPat] -> DataPat -> TypeMap -> [Component]
-> Result (Type, [Selector])
do newCs <- mapM (anaComp tys rt tm) cs
return (mkProductType (map fst newCs) [], map snd newCs)
anaComp :: [DataPat] -> DataPat -> TypeMap -> Component
-> Result (Type, Selector)
anaComp tys rt tm (Selector s p t _ _) =
do ct <- anaCompType tys rt t tm
return (ct, Select (Just s) ct p)
anaComp tys rt tm (NoSelector t) =
do ct <- anaCompType tys rt t tm
return (ct, Select Nothing ct Partial)
getSelType :: DataPat -> Partiality -> Type -> Result TypeScheme
getSelType dp@(_, args, _) p rt = let dt = typeIdToType dp in
generalize $ TypeScheme args ([] :=> (case p of
Partial -> addPartiality [dt]
Total -> id) (FunType dt FunArr rt [])) []
anaCompType :: [DataPat] -> DataPat -> Type -> TypeMap -> Result Type
anaCompType tys (_, as, _) t tm = do
(_, ct) <- anaType (Just star, t) tm
let ds = unboundTypevars as ct
if null ds then return () else Result ds Nothing
mapM (checkMonomorphRecursion ct tm) tys
checkMonomorphRecursion :: Type -> TypeMap -> DataPat -> Result ()
checkMonomorphRecursion t tm p@(i, _, _) =
let rt = typeIdToType p in
if equalSubs tm t rt then return ()
else Result [Diag Error ("illegal polymorphic recursion"
++ expected rt t) $ getMyPos t] Nothing