@@ -27,6 +27,7 @@ module Rel8.Tabulate
27 , difference
27 , difference
28 , aggregateTabulation
28 , aggregateTabulation
29 , orderTabulation
29 , orderTabulation
30 , optionalTabulation
31 , optionalTabulation
31 , manyTabulation
32 , manyTabulation
32 , someTabulation
33 , someTabulation
@@ -55,7 +56,7 @@ import Rel8.Query.Maybe ( optional )
55import Rel8.Query.Order ( orderBy )
56import Rel8.Query.Order ( orderBy )
56import Rel8.Query.These ( alignBy )
57import Rel8.Query.These ( alignBy )
57import Rel8.Table ( Table )
58import Rel8.Table ( Table )
58−import Rel8.Table.Aggregate ( groupBy, listAgg, nonEmptyAgg )
59+import Rel8.Table.Aggregate ( groupBy, headAgg, listAgg, nonEmptyAgg )
59import Rel8.Table.Alternative
60import Rel8.Table.Alternative
60 ( AltTable, (<|>:)
61 ( AltTable, (<|>:)
61 , AlternativeTable, emptyTable
62 , AlternativeTable, emptyTable
@@ -368,6 +369,14 @@ orderTabulation ordering (Tabulation as) =
368 Tabulation $ orderBy (snd >$< ordering) . as
369 Tabulation $ orderBy (snd >$< ordering) . as
372+-- | Turns the given 'Tabulation' from a \"multimap\" into a \"map\". If there
373+-- is more than one value at a particular key, only the first one is kept.
374+-- \"First\" is in general undefined, but 'orderTabulation' can be used to
375+-- make it deterministic.
376+singularize :: (EqTable k, Table Expr a) => Tabulation k a -> Tabulation k a
377+singularize = aggregateTabulation . fmap headAgg
371optionalTabulation :: EqTable k
380optionalTabulation :: EqTable k
372 => Tabulation k a -> Tabulation k (MaybeTable a)
381 => Tabulation k a -> Tabulation k (MaybeTable a)
373optionalTabulation as = Tabulation $ \case
382optionalTabulation as = Tabulation $ \case