@@ -53,6 +53,8 @@ import Prelude ()
5353import Prelude.Compat
5454import Servant.API.Header
5555 (Header , Header' )
56+ import Servant.API.Modifiers
57+ (Optional , Strict )
5658import Servant.API.UVerb.Union
5759import qualified Data.SOP.BasicFunctors as SOP
5860import qualified Data.SOP.NS as SOP
@@ -158,35 +160,35 @@ instance (KnownSymbol h, GetHeadersFromHList rest, ToHttpApiData v)
158160-- * Adding headers
159161
160162-- We need all these fundeps to save type inference
161- class AddHeader (mods :: [* ]) h v orig new
162- | mods h v orig -> new , new -> mods , new -> h , new -> v , new -> orig where
163+ class AddHeader h v orig new (mods :: [* ])
164+ | h v orig mods -> new , new -> h , new -> v , new -> orig , new -> mods where
163165 addOptionalHeader :: ResponseHeader h v -> orig -> new -- ^ N.B.: The same header can't be added multiple times
164166
165167-- In this instance, we add a Header on top of something that is already decorated with some headers
166168instance {-# OVERLAPPING #-} ( KnownSymbol h , ToHttpApiData v )
167- => AddHeader mods h v (Headers (fst ': rest ) a ) (Headers (Header' mods h v ': fst ': rest ) a ) where
169+ => AddHeader h v (Headers (fst ': rest ) a ) (Headers (Header' mods h v ': fst ': rest ) a ) mods where
168170 addOptionalHeader hdr (Headers resp heads) = Headers resp (HCons hdr heads)
169171
170172-- In this instance, 'a' parameter is decorated with a Header.
171173instance {-# OVERLAPPABLE #-} ( KnownSymbol h , ToHttpApiData v , new ~ Headers '[Header' mods h v ] a )
172- => AddHeader mods h v a new where
174+ => AddHeader h v a new mods where
173175 addOptionalHeader hdr resp = Headers resp (HCons hdr HNil )
174176
175177-- Instances to decorate all responses in a 'Union' with headers. The functional
176178-- dependencies force us to consider singleton lists as the base case in the
177179-- recursion (it is impossible to determine h and v otherwise from old / new
178180-- responses if the list is empty).
179- instance (AddHeader mods h v old new ) => AddHeader mods h v (Union '[old ]) (Union '[new ]) where
181+ instance (AddHeader h v old new mods ) => AddHeader h v (Union '[old ]) (Union '[new ]) mods where
180182 addOptionalHeader hdr resp =
181183 SOP. Z $ SOP. I $ addOptionalHeader hdr $ SOP. unI $ SOP. unZ $ resp
182184
183185instance
184- ( AddHeader mods h v old new , AddHeader mods h v (Union oldrest ) (Union newrest )
186+ ( AddHeader h v old new mods , AddHeader h v (Union oldrest ) (Union newrest ) mods
185187 -- This ensures that the remainder of the response list is _not_ empty
186188 -- It is necessary to prevent the two instances for union types from
187189 -- overlapping.
188190 , oldrest ~ (a ': as ), newrest ~ (b ': bs ))
189- => AddHeader mods h v (Union (old ': (a ': as ))) (Union (new ': (b ': bs ))) where
191+ => AddHeader h v (Union (old ': (a ': as ))) (Union (new ': (b ': bs ))) mods where
190192 addOptionalHeader hdr resp = case resp of
191193 SOP. Z (SOP. I rHead) -> SOP. Z $ SOP. I $ addOptionalHeader hdr rHead
192194 SOP. S rOthers -> SOP. S $ addOptionalHeader hdr rOthers
@@ -211,15 +213,15 @@ instance
211213-- Note that while in your handlers type annotations are not required, since
212214-- the type can be inferred from the API type, in other cases you may find
213215-- yourself needing to add annotations.
214- addHeader :: AddHeader mods h v orig new => v -> orig -> new
216+ addHeader :: AddHeader h v orig new mods => v -> orig -> new
215217addHeader = addOptionalHeader . Header
216218
217219-- | Deliberately do not add a header to a value.
218220--
219221-- >>> let example1 = noHeader "hi" :: Headers '[Header "someheader" Int] String
220222-- >>> getHeaders example1
221223-- []
222- noHeader :: AddHeader mods h v orig new => orig -> new
224+ noHeader :: AddHeader h v orig new mods => orig -> new
223225noHeader = addOptionalHeader MissingHeader
224226
225227class HasResponseHeader h a headers where
0 commit comments