2 -- (c) The University of Glasgow
12 availsToNameSetWithSelectors
,
14 availName
, availNames
, availNonFldNames
,
15 availNamesWithSelectors
,
31 -- -----------------------------------------------------------------------------
34 -- | Records what things are "available", i.e. in scope
35 data AvailInfo
= Avail IsPatSyn Name
-- ^ An ordinary identifier in scope
39 -- ^ A type or class in scope. Parameters:
41 -- 1) The name of the type or class
42 -- 2) The available pieces of type or class,
43 -- excluding field selectors.
44 -- 3) The record fields of the type
45 -- (see Note [Representing fields in AvailInfo]).
47 -- The AvailTC Invariant:
48 -- * If the type or class is itself
49 -- to be in scope, it must be
50 -- *first* in this list. Thus,
51 -- typically: @AvailTC Eq [Eq, ==, \/=]@
53 -- Equality used when deciding if the
54 -- interface has changed
56 data IsPatSyn
= NotPatSyn | IsPatSyn
deriving Eq
58 -- | A collection of 'AvailInfo' - several things that are \"available\"
59 type Avails
= [AvailInfo
]
62 Note [Representing fields in AvailInfo]
63 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
64 When -XDuplicateRecordFields is disabled (the normal case), a
67 data T = MkT { foo :: Int }
69 gives rise to the AvailInfo
71 AvailTC T [T, MkT] [FieldLabel "foo" False foo],
73 whereas if -XDuplicateRecordFields is enabled it gives
75 AvailTC T [T, MkT] [FieldLabel "foo" True $sel:foo:MkT]
77 since the label does not match the selector name.
79 The labels in a field list are not necessarily unique:
80 data families allow the same parent (the family tycon) to have
81 multiple distinct fields with the same label. For example,
84 data instance F Int = MkFInt { foo :: Int }
85 data instance F Bool = MkFBool { foo :: Bool}
89 AvailTC F [F, MkFInt, MkFBool]
90 [FieldLabel "foo" True $sel:foo:MkFInt, FieldLabel "foo" True $sel:foo:MkFBool].
92 Moreover, note that the flIsOverloaded flag need not be the same for
93 all the elements of the list. In the example above, this occurs if
94 the two data instances are defined in different modules, one with
95 `-XDuplicateRecordFields` enabled and one with it disabled. Thus it
98 AvailTC F [F, MkFInt, MkFBool]
99 [FieldLabel "foo" True $sel:foo:MkFInt, FieldLabel "foo" False foo].
101 If the two data instances are defined in different modules, both
102 without `-XDuplicateRecordFields`, it will be impossible to export
103 them from the same module (even with `-XDuplicateRecordfields`
104 enabled), because they would be represented identically. The
105 workaround here is to enable `-XDuplicateRecordFields` on the defining
109 -- | Compare lexicographically
110 stableAvailCmp
:: AvailInfo
-> AvailInfo
-> Ordering
111 stableAvailCmp
(Avail _ n1
) (Avail _ n2
) = n1 `stableNameCmp` n2
112 stableAvailCmp
(Avail
{}) (AvailTC
{}) = LT
113 stableAvailCmp
(AvailTC n ns nfs
) (AvailTC m ms mfs
) =
114 (n `stableNameCmp` m
) `thenCmp`
115 (cmpList stableNameCmp ns ms
) `thenCmp`
116 (cmpList
(stableNameCmp `on` flSelector
) nfs mfs
)
117 stableAvailCmp
(AvailTC
{}) (Avail
{}) = GT
119 patSynAvail
:: Name
-> AvailInfo
120 patSynAvail n
= Avail IsPatSyn n
122 avail
:: Name
-> AvailInfo
123 avail n
= Avail NotPatSyn n
125 -- -----------------------------------------------------------------------------
126 -- Operations on AvailInfo
128 availsToNameSet
:: [AvailInfo
] -> NameSet
129 availsToNameSet avails
= foldr add emptyNameSet avails
130 where add avail set
= extendNameSetList set
(availNames avail
)
132 availsToNameSetWithSelectors
:: [AvailInfo
] -> NameSet
133 availsToNameSetWithSelectors avails
= foldr add emptyNameSet avails
134 where add avail set
= extendNameSetList set
(availNamesWithSelectors avail
)
136 availsToNameEnv
:: [AvailInfo
] -> NameEnv AvailInfo
137 availsToNameEnv avails
= foldr add emptyNameEnv avails
138 where add avail env
= extendNameEnvList env
139 (zip (availNames avail
) (repeat avail
))
141 -- | Just the main name made available, i.e. not the available pieces
142 -- of type or class brought into scope by the 'GenAvailInfo'
143 availName
:: AvailInfo
-> Name
144 availName
(Avail _ n
) = n
145 availName
(AvailTC n _ _
) = n
147 -- | All names made available by the availability information (excluding overloaded selectors)
148 availNames
:: AvailInfo
-> [Name
]
149 availNames
(Avail _ n
) = [n
]
150 availNames
(AvailTC _ ns fs
) = ns
++ [ flSelector f | f
<- fs
, not (flIsOverloaded f
) ]
152 -- | All names made available by the availability information (including overloaded selectors)
153 availNamesWithSelectors
:: AvailInfo
-> [Name
]
154 availNamesWithSelectors
(Avail _ n
) = [n
]
155 availNamesWithSelectors
(AvailTC _ ns fs
) = ns
++ map flSelector fs
157 -- | Names for non-fields made available by the availability information
158 availNonFldNames
:: AvailInfo
-> [Name
]
159 availNonFldNames
(Avail _ n
) = [n
]
160 availNonFldNames
(AvailTC _ ns _
) = ns
162 -- | Fields made available by the availability information
163 availFlds
:: AvailInfo
-> [FieldLabel
]
164 availFlds
(AvailTC _ _ fs
) = fs
167 -- -----------------------------------------------------------------------------
170 instance Outputable AvailInfo
where
173 pprAvail
:: AvailInfo
-> SDoc
176 pprAvail
(AvailTC n ns fs
)
177 = ppr n
<> braces
(sep
[ fsep
(punctuate comma
(map ppr ns
)) <> semi
178 , fsep
(punctuate comma
(map (ppr
. flLabel
) fs
))])
180 instance Binary AvailInfo
where
181 put_ bh
(Avail b aa
) = do
185 put_ bh
(AvailTC ab ac ad
) = do
199 return (AvailTC ab ac ad
)
201 instance Binary IsPatSyn
where
202 put_ bh IsPatSyn
= putByte bh
0
203 put_ bh NotPatSyn
= putByte bh
1
208 _
-> return NotPatSyn