@@ -1,4 +1,6 @@
1+{-# language AllowAmbiguousTypes #-}
12{-# language DataKinds #-}
3+{-# language DefaultSignatures #-}
24{-# language FlexibleInstances #-}
35{-# language NamedFieldPuns #-}
46{-# language ScopedTypeVariables #-}
@@ -10,7 +12,7 @@
1012{-# language ViewPatterns #-}
1113
1214module Rel8.Table.Ord
13− ( OrdTable, (<:), (<=:), (>:), (>=:), least, greatest
15+ ( OrdTable( ordTable ), (<:), (<=:), (>:), (>=:), least, greatest
1416 )
1517where
1618
@@ -24,7 +26,6 @@ import Rel8.Expr ( Expr, Col(..) )
2426import Rel8.Expr.Bool ( (||.), (&&.), false, true )
2527import Rel8.Expr.Eq ( (==.) )
2628import Rel8.Expr.Ord ( (<.), (>.) )
27−import Rel8.Opaque ( Opaque )
2829import Rel8.Schema.Dict ( Dict( Dict ) )
2930import Rel8.Schema.HTable ( HConstrainTable, htabulateA, hfield, hdicts )
3031import Rel8.Schema.Spec.ConstrainDBType ( ConstrainDBType )
@@ -32,21 +33,24 @@ import Rel8.Table ( Columns, toColumns )
3233import Rel8.Table.Bool ( bool )
3334import Rel8.Table.Eq ( EqTable )
3435import Rel8.Type.Ord ( DBOrd )
36+import Rel8.Schema.Nullability (Sql)
3537
3638
3739-- | The class of 'Table's that can be ordered. Ordering on tables is defined
3840-- by their lexicographic ordering of all columns, so this class means "all
3941-- columns in a 'Table' have an instance of 'DBOrd'".
4042type OrdTable :: Type -> Constraint
41−class
42− ( EqTable a
43− , HConstrainTable (Columns a) (ConstrainDBType DBOrd)
44− ) => OrdTable a
45−instance
46− ( EqTable a
47− , HConstrainTable (Columns a) (ConstrainDBType DBOrd)
48− ) => OrdTable a
49−instance {-# OVERLAPPING #-} OrdTable Opaque
43+class EqTable a => OrdTable a where
44+ ordTable :: Columns a (Dict (ConstrainDBType DBOrd))
45+
46+ default ordTable :: HConstrainTable (Columns a) (ConstrainDBType DBOrd) => Columns a (Dict (ConstrainDBType DBOrd))
47+ ordTable = hdicts @(Columns a) @(ConstrainDBType DBOrd)
48+
49+
50+instance (EqTable (t Expr), f ~ Expr, HConstrainTable (Columns (t Expr)) (ConstrainDBType DBOrd)) => OrdTable (t f)
51+
52+
53+instance Sql DBOrd a => OrdTable (Expr a)
5054
5155
5256-- | Test if one 'Table' sorts before another. Corresponds to comparing all
@@ -55,10 +59,9 @@ instance {-# OVERLAPPING #-} OrdTable Opaque
5559(toColumns -> as) <: (toColumns -> bs) =
5660 foldr @[] go false $ getConst $ htabulateA $ \field ->
5761 case (hfield as field, hfield bs field) of
58− (DB a, DB b) -> case hfield dicts field of
62+ (DB a, DB b) -> case hfield (ordTable @a) field of
5963 Dict -> Const [(a <. b, a ==. b)]
6064 where
61− dicts = hdicts @(Columns a) @(ConstrainDBType DBOrd)
6265 go (lt, eq) a = lt ||. (eq &&. a)
6366infix 4 <:
6467
@@ -69,10 +72,9 @@ infix 4 <:
6972(toColumns -> as) <=: (toColumns -> bs) =
7073 foldr @[] go true $ getConst $ htabulateA $ \field ->
7174 case (hfield as field, hfield bs field) of
72− (DB a, DB b) -> case hfield dicts field of
75+ (DB a, DB b) -> case hfield (ordTable @a) field of
7376 Dict -> Const [(a <. b, a ==. b)]
7477 where
75− dicts = hdicts @(Columns a) @(ConstrainDBType DBOrd)
7678 go (lt, eq) a = lt ||. (eq &&. a)
7779infix 4 <=:
7880
@@ -83,10 +85,9 @@ infix 4 <=:
8385(toColumns -> as) >: (toColumns -> bs) =
8486 foldr @[] go false $ getConst $ htabulateA $ \field ->
8587 case (hfield as field, hfield bs field) of
86− (DB a, DB b) -> case hfield dicts field of
88+ (DB a, DB b) -> case hfield (ordTable @a) field of
8789 Dict -> Const [(a >. b, a ==. b)]
8890 where
89− dicts = hdicts @(Columns a) @(ConstrainDBType DBOrd)
9091 go (gt, eq) a = gt ||. (eq &&. a)
9192infix 4 >:
9293
@@ -97,10 +98,9 @@ infix 4 >:
9798(toColumns -> as) >=: (toColumns -> bs) =
9899 foldr @[] go true $ getConst $ htabulateA $ \field ->
99100 case (hfield as field, hfield bs field) of
100− (DB a, DB b) -> case hfield dicts field of
101+ (DB a, DB b) -> case hfield (ordTable @a) field of
101102 Dict -> Const [(a >. b, a ==. b)]
102103 where
103− dicts = hdicts @(Columns a) @(ConstrainDBType DBOrd)
104104 go (gt, eq) a = gt ||. (eq &&. a)
105105infix 4 >=:
106106