Skip to content

Commit fae9e76

Browse files
authored
Merge pull request #208 from kl0tl/record-bounded-instance
Add `Bounded` instance for records
2 parents c7b312a + 5e3bf30 commit fae9e76

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

src/Data/Bounded.purs

+46-1
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,17 @@ module Data.Bounded
33
, bottom
44
, top
55
, module Data.Ord
6+
, class BoundedRecord, bottomRecord, topRecord
67
) where
78

8-
import Data.Ord (class Ord, Ordering(..), compare, (<), (<=), (>), (>=))
9+
import Data.Ord (class Ord, class OrdRecord, Ordering(..), compare, (<), (<=), (>), (>=))
10+
import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
911
import Data.Unit (Unit, unit)
12+
import Prim.Row as Row
13+
import Prim.RowList as RL
14+
import Record.Unsafe (unsafeSet)
15+
import Type.Data.Row (RProxy(..))
16+
import Type.Data.RowList (RLProxy(..))
1017

1118
-- | The `Bounded` type class represents totally ordered types that have an
1219
-- | upper and lower boundary.
@@ -54,3 +61,41 @@ foreign import bottomNumber :: Number
5461
instance boundedNumber :: Bounded Number where
5562
top = topNumber
5663
bottom = bottomNumber
64+
65+
class OrdRecord rowlist row <= BoundedRecord rowlist row subrow | rowlist -> subrow where
66+
topRecord :: RLProxy rowlist -> RProxy row -> Record subrow
67+
bottomRecord :: RLProxy rowlist -> RProxy row -> Record subrow
68+
69+
instance boundedRecordNil :: BoundedRecord RL.Nil row () where
70+
topRecord _ _ = {}
71+
bottomRecord _ _ = {}
72+
73+
instance boundedRecordCons
74+
:: ( IsSymbol key
75+
, Bounded focus
76+
, Row.Cons key focus rowTail row
77+
, Row.Cons key focus subrowTail subrow
78+
, BoundedRecord rowlistTail row subrowTail
79+
)
80+
=> BoundedRecord (RL.Cons key focus rowlistTail) row subrow where
81+
topRecord _ rowProxy
82+
= insert top tail
83+
where
84+
key = reflectSymbol (SProxy :: SProxy key)
85+
insert = unsafeSet key :: focus -> Record subrowTail -> Record subrow
86+
tail = topRecord (RLProxy :: RLProxy rowlistTail) rowProxy
87+
88+
bottomRecord _ rowProxy
89+
= insert bottom tail
90+
where
91+
key = reflectSymbol (SProxy :: SProxy key)
92+
insert = unsafeSet key :: focus -> Record subrowTail -> Record subrow
93+
tail = bottomRecord (RLProxy :: RLProxy rowlistTail) rowProxy
94+
95+
instance boundedRecord
96+
:: ( RL.RowToList row list
97+
, BoundedRecord list row row
98+
)
99+
=> Bounded (Record row) where
100+
top = topRecord (RLProxy :: RLProxy list) (RProxy :: RProxy row)
101+
bottom = bottomRecord (RLProxy :: RLProxy list) (RProxy :: RProxy row)

test/Test/Main.purs

+6-1
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,9 @@ testRecordInstances = do
149149
testOrd { a: 42, b: "hello" } { a: 42, b: "hello" } EQ
150150
testOrd { a: 42, b: "hell" } { a: 42, b: "hello" } LT
151151
testOrd { a: 42, b: "hello" } { a: 42, b: "hell" } GT
152-
152+
assert "Record bottom" $
153+
(bottom :: { a :: Boolean }).a
154+
== bottom
155+
assert "Record top" $
156+
(top :: { a :: Boolean }).a
157+
== top

0 commit comments

Comments
 (0)