@@ -24,6 +24,7 @@ module Rel8.Tabulate
2424 , similarity
2525 , difference
2626 , aggregateTabulation
27+ , orderTabulation
2728 , optionalTabulation
2829 , manyTabulation
2930 , someTabulation
@@ -35,6 +36,7 @@ import Control.Applicative ( liftA2 )
3536import Control.Monad ( join, liftM2 )
3637import Data.Bifunctor ( bimap, first )
3738import Data.Foldable ( traverse_ )
39+import Data.Functor.Contravariant ( (>$<) )
3840import Data.Maybe ( fromMaybe )
3941import Prelude hiding ( filter, lookup, undefined, zip, zipWith )
4042
@@ -42,11 +44,13 @@ import Prelude hiding ( filter, lookup, undefined, zip, zipWith )
4244import Rel8.Aggregate ( Aggregate )
4345import Rel8.Expr ( Expr )
4446import Rel8.Expr.Bool ( not_, true )
47+import Rel8.Order ( Order )
4548import Rel8.Query ( Query )
4649import Rel8.Query.Aggregate ( aggregate )
4750import Rel8.Query.Exists ( withBy, withoutBy )
4851import Rel8.Query.Filter ( filter, where_ )
4952import Rel8.Query.Maybe ( optional )
53+import Rel8.Query.Order ( orderBy )
5054import Rel8.Query.These ( alignBy )
5155import Rel8.Table ( Table )
5256import Rel8.Table.Aggregate ( groupBy, listAgg, nonEmptyAgg )
@@ -330,6 +334,15 @@ aggregateTabulation kas = do
330334 fromQuery $ aggregate $ bitraverse1 groupBy id <$> as
331335
332336
337+-- | 'orderTabulation' orders the /values/ of a 'Tabulation' (not the keys).
338+-- In general this is meaningless, but if used together with 'manyTabulation'
339+-- or 'someTabulation', the resulting lists will be ordered according to
340+-- ordering given to 'orderTabulation'.
341+orderTabulation :: Order a -> Tabulation k a -> Tabulation k a
342+orderTabulation ordering (Tabulation as) =
343+ Tabulation $ orderBy (snd >$< ordering) . as
344+
345+
333346optionalTabulation :: EqTable k
334347 => Tabulation k a -> Tabulation k (MaybeTable a)
335348optionalTabulation as = Tabulation $ \k -> do