Skip to content

Commit d39eb6e

Browse files
justinwoopaf31
authored andcommitted
add equal function (#4)
1 parent 686c179 commit d39eb6e

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

src/Data/Record.purs

+34-2
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ module Data.Record
44
, modify
55
, insert
66
, delete
7+
, equal
8+
, class EqualFields
9+
, equalFields
710
) where
811

912
import Data.Function.Uncurried (runFn2, runFn3)
1013
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)
1317

1418
-- | Get a property for a label which is specified using a value-level proxy for
1519
-- | a type-level string.
@@ -109,3 +113,31 @@ delete
109113
-> Record r2
110114
-> Record r1
111115
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

test/Main.purs

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ module Test.Main where
33
import Prelude
44

55
import Control.Monad.Eff (Eff)
6-
import Data.Record (delete, get, insert, modify, set)
76
import Data.Record.Builder as Builder
7+
import Data.Record (delete, get, insert, modify, set, equal)
88
import Data.Symbol (SProxy(..))
99
import Test.Assert (ASSERT, assert')
1010

@@ -23,6 +23,10 @@ main = do
2323
get x (modify x (_ + 1) (set x 0 { x: 42 })) == 1
2424
assert' "delete, get" $
2525
get x (delete y { x: 42, y: 1337 }) == 42
26+
assert' "equal" $
27+
equal { a: 1, b: "b", c: true } { a: 1, b: "b", c: true }
28+
assert' "equal2" $
29+
not $ equal { a: 1, b: "b", c: true } { a: 1, b: "b", c: false }
2630

2731
let testBuilder = Builder.build (Builder.insert x 42
2832
>>> Builder.merge { y: true, z: "testing" }

0 commit comments

Comments
 (0)