Skip to content

Commit 7a691ce

Browse files
authored
Merge pull request #180 from LiamGoodacre/feature/ord-record
Add/finish Ord instance for Records
2 parents f9bde67 + 4dcefed commit 7a691ce

File tree

2 files changed

+42
-34
lines changed

2 files changed

+42
-34
lines changed

src/Data/Ord.purs

+36-34
Original file line numberDiff line numberDiff line change
@@ -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)
1820
import Data.Ord.Unsafe (unsafeCompare)
1921
import Data.Ordering (Ordering(..))
2022
import Data.Ring (class Ring, zero, one, negate)
2123
import Data.Unit (Unit)
2224
import 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
169175
instance 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+

test/Test/Main.purs

+6
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,9 @@ testRecordInstances = do
144144
{ a: true, b: false, c: true, d: false }
145145
{ a: true, b: true, c: false, d: false }
146146
== { a: true, b: true, c: false, d: true }
147+
testOrd { a: 0, b: "hello" } { a: 42, b: "hello" } LT
148+
testOrd { a: 42, b: "hello" } { a: 0, b: "hello" } GT
149+
testOrd { a: 42, b: "hello" } { a: 42, b: "hello" } EQ
150+
testOrd { a: 42, b: "hell" } { a: 42, b: "hello" } LT
151+
testOrd { a: 42, b: "hello" } { a: 42, b: "hell" } GT
152+

0 commit comments

Comments
 (0)