@@ -4,12 +4,16 @@ module Data.Record
4
4
, modify
5
5
, insert
6
6
, delete
7
+ , equal
8
+ , class EqualFields
9
+ , equalFields
7
10
) where
8
11
9
12
import Data.Function.Uncurried (runFn2 , runFn3 )
10
13
import Data.Record.Unsafe (unsafeGetFn , unsafeSetFn , unsafeDeleteFn )
11
- import Data.Symbol (class IsSymbol , SProxy , reflectSymbol )
12
- import Type.Row (class RowLacks )
14
+ import Data.Symbol (class IsSymbol , SProxy (..), reflectSymbol )
15
+ import Prelude (class Eq , (&&), (==))
16
+ import Type.Row (class RowLacks , class RowToList , Cons , Nil , RLProxy (RLProxy), kind RowList )
13
17
14
18
-- | Get a property for a label which is specified using a value-level proxy for
15
19
-- | a type-level string.
@@ -109,3 +113,31 @@ delete
109
113
-> Record r2
110
114
-> Record r1
111
115
delete l r = runFn2 unsafeDeleteFn (reflectSymbol l) r
116
+
117
+ -- | Check two records of the same type for equality.
118
+ equal
119
+ :: forall r rs
120
+ . RowToList r rs
121
+ => EqualFields rs r
122
+ => Record r
123
+ -> Record r
124
+ -> Boolean
125
+ equal a b = equalFields (RLProxy :: RLProxy rs ) a b
126
+
127
+ class EqualFields (rs :: RowList ) (row :: # Type ) | rs -> row where
128
+ equalFields :: RLProxy rs -> Record row -> Record row -> Boolean
129
+
130
+ instance equalFieldsCons
131
+ ::
132
+ ( IsSymbol name
133
+ , Eq ty
134
+ , RowCons name ty tailRow row
135
+ , EqualFields tail row
136
+ ) => EqualFields (Cons name ty tail ) row where
137
+ equalFields _ a b = get' a == get' b && equalRest a b
138
+ where
139
+ get' = get (SProxy :: SProxy name )
140
+ equalRest = equalFields (RLProxy :: RLProxy tail )
141
+
142
+ instance equalFieldsNil :: EqualFields Nil row where
143
+ equalFields _ _ _ = true
0 commit comments