@@ -1,3 +1,4 @@
1module Type.Alias (realias, rules, canonicalRealias, Rules) where
2module Type.Alias (realias, rules, canonicalRealias, Rules) where
3import Control.Applicative ((<$>),(<*>))
4import Control.Applicative ((<$>),(<*>))
@@ -30,10 +31,9 @@ localizer moduleImports = go
31 case tipe of
32 case tipe of
32 Var _ -> tipe
33 Var _ -> tipe
34 Lambda t1 t2 -> Lambda (go t1) (go t2)
34 Lambda t1 t2 -> Lambda (go t1) (go t2)
35 Data name ts -> Data (localize name) (map go ts)
35 Data name ts -> Data (localize name) (map go ts)
36− Record fs ext -> Record (map (second go) fs) (go ext)
36+ Record fs ext -> Record (map (second go) fs) ext
38 byMethod = foldr (\(n,m) d -> Map.insertWith (++) n [m] d)
38 byMethod = foldr (\(n,m) d -> Map.insertWith (++) n [m] d)
39 Map.empty moduleImports
39 Map.empty moduleImports
@@ -83,10 +83,9 @@ canonicalRealias aliases tipe =
84 case tipe of
84 case tipe of
85 Var _ -> tipe
85 Var _ -> tipe
87 Lambda t1 t2 -> Lambda (f t1) (f t2)
86 Lambda t1 t2 -> Lambda (f t1) (f t2)
88 Data name ts -> Data name (map f ts)
87 Data name ts -> Data name (map f ts)
89− Record fs ext -> Record (map (second f) fs) (f ext)
88+ Record fs ext -> Record (map (second f) fs) ext
91allEqual [] = True
90allEqual [] = True
92allEqual (x:xs) = all (==x) xs
91allEqual (x:xs) = all (==x) xs
@@ -102,8 +101,7 @@ bestType tipes = fst $ List.minimumBy (\a b -> compare (snd a) (snd b)) pairs
102 Lambda t1 t2 -> numFields t1 + numFields t2
101 Lambda t1 t2 -> numFields t1 + numFields t2
103 Var _ -> 0
102 Var _ -> 0
104 Data _ ts -> sum (map numFields ts)
103 Data _ ts -> sum (map numFields ts)
106− Record fields ext -> length fields + sum (map (numFields . snd) fields) + numFields ext
104+ Record fields _ -> length fields + sum (map (numFields . snd) fields)
108diff :: Type -> Type -> Maybe [(String,Type)]
106diff :: Type -> Type -> Maybe [(String,Type)]
109diff general specific =
107diff general specific =
@@ -113,11 +111,11 @@ diff general specific =
113 (Data gname gts, Data sname sts)
111 (Data gname gts, Data sname sts)
114 | gname == sname && length gts == length sts ->
112 | gname == sname && length gts == length sts ->
115 concat <$> zipWithM diff gts sts
113 concat <$> zipWithM diff gts sts
116− (EmptyRecord, EmptyRecord) -> Just []
114+ (Record [] Nothing, Record [] Nothing) -> Just []
117− (Record _ _, Record _ _) ->
115+ (Record _ _, Record [] Nothing) -> Nothing
118− let (gfs,gext) = collectRecords general
116+ (Record [] Nothing, Record _ _) -> Nothing
119− (sfs,sext) = collectRecords specific
117+ (Record gfs gext, Record sfs sext) ->
120− gfields = collectFields gfs
118+ let gfields = collectFields gfs
121 sfields = collectFields sfs
119 sfields = collectFields sfs
123 overlap = Map.intersectionWith (\gs ss -> length gs == length ss) sfields gfields
121 overlap = Map.intersectionWith (\gs ss -> length gs == length ss) sfields gfields
@@ -126,10 +124,12 @@ diff general specific =
126 case isAligned of
124 case isAligned of
127 False -> Nothing
125 False -> Nothing
128 True -> let remaining = Map.difference sfields gfields
126 True -> let remaining = Map.difference sfields gfields
127+ sext' = case sext of
129− sext' = if Map.null remaining then sext else
128+ Just x | Map.null remaining -> Var x
130− Record (flattenFields remaining) sext
129+ _ -> Record (flattenFields remaining) sext
130+ gext' = maybe (Record [] Nothing) Var gext
131 matchMap = Map.intersectionWith (zipWith diff) gfields sfields
131 matchMap = Map.intersectionWith (zipWith diff) gfields sfields
132− in concat <$> sequence (diff gext sext' : concat (Map.elems matchMap))
132+ in concat <$> sequence (diff gext' sext' : concat (Map.elems matchMap))
133 (_,_) -> Nothing
133 (_,_) -> Nothing
135collectFields fields =
135collectFields fields =