2 % (c) The GRASP/AQUA Project, Glasgow University, 2000
4 \section[FunDeps]{FunDeps - functional dependencies}
6 It's better to read it as: "if we know these, then we're going to know these"
11 instantiateFdClassTys,
16 #include "HsVersions.h"
19 import Class ( Class, FunDep, classTvsFds )
20 import Type ( Type, tyVarsOfTypes )
21 import Outputable ( Outputable, SDoc, interppSP, ptext, empty, hsep, punctuate, comma )
25 import Unique ( Uniquable )
26 import List ( elemIndex )
27 import Util ( zipEqual )
32 oclose :: Uniquable a => [FunDep a] -> UniqSet a -> UniqSet a
33 -- (oclose fds tvs) closes the set of type variables tvs,
34 -- wrt the functional dependencies fds. The result is a superset
35 -- of the argument set.
38 -- oclose [a -> b] {a} = {a,b}
39 -- oclose [a b -> c] {a} = {a}
40 -- oclose [a b -> c] {a,b} = {a,b,c}
41 -- If all of the things on the left of an arrow are in the set, add
42 -- the things on the right of that arrow.
45 case oclose1 fds vs of
47 (vs', True) -> oclose fds vs'
49 oclose1 [] vs = (vs, False)
50 oclose1 (fd@(ls, rs):fds) vs =
56 vs'b1@(vs', b1) = oclose1 fds vs
57 (vs'', b2) = ounion rs vs'
60 osubset (u:us) vs = if u `elementOfUniqSet` vs then osubset us vs else False
62 ounion [] ys = (ys, False)
64 | x `elementOfUniqSet` ys = (ys', b)
65 | otherwise = (addOneToUniqSet ys' x, True)
67 (ys', b) = ounion xs ys
69 instantiateFdClassTys :: Class -> [Type] -> [FunDep Type]
70 -- Get the FDs of the class, and instantiate them
71 instantiateFdClassTys clas tys
72 = [(map lookup us, map lookup vs) | (us,vs) <- fundeps]
74 (tyvars, fundeps) = classTvsFds clas
75 env = mkVarEnv (zipEqual "instantiateFdClassTys" tyvars tys)
76 lookup tv = lookupVarEnv_NF env tv
78 tyVarFunDep :: [FunDep Type] -> [FunDep TyVar]
80 = [(getTyvars xs, getTyvars ys) | (xs, ys) <- fdtys]
82 getTyvars = varSetElems . tyVarsOfTypes
84 pprFundeps :: Outputable a => [FunDep a] -> SDoc
86 pprFundeps fds = hsep (ptext SLIT("|") : punctuate comma (map ppr_fd fds))
88 ppr_fd (us, vs) = hsep [interppSP us, ptext SLIT("->"), interppSP vs]