Skip to content

Commit

Permalink
Merge pull request #612 from sanctuary-js/davidchambers/value
Browse files Browse the repository at this point in the history
strmap: add S.value
  • Loading branch information
davidchambers authored Apr 5, 2019
2 parents 6ecba34 + c921816 commit 507d749
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 27 deletions.
46 changes: 37 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -487,11 +487,6 @@
};
}

// value :: { value :: a } -> a
function value(r) {
return r.value;
}

// :: Type
var a = $.TypeVariable ('a');
var b = $.TypeVariable ('b');
Expand Down Expand Up @@ -2283,7 +2278,7 @@
//. ['foo', 'baz']
//. ```
function justs(maybes) {
return map (value) (filter (isJust) (maybes));
return map (prop ('value')) (filter (isJust) (maybes));
}
_.justs = {
consts: {f: [Z.Filterable, Z.Functor]},
Expand Down Expand Up @@ -2557,7 +2552,7 @@
_.lefts = {
consts: {f: [Z.Filterable, Z.Functor]},
types: [f ($Either (a) (b)), f (a)],
impl: B (map (value)) (filter (isLeft))
impl: B (map (prop ('value'))) (filter (isLeft))
};

//# rights :: (Filterable f, Functor f) => f (Either a b) -> f b
Expand All @@ -2574,7 +2569,7 @@
_.rights = {
consts: {f: [Z.Filterable, Z.Functor]},
types: [f ($Either (a) (b)), f (b)],
impl: B (map (value)) (filter (isRight))
impl: B (map (prop ('value'))) (filter (isRight))
};

//# tagBy :: (a -> Boolean) -> a -> Either a a
Expand Down Expand Up @@ -3830,6 +3825,7 @@
//. lacks the specified property, a type error is thrown.
//.
//. For accessing properties of uncertain objects, use [`get`](#get) instead.
//. For accessing string map values by key, use [`value`](#value) instead.
//.
//. ```javascript
//. > S.prop ('a') ({a: 1, b: 2})
Expand Down Expand Up @@ -3884,7 +3880,7 @@
//. value of the specified object property if it exists and the value
//. satisfies the given predicate; Nothing otherwise.
//.
//. See also [`gets`](#gets) and [`prop`](#prop).
//. See also [`gets`](#gets), [`prop`](#prop), and [`value`](#value).
//.
//. ```javascript
//. > S.get (S.is ($.Number)) ('x') ({x: 1, y: 2})
Expand Down Expand Up @@ -3952,6 +3948,38 @@
//. [type identifier][] is `'Object'` and the values of its enumerable own
//. properties are all members of type `a`.

//# value :: String -> StrMap a -> Maybe a
//.
//. Retrieve the value associated with the given key in the given string map.
//.
//. Formally, `value (k) (m)` evaluates to `Just (m[k])` if `k` is an
//. enumerable own property of `m`; `Nothing` otherwise.
//.
//. See also [`prop`](#prop) and [`get`](#get).
//.
//. ```javascript
//. > S.value ('foo') ({foo: 1, bar: 2})
//. Just (1)
//.
//. > S.value ('bar') ({foo: 1, bar: 2})
//. Just (2)
//.
//. > S.value ('baz') ({foo: 1, bar: 2})
//. Nothing
//. ```
function value(key) {
return function(strMap) {
return Object.prototype.propertyIsEnumerable.call (strMap, key) ?
Just (strMap[key]) :
Nothing;
};
}
_.value = {
consts: {},
types: [$.String, $.StrMap (a), $Maybe (a)],
impl: value
};

//# singleton :: String -> a -> StrMap a
//.
//. Takes a string and a value of any type, and returns a string map with
Expand Down
29 changes: 29 additions & 0 deletions test/internal/strMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';

const proto = Object.create (null);

Object.defineProperty (
proto,
'non-enumerable inherited property',
{enumerable: false, value: 'non-enumerable inherited property'}
);
Object.defineProperty (
proto,
'enumerable inherited property',
{enumerable: true, value: 'enumerable inherited property'}
);

const strMap = Object.create (proto);

Object.defineProperty (
strMap,
'non-enumerable own property',
{enumerable: false, value: 'non-enumerable own property'}
);
Object.defineProperty (
strMap,
'enumerable own property',
{enumerable: true, value: 'enumerable own property'}
);

module.exports = strMap;
8 changes: 2 additions & 6 deletions test/keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const S = require ('..');

const eq = require ('./internal/eq');
const strMap = require ('./internal/strMap');


test ('keys', () => {
Expand All @@ -14,11 +15,6 @@ test ('keys', () => {
eq (S.sort (S.keys ({}))) ([]);
eq (S.sort (S.keys ({a: 1, b: 2, c: 3}))) (['a', 'b', 'c']);

const proto = {a: 1, b: 2};
const obj = Object.create (proto);
obj.c = 3;
obj.d = 4;

eq (S.sort (S.keys (obj))) (['c', 'd']);
eq (S.keys (strMap)) (['enumerable own property']);

});
8 changes: 2 additions & 6 deletions test/pairs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const S = require ('..');

const eq = require ('./internal/eq');
const strMap = require ('./internal/strMap');


test ('pairs', () => {
Expand All @@ -14,11 +15,6 @@ test ('pairs', () => {
eq (S.sort (S.pairs ({}))) ([]);
eq (S.sort (S.pairs ({a: 1, b: 2, c: 3}))) ([S.Pair ('a') (1), S.Pair ('b') (2), S.Pair ('c') (3)]);

const proto = {a: 1, b: 2};
const obj = Object.create (proto);
obj.c = 3;
obj.d = 4;

eq (S.sort (S.pairs (obj))) ([S.Pair ('c') (3), S.Pair ('d') (4)]);
eq (S.pairs (strMap)) ([S.Pair ('enumerable own property') ('enumerable own property')]);

});
26 changes: 26 additions & 0 deletions test/value.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

const S = require ('..');

const eq = require ('./internal/eq');
const strMap = require ('./internal/strMap');


test ('value', () => {

eq (typeof S.value) ('function');
eq (S.value.length) (1);
eq (S.show (S.value)) ('value :: String -> StrMap a -> Maybe a');

eq (S.value ('foo') ({foo: 1, bar: 2})) (S.Just (1));
eq (S.value ('bar') ({foo: 1, bar: 2})) (S.Just (2));
eq (S.value ('baz') ({foo: 1, bar: 2})) (S.Nothing);

eq (S.value ('valueOf') ({})) (S.Nothing);

eq (S.value ('non-enumerable inherited property') (strMap)) (S.Nothing);
eq (S.value ('enumerable inherited property') (strMap)) (S.Nothing);
eq (S.value ('non-enumerable own property') (strMap)) (S.Nothing);
eq (S.value ('enumerable own property') (strMap)) (S.Just ('enumerable own property'));

});
8 changes: 2 additions & 6 deletions test/values.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const S = require ('..');

const eq = require ('./internal/eq');
const strMap = require ('./internal/strMap');


test ('values', () => {
Expand All @@ -14,11 +15,6 @@ test ('values', () => {
eq (S.sort (S.values ({}))) ([]);
eq (S.sort (S.values ({a: 1, b: 2, c: 3}))) ([1, 2, 3]);

const proto = {a: 1, b: 2};
const obj = Object.create (proto);
obj.c = 3;
obj.d = 4;

eq (S.sort (S.values (obj))) ([3, 4]);
eq (S.values (strMap)) (['enumerable own property']);

});

0 comments on commit 507d749

Please sign in to comment.