@@ -292,6 +292,121 @@ instance (KnownSymbol sym, HasClient sublayout)
292292
293293 where paramname = cs $ symbolVal (Proxy :: Proxy sym)
294294
295+-- | If you use a 'MatrixParam' in one of your endpoints in your API,
296+-- the corresponding querying function will automatically take
297+-- an additional argument of the type specified by your 'MatrixParam',
298+-- enclosed in Maybe.
299+--
300+-- If you give Nothing, nothing will be added to the query string.
301+--
302+-- If you give a non-'Nothing' value, this function will take care
303+-- of inserting a textual representation of this value in the query string.
304+--
305+-- You can control how values for your type are turned into
306+-- text by specifying a 'ToText' instance for your type.
307+--
308+-- Example:
309+--
310+-- > type MyApi = "books" :> MatrixParam "author" Text :> Get [Book]
311+-- >
312+-- > myApi :: Proxy MyApi
313+-- > myApi = Proxy
314+-- >
315+-- > getBooksBy :: Maybe Text -> BaseUrl -> EitherT String IO [Book]
316+-- > getBooksBy = client myApi
317+-- > -- then you can just use "getBooksBy" to query that endpoint.
318+-- > -- 'getBooksBy Nothing' for all books
319+-- > -- 'getBooksBy (Just "Isaac Asimov")' to get all books by Isaac Asimov
320+instance (KnownSymbol sym, ToText a, HasClient sublayout)
321+ => HasClient (MatrixParam sym a :> sublayout) where
322+
323+ type Client (MatrixParam sym a :> sublayout) =
324+ Maybe a -> Client sublayout
325+
326+ -- if mparam = Nothing, we don't add it to the query string
327+ clientWithRoute Proxy req mparam =
328+ clientWithRoute (Proxy :: Proxy sublayout) $
329+ maybe req (flip (appendToMatrixParams pname . Just) req) mparamText
330+
331+ where pname = symbolVal (Proxy :: Proxy sym)
332+ mparamText = fmap (cs . toText) mparam
333+
334+-- | If you use a 'MatrixParams' in one of your endpoints in your API,
335+-- the corresponding querying function will automatically take an
336+-- additional argument, a list of values of the type specified by your
337+-- 'MatrixParams'.
338+--
339+-- If you give an empty list, nothing will be added to the query string.
340+--
341+-- Otherwise, this function will take care of inserting a textual
342+-- representation of your values in the path segment string, under the
343+-- same matrix string parameter name.
344+--
345+-- You can control how values for your type are turned into text by
346+-- specifying a 'ToText' instance for your type.
347+--
348+-- Example:
349+--
350+-- > type MyApi = "books" :> MatrixParams "authors" Text :> Get [Book]
351+-- >
352+-- > myApi :: Proxy MyApi
353+-- > myApi = Proxy
354+-- >
355+-- > getBooksBy :: [Text] -> BaseUrl -> EitherT String IO [Book]
356+-- > getBooksBy = client myApi
357+-- > -- then you can just use "getBooksBy" to query that endpoint.
358+-- > -- 'getBooksBy []' for all books
359+-- > -- 'getBooksBy ["Isaac Asimov", "Robert A. Heinlein"]'
360+-- > -- to get all books by Asimov and Heinlein
361+instance (KnownSymbol sym, ToText a, HasClient sublayout)
362+ => HasClient (MatrixParams sym a :> sublayout) where
363+
364+ type Client (MatrixParams sym a :> sublayout) =
365+ [a] -> Client sublayout
366+
367+ clientWithRoute Proxy req paramlist =
368+ clientWithRoute (Proxy :: Proxy sublayout) $
369+ foldl' (\ req' value -> maybe req' (flip (appendToMatrixParams pname) req' . Just . cs) value) req paramlist'
370+
371+ where pname = cs pname'
372+ pname' = symbolVal (Proxy :: Proxy sym)
373+ paramlist' = map (Just . toText) paramlist
374+
375+-- | If you use a 'MatrixFlag' in one of your endpoints in your API,
376+-- the corresponding querying function will automatically take an
377+-- additional 'Bool' argument.
378+--
379+-- If you give 'False', nothing will be added to the path segment.
380+--
381+-- Otherwise, this function will insert a value-less matrix parameter
382+-- under the name associated to your 'MatrixFlag'.
383+--
384+-- Example:
385+--
386+-- > type MyApi = "books" :> MatrixFlag "published" :> Get [Book]
387+-- >
388+-- > myApi :: Proxy MyApi
389+-- > myApi = Proxy
390+-- >
391+-- > getBooks :: Bool -> BaseUrl -> EitherT String IO [Book]
392+-- > getBooks = client myApi
393+-- > -- then you can just use "getBooks" to query that endpoint.
394+-- > -- 'getBooksBy False' for all books
395+-- > -- 'getBooksBy True' to only get _already published_ books
396+instance (KnownSymbol sym, HasClient sublayout)
397+ => HasClient (MatrixFlag sym :> sublayout) where
398+
399+ type Client (MatrixFlag sym :> sublayout) =
400+ Bool -> Client sublayout
401+
402+ clientWithRoute Proxy req flag =
403+ clientWithRoute (Proxy :: Proxy sublayout) $
404+ if flag
405+ then appendToMatrixParams paramname Nothing req
406+ else req
407+
408+ where paramname = cs $ symbolVal (Proxy :: Proxy sym)
409+
295410-- | Pick a 'Method' and specify where the server you want to query is. You get
296411-- back the status code and the response body as a 'ByteString'.
297412instance HasClient Raw where