@@ -12,14 +12,20 @@ module Data.Ord
1212 , abs
1313 , signum
1414 , module Data.Ordering
15+ , class OrdRecord , compareRecord
1516 ) where
1617
17- import Data.Eq (class Eq , class Eq1 )
18+ import Data.Eq (class Eq , class Eq1 , class EqRecord , (/=))
19+ import Data.Symbol (class IsSymbol , SProxy (..), reflectSymbol )
1820import Data.Ord.Unsafe (unsafeCompare )
1921import Data.Ordering (Ordering (..))
2022import Data.Ring (class Ring , zero , one , negate )
2123import Data.Unit (Unit )
2224import Data.Void (Void )
25+ import Prim.Row as Row
26+ import Prim.RowList as RL
27+ import Record.Unsafe (unsafeGet )
28+ import Type.Data.RowList (RLProxy (..))
2329
2430-- | The `Ord` type class represents types which support comparisons with a
2531-- | _total order_.
@@ -169,36 +175,32 @@ class Eq1 f <= Ord1 f where
169175instance ord1Array :: Ord1 Array where
170176 compare1 = compare
171177
172- -- Ordering for records is currently unimplemented as there are outstanding
173- -- questions around whether this implementation be useful. This is because it
174- -- prioritises the keys alphabetically, and this behaviour isn't overridable.
175- -- For now, we leave this unavailable, but the implementation is as follows:
176-
177- -- class EqRecord rowlist row focus <= OrdRecord rowlist row focus | rowlist -> focus where
178- -- compareImpl :: RLProxy rowlist -> Record row -> Record row -> Ordering
179- --
180- -- instance ordRecordNil :: OrdRecord RL.Nil row focus where
181- -- compareImpl _ _ _ = EQ
182- --
183- -- instance ordRecordCons
184- -- :: ( OrdRecord rowlistTail row subfocus
185- -- , Row.Cons key focus rowTail row
186- -- , IsSymbol key
187- -- , Ord focus
188- -- )
189- -- => OrdRecord (RL.Cons key focus rowlistTail) row focus where
190- -- compareImpl _ ra rb
191- -- = if left /= EQ
192- -- then left
193- -- else compareImpl (RLProxy :: RLProxy rowlistTail) ra rb
194- -- where
195- -- key = reflectSymbol (SProxy :: SProxy key)
196- -- unsafeGet' = unsafeGet :: String -> Record row -> focus
197- -- left = unsafeGet' key ra `compare` unsafeGet' key rb
198- --
199- -- instance ordRecord
200- -- :: ( RL.RowToList row list
201- -- , OrdRecord list row focus
202- -- )
203- -- => Ord (Record row) where
204- -- compare = compareImpl (RLProxy :: RLProxy list)
178+ class EqRecord rowlist row <= OrdRecord rowlist row where
179+ compareRecord :: RLProxy rowlist -> Record row -> Record row -> Ordering
180+
181+ instance ordRecordNil :: OrdRecord RL.Nil row where
182+ compareRecord _ _ _ = EQ
183+
184+ instance ordRecordCons
185+ :: ( OrdRecord rowlistTail row
186+ , Row.Cons key focus rowTail row
187+ , IsSymbol key
188+ , Ord focus
189+ )
190+ => OrdRecord (RL.Cons key focus rowlistTail ) row where
191+ compareRecord _ ra rb
192+ = if left /= EQ
193+ then left
194+ else compareRecord (RLProxy :: RLProxy rowlistTail ) ra rb
195+ where
196+ key = reflectSymbol (SProxy :: SProxy key )
197+ unsafeGet' = unsafeGet :: String -> Record row -> focus
198+ left = unsafeGet' key ra `compare` unsafeGet' key rb
199+
200+ instance ordRecord
201+ :: ( RL.RowToList row list
202+ , OrdRecord list row
203+ )
204+ => Ord (Record row ) where
205+ compare = compareRecord (RLProxy :: RLProxy list )
206+
0 commit comments