Skip to content

Commit 29f6fe4

Browse files
authored
get, set, modify, insert, delete (#1)
* get and set functions * Typo * eslint * Tests * RowLacks for insert * Remove unused type arg
1 parent 85e73b6 commit 29f6fe4

File tree

4 files changed

+173
-2
lines changed

4 files changed

+173
-2
lines changed

bower.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,13 @@
1515
"test",
1616
"bower.json",
1717
"package.json"
18-
]
18+
],
19+
"dependencies": {
20+
"purescript-symbols": "^3.0.0",
21+
"purescript-functions": "^3.0.0",
22+
"purescript-typelevel-prelude": "^2.3.1"
23+
},
24+
"devDependencies": {
25+
"purescript-assert": "^3.0.0"
26+
}
1927
}

src/Data/Record.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"use strict";
2+
3+
exports.unsafeGet = function(label, rec) {
4+
return rec[label];
5+
};
6+
7+
exports.unsafeSet = function(label, value, rec) {
8+
var copy = {};
9+
for (var key in rec) {
10+
if ({}.hasOwnProperty.call(rec, key)) {
11+
copy[key] = rec[key];
12+
}
13+
}
14+
copy[label] = value;
15+
return copy;
16+
};
17+
18+
exports.unsafeDelete = function(label, rec) {
19+
var copy = {};
20+
for (var key in rec) {
21+
if (key !== label && {}.hasOwnProperty.call(rec, key)) {
22+
copy[key] = rec[key];
23+
}
24+
}
25+
return copy;
26+
};

src/Data/Record.purs

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,114 @@
1-
module Data.Record where
1+
module Data.Record
2+
( get
3+
, set
4+
, modify
5+
, insert
6+
, delete
7+
) where
8+
9+
import Data.Function.Uncurried (Fn2, Fn3, runFn2, runFn3)
10+
import Data.Symbol (class IsSymbol, SProxy, reflectSymbol)
11+
import Type.Row (class RowLacks)
12+
13+
foreign import unsafeGet :: forall r a. Fn2 String (Record r) a
14+
foreign import unsafeSet :: forall r1 r2 a. Fn3 String a (Record r1) (Record r2)
15+
foreign import unsafeDelete :: forall r1 r2. Fn2 String (Record r1) (Record r2)
16+
17+
-- | Get a property for a label which is specified using a value-level proxy for
18+
-- | a type-level string.
19+
-- |
20+
-- | For example:
21+
-- |
22+
-- | ```purescript
23+
-- | get (SProxy :: SProxy "x") :: forall r a. { x :: a | r } -> a
24+
-- | ```
25+
get
26+
:: forall r r' l a
27+
. IsSymbol l
28+
=> RowCons l a r' r
29+
=> SProxy l
30+
-> Record r
31+
-> a
32+
get l r = runFn2 unsafeGet (reflectSymbol l) r
33+
34+
-- | Set a property for a label which is specified using a value-level proxy for
35+
-- | a type-level string.
36+
-- |
37+
-- | For example:
38+
-- |
39+
-- | ```purescript
40+
-- | set (SProxy :: SProxy "x")
41+
-- | :: forall r a b. a -> { x :: b | r } -> { x :: a | r }
42+
-- | ```
43+
set
44+
:: forall r1 r2 r l a b
45+
. IsSymbol l
46+
=> RowCons l a r r1
47+
=> RowCons l b r r2
48+
=> SProxy l
49+
-> b
50+
-> Record r1
51+
-> Record r2
52+
set l b r = runFn3 unsafeSet (reflectSymbol l) b r
53+
54+
-- | Modify a property for a label which is specified using a value-level proxy for
55+
-- | a type-level string.
56+
-- |
57+
-- | For example:
58+
-- |
59+
-- | ```purescript
60+
-- | modify (SProxy :: SProxy "x")
61+
-- | :: forall r a b. (a -> b) -> { x :: a | r } -> { x :: b | r }
62+
-- | ```
63+
modify
64+
:: forall r1 r2 r l a b
65+
. IsSymbol l
66+
=> RowCons l a r r1
67+
=> RowCons l b r r2
68+
=> SProxy l
69+
-> (a -> b)
70+
-> Record r1
71+
-> Record r2
72+
modify l f r = set l (f (get l r)) r
73+
74+
-- | Insert a new property for a label which is specified using a value-level proxy for
75+
-- | a type-level string.
76+
-- |
77+
-- | For example:
78+
-- |
79+
-- | ```purescript
80+
-- | insert (SProxy :: SProxy "x")
81+
-- | :: forall r a. a -> { | r } -> { x :: a | r }
82+
-- | ```
83+
insert
84+
:: forall r1 r2 l a
85+
. IsSymbol l
86+
=> RowLacks l r1
87+
=> RowCons l a r1 r2
88+
=> SProxy l
89+
-> a
90+
-> Record r1
91+
-> Record r2
92+
insert l a r = runFn3 unsafeSet (reflectSymbol l) a r
93+
94+
-- | Delete a property for a label which is specified using a value-level proxy for
95+
-- | a type-level string.
96+
-- |
97+
-- | Note that the type of the resulting row must _lack_ the specified property.
98+
-- | Since duplicate labels are allowed, this is checked with a type class constraint.
99+
-- |
100+
-- | For example:
101+
-- |
102+
-- | ```purescript
103+
-- | delete (SProxy :: SProxy "x")
104+
-- | :: forall r a. RowLacks "x" r => { x :: a | r } -> { | r }
105+
-- | ```
106+
delete
107+
:: forall r1 r2 l a
108+
. IsSymbol l
109+
=> RowLacks l r1
110+
=> RowCons l a r1 r2
111+
=> SProxy l
112+
-> Record r2
113+
-> Record r1
114+
delete l r = runFn2 unsafeDelete (reflectSymbol l) r

test/Main.purs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module Test.Main where
2+
3+
import Prelude
4+
5+
import Control.Monad.Eff (Eff)
6+
import Data.Record (delete, get, insert, modify, set)
7+
import Data.Symbol (SProxy(..))
8+
import Test.Assert (ASSERT, assert')
9+
10+
main :: Eff (assert :: ASSERT) Unit
11+
main = do
12+
let x = SProxy :: SProxy "x"
13+
y = SProxy :: SProxy "y"
14+
15+
assert' "insert, get" $
16+
get x (insert x 42 {}) == 42
17+
assert' "insert, modify, get" $
18+
get x (modify x (_ + 1) (insert x 42 {})) == 43
19+
assert' "set, get" $
20+
get x (set x 0 { x: 42 }) == 0
21+
assert' "set, modify, get" $
22+
get x (modify x (_ + 1) (set x 0 { x: 42 })) == 1
23+
assert' "delete, get" $
24+
get x (delete y { x: 42, y: 1337 }) == 42

0 commit comments

Comments
 (0)