Skip to content

Commit 5f6bbde

Browse files
Merge pull request #475 from sanctuary-js/davidchambers/type-classes
[email protected]
2 parents cbcb858 + 72a3f19 commit 5f6bbde

File tree

9 files changed

+189
-106
lines changed

9 files changed

+189
-106
lines changed

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
],
2424
"dependencies": {
2525
"sanctuary-def": "0.14.0",
26-
"sanctuary-type-classes": "7.2.0",
26+
"sanctuary-type-classes": "8.0.1",
2727
"sanctuary-type-identifiers": "2.0.1"
2828
},
2929
"ignore": [

index.js

Lines changed: 117 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,98 @@
786786
//. ```
787787
S.invert = def('invert', {g: [Z.Group]}, [g, g], Z.invert);
788788

789+
//# filter :: Filterable f => (a -> Boolean) -> f a -> f a
790+
//.
791+
//. Curried version of [`Z.filter`][]. Discards every element which does not
792+
//. satisfy the predicate.
793+
//.
794+
//. See also [`reject`](#reject).
795+
//.
796+
//. ```javascript
797+
//. > S.filter(S.odd, [1, 2, 3])
798+
//. [1, 3]
799+
//.
800+
//. > S.filter(S.odd, {x: 1, y: 2, z: 3})
801+
//. {x: 1, z: 3}
802+
//.
803+
//. > S.filter(S.odd, S.Nothing)
804+
//. Nothing
805+
//.
806+
//. > S.filter(S.odd, S.Just(0))
807+
//. Nothing
808+
//.
809+
//. > S.filter(S.odd, S.Just(1))
810+
//. Just(1)
811+
//. ```
812+
S.filter =
813+
def('filter', {f: [Z.Filterable]}, [$.Predicate(a), f(a), f(a)], Z.filter);
814+
815+
//# reject :: Filterable f => (a -> Boolean) -> f a -> f a
816+
//.
817+
//. Curried version of [`Z.reject`][]. Discards every element which satisfies
818+
//. the predicate.
819+
//.
820+
//. See also [`filter`](#filter).
821+
//.
822+
//. ```javascript
823+
//. > S.reject(S.odd, [1, 2, 3])
824+
//. [2]
825+
//.
826+
//. > S.reject(S.odd, {x: 1, y: 2, z: 3})
827+
//. {y: 2}
828+
//.
829+
//. > S.reject(S.odd, S.Nothing)
830+
//. Nothing
831+
//.
832+
//. > S.reject(S.odd, S.Just(0))
833+
//. Just(0)
834+
//.
835+
//. > S.reject(S.odd, S.Just(1))
836+
//. Nothing
837+
//. ```
838+
S.reject =
839+
def('reject', {f: [Z.Filterable]}, [$.Predicate(a), f(a), f(a)], Z.reject);
840+
841+
//# takeWhile :: Filterable f => (a -> Boolean) -> f a -> f a
842+
//.
843+
//. Curried version of [`Z.takeWhile`][]. Discards the first element which
844+
//. does not satisfy the predicate, and all subsequent elements.
845+
//.
846+
//. See also [`dropWhile`](#dropWhile).
847+
//.
848+
//. ```javascript
849+
//. > S.takeWhile(S.odd, [3, 3, 3, 7, 6, 3, 5, 4])
850+
//. [3, 3, 3, 7]
851+
//.
852+
//. > S.takeWhile(S.even, [3, 3, 3, 7, 6, 3, 5, 4])
853+
//. []
854+
//. ```
855+
S.takeWhile =
856+
def('takeWhile',
857+
{f: [Z.Filterable]},
858+
[$.Predicate(a), f(a), f(a)],
859+
Z.takeWhile);
860+
861+
//# dropWhile :: Filterable f => (a -> Boolean) -> f a -> f a
862+
//.
863+
//. Curried version of [`Z.dropWhile`][]. Retains the first element which
864+
//. does not satisfy the predicate, and all subsequent elements.
865+
//.
866+
//. See also [`takeWhile`](#takeWhile).
867+
//.
868+
//. ```javascript
869+
//. > S.dropWhile(S.odd, [3, 3, 3, 7, 6, 3, 5, 4])
870+
//. [6, 3, 5, 4]
871+
//.
872+
//. > S.dropWhile(S.even, [3, 3, 3, 7, 6, 3, 5, 4])
873+
//. [3, 3, 3, 7, 6, 3, 5, 4]
874+
//. ```
875+
S.dropWhile =
876+
def('dropWhile',
877+
{f: [Z.Filterable]},
878+
[$.Predicate(a), f(a), f(a)],
879+
Z.dropWhile);
880+
789881
//# map :: Functor f => (a -> b) -> f a -> f b
790882
//.
791883
//. Curried version of [`Z.map`][].
@@ -1225,82 +1317,6 @@
12251317
[Fn(b, a), f(a), f(b)],
12261318
Z.contramap);
12271319

1228-
//# filter :: (Applicative f, Foldable f, Monoid (f a)) => (a -> Boolean) -> f a -> f a
1229-
//.
1230-
//. Curried version of [`Z.filter`][]. Filters its second argument in
1231-
//. accordance with the given predicate.
1232-
//.
1233-
//. See also [`filterM`](#filterM).
1234-
//.
1235-
//. ```javascript
1236-
//. > S.filter(S.odd, [1, 2, 3, 4, 5])
1237-
//. [1, 3, 5]
1238-
//. ```
1239-
S.filter =
1240-
def('filter',
1241-
{f: [Z.Applicative, Z.Foldable, Z.Monoid]},
1242-
[$.Predicate(a), f(a), f(a)],
1243-
Z.filter);
1244-
1245-
//# filterM :: (Alternative m, Monad m) => (a -> Boolean) -> m a -> m a
1246-
//.
1247-
//. Curried version of [`Z.filterM`][]. Filters its second argument in
1248-
//. accordance with the given predicate.
1249-
//.
1250-
//. See also [`filter`](#filter).
1251-
//.
1252-
//. ```javascript
1253-
//. > S.filterM(S.odd, [1, 2, 3, 4, 5])
1254-
//. [1, 3, 5]
1255-
//.
1256-
//. > S.filterM(S.odd, S.Just(9))
1257-
//. Just(9)
1258-
//.
1259-
//. > S.filterM(S.odd, S.Just(4))
1260-
//. Nothing
1261-
//. ```
1262-
S.filterM =
1263-
def('filterM',
1264-
{m: [Z.Alternative, Z.Monad]},
1265-
[$.Predicate(a), m(a), m(a)],
1266-
Z.filterM);
1267-
1268-
//# takeWhile :: (Foldable f, Alternative f) => (a -> Boolean) -> f a -> f a
1269-
//.
1270-
//. Discards the first inner value which does not satisfy the predicate, and
1271-
//. all subsequent inner values.
1272-
//.
1273-
//. ```javascript
1274-
//. > S.takeWhile(S.odd, [3, 3, 3, 7, 6, 3, 5, 4])
1275-
//. [3, 3, 3, 7]
1276-
//.
1277-
//. > S.takeWhile(S.even, [3, 3, 3, 7, 6, 3, 5, 4])
1278-
//. []
1279-
//. ```
1280-
S.takeWhile =
1281-
def('takeWhile',
1282-
{f: [Z.Foldable, Z.Alternative]},
1283-
[$.Predicate(a), f(a), f(a)],
1284-
Z.takeWhile);
1285-
1286-
//# dropWhile :: (Foldable f, Alternative f) => (a -> Boolean) -> f a -> f a
1287-
//.
1288-
//. Retains the first inner value which does not satisfy the predicate, and
1289-
//. all subsequent inner values.
1290-
//.
1291-
//. ```javascript
1292-
//. > S.dropWhile(S.odd, [3, 3, 3, 7, 6, 3, 5, 4])
1293-
//. [6, 3, 5, 4]
1294-
//.
1295-
//. > S.dropWhile(S.even, [3, 3, 3, 7, 6, 3, 5, 4])
1296-
//. [3, 3, 3, 7, 6, 3, 5, 4]
1297-
//. ```
1298-
S.dropWhile =
1299-
def('dropWhile',
1300-
{f: [Z.Foldable, Z.Alternative]},
1301-
[$.Predicate(a), f(a), f(a)],
1302-
Z.dropWhile);
1303-
13041320
//. ### Combinator
13051321

13061322
//# I :: a -> a
@@ -1828,6 +1844,28 @@
18281844
other.isNothing ? this : Just(Z.concat(this.value, other.value));
18291845
}
18301846

1847+
//# Maybe#fantasy-land/filter :: Maybe a ~> (a -> Boolean) -> Maybe a
1848+
//.
1849+
//. Takes a predicate and returns `this` if `this` is a Just and this Just's
1850+
//. value satisfies the given predicate; Nothing otherwise.
1851+
//.
1852+
//. It is idiomatic to use [`filter`](#filter) rather than use this method
1853+
//. directly.
1854+
//.
1855+
//. ```javascript
1856+
//. > S.filter(S.odd, S.Nothing)
1857+
//. Nothing
1858+
//.
1859+
//. > S.filter(S.odd, S.Just(0))
1860+
//. Nothing
1861+
//.
1862+
//. > S.filter(S.odd, S.Just(1))
1863+
//. Just(1)
1864+
//. ```
1865+
Maybe.prototype['fantasy-land/filter'] = function(pred) {
1866+
return this.isJust && pred(this.value) ? this : Nothing;
1867+
};
1868+
18311869
//# Maybe#fantasy-land/map :: Maybe a ~> (a -> b) -> Maybe b
18321870
//.
18331871
//. Takes a function and returns `this` if `this` is Nothing; otherwise
@@ -4689,13 +4727,13 @@
46894727
//. [`Z.compose`]: v:sanctuary-js/sanctuary-type-classes#compose
46904728
//. [`Z.concat`]: v:sanctuary-js/sanctuary-type-classes#concat
46914729
//. [`Z.contramap`]: v:sanctuary-js/sanctuary-type-classes#contramap
4730+
//. [`Z.dropWhile`]: v:sanctuary-js/sanctuary-type-classes#dropWhile
46924731
//. [`Z.duplicate`]: v:sanctuary-js/sanctuary-type-classes#duplicate
46934732
//. [`Z.empty`]: v:sanctuary-js/sanctuary-type-classes#empty
46944733
//. [`Z.equals`]: v:sanctuary-js/sanctuary-type-classes#equals
46954734
//. [`Z.extend`]: v:sanctuary-js/sanctuary-type-classes#extend
46964735
//. [`Z.extract`]: v:sanctuary-js/sanctuary-type-classes#extract
46974736
//. [`Z.filter`]: v:sanctuary-js/sanctuary-type-classes#filter
4698-
//. [`Z.filterM`]: v:sanctuary-js/sanctuary-type-classes#filterM
46994737
//. [`Z.gt`]: v:sanctuary-js/sanctuary-type-classes#gt
47004738
//. [`Z.gte`]: v:sanctuary-js/sanctuary-type-classes#gte
47014739
//. [`Z.id`]: v:sanctuary-js/sanctuary-type-classes#id
@@ -4706,7 +4744,9 @@
47064744
//. [`Z.map`]: v:sanctuary-js/sanctuary-type-classes#map
47074745
//. [`Z.of`]: v:sanctuary-js/sanctuary-type-classes#of
47084746
//. [`Z.promap`]: v:sanctuary-js/sanctuary-type-classes#promap
4747+
//. [`Z.reject`]: v:sanctuary-js/sanctuary-type-classes#reject
47094748
//. [`Z.sequence`]: v:sanctuary-js/sanctuary-type-classes#sequence
4749+
//. [`Z.takeWhile`]: v:sanctuary-js/sanctuary-type-classes#takeWhile
47104750
//. [`Z.toString`]: v:sanctuary-js/sanctuary-type-classes#toString
47114751
//. [`Z.traverse`]: v:sanctuary-js/sanctuary-type-classes#traverse
47124752
//. [`Z.zero`]: v:sanctuary-js/sanctuary-type-classes#zero

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212
},
1313
"dependencies": {
1414
"sanctuary-def": "0.14.0",
15-
"sanctuary-type-classes": "7.2.0",
15+
"sanctuary-type-classes": "8.0.1",
1616
"sanctuary-type-identifiers": "2.0.1"
1717
},
1818
"devDependencies": {
1919
"browserify": "13.1.x",
2020
"doctest": "0.13.x",
2121
"eslint": "4.9.x",
22-
"fantasy-land": "3.4.0",
22+
"fantasy-land": "3.5.0",
2323
"istanbul": "0.4.x",
2424
"jsverify": "0.7.x",
2525
"karma": "1.3.x",

test/dropWhile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ test('dropWhile', function() {
99

1010
eq(typeof S.dropWhile, 'function');
1111
eq(S.dropWhile.length, 2);
12-
eq(S.dropWhile.toString(), 'dropWhile :: (Foldable f, Alternative f) => (a -> Boolean) -> f a -> f a');
12+
eq(S.dropWhile.toString(), 'dropWhile :: Filterable f => (a -> Boolean) -> f a -> f a');
1313

1414
eq(S.dropWhile(S.odd, [3, 3, 3, 7, 6, 3, 5, 4]), [6, 3, 5, 4]);
1515
eq(S.dropWhile(S.even, [3, 3, 3, 7, 6, 3, 5, 4]), [3, 3, 3, 7, 6, 3, 5, 4]);

test/filter.js

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,38 @@
11
'use strict';
22

3-
var S = require('..');
3+
var S = require('./internal/sanctuary');
44

5+
var List = require('./internal/List');
56
var eq = require('./internal/eq');
67

78

9+
var Cons = List.Cons;
10+
var Nil = List.Nil;
11+
12+
813
test('filter', function() {
914

1015
eq(typeof S.filter, 'function');
1116
eq(S.filter.length, 2);
12-
eq(S.filter.toString(), 'filter :: (Applicative f, Foldable f, Monoid f) => (a -> Boolean) -> f a -> f a');
17+
eq(S.filter.toString(), 'filter :: Filterable f => (a -> Boolean) -> f a -> f a');
1318

1419
eq(S.filter(S.odd, []), []);
1520
eq(S.filter(S.odd, [0, 2, 4, 6, 8]), []);
1621
eq(S.filter(S.odd, [1, 3, 5, 7, 9]), [1, 3, 5, 7, 9]);
1722
eq(S.filter(S.odd, [1, 2, 3, 4, 5]), [1, 3, 5]);
1823

24+
eq(S.filter(S.odd, {}), {});
25+
eq(S.filter(S.odd, {x: 1}), {x: 1});
26+
eq(S.filter(S.odd, {x: 1, y: 2}), {x: 1});
27+
eq(S.filter(S.odd, {x: 1, y: 2, z: 3}), {x: 1, z: 3});
28+
29+
eq(S.filter(S.odd, S.Nothing), S.Nothing);
30+
eq(S.filter(S.odd, S.Just(0)), S.Nothing);
31+
eq(S.filter(S.odd, S.Just(1)), S.Just(1));
32+
33+
eq(S.filter(S.odd, Nil), Nil);
34+
eq(S.filter(S.odd, Cons(1, Nil)), Cons(1, Nil));
35+
eq(S.filter(S.odd, Cons(1, Cons(2, Nil))), Cons(1, Nil));
36+
eq(S.filter(S.odd, Cons(1, Cons(2, Cons(3, Nil)))), Cons(1, Cons(3, Nil)));
37+
1938
});

test/filterM.js

Lines changed: 0 additions & 22 deletions
This file was deleted.

test/internal/List.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ List.prototype[FL.concat] = function(other) {
6363
Cons(this.head, Z.concat(this.tail, other));
6464
};
6565

66+
List.prototype[FL.filter] = function(pred) {
67+
return this.isNil ?
68+
Nil :
69+
pred(this.head) ?
70+
Cons(this.head, Z.filter(pred, this.tail)) :
71+
Z.filter(pred, this.tail);
72+
};
73+
6674
List.prototype[FL.map] = function(f) {
6775
return this.isNil ?
6876
Nil :

test/reject.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use strict';
2+
3+
var S = require('./internal/sanctuary');
4+
5+
var List = require('./internal/List');
6+
var eq = require('./internal/eq');
7+
8+
9+
var Cons = List.Cons;
10+
var Nil = List.Nil;
11+
12+
13+
test('reject', function() {
14+
15+
eq(typeof S.reject, 'function');
16+
eq(S.reject.length, 2);
17+
eq(S.reject.toString(), 'reject :: Filterable f => (a -> Boolean) -> f a -> f a');
18+
19+
eq(S.reject(S.odd, []), []);
20+
eq(S.reject(S.odd, [0, 2, 4, 6, 8]), [0, 2, 4, 6, 8]);
21+
eq(S.reject(S.odd, [1, 3, 5, 7, 9]), []);
22+
eq(S.reject(S.odd, [1, 2, 3, 4, 5]), [2, 4]);
23+
24+
eq(S.reject(S.odd, {}), {});
25+
eq(S.reject(S.odd, {x: 1}), {});
26+
eq(S.reject(S.odd, {x: 1, y: 2}), {y: 2});
27+
eq(S.reject(S.odd, {x: 1, y: 2, z: 3}), {y: 2});
28+
29+
eq(S.reject(S.odd, S.Nothing), S.Nothing);
30+
eq(S.reject(S.odd, S.Just(0)), S.Just(0));
31+
eq(S.reject(S.odd, S.Just(1)), S.Nothing);
32+
33+
eq(S.reject(S.odd, Nil), Nil);
34+
eq(S.reject(S.odd, Cons(1, Nil)), Nil);
35+
eq(S.reject(S.odd, Cons(1, Cons(2, Nil))), Cons(2, Nil));
36+
eq(S.reject(S.odd, Cons(1, Cons(2, Cons(3, Nil)))), Cons(2, Nil));
37+
38+
});

test/takeWhile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ test('takeWhile', function() {
99

1010
eq(typeof S.takeWhile, 'function');
1111
eq(S.takeWhile.length, 2);
12-
eq(S.takeWhile.toString(), 'takeWhile :: (Foldable f, Alternative f) => (a -> Boolean) -> f a -> f a');
12+
eq(S.takeWhile.toString(), 'takeWhile :: Filterable f => (a -> Boolean) -> f a -> f a');
1313

1414
eq(S.takeWhile(S.odd, [3, 3, 3, 7, 6, 3, 5, 4]), [3, 3, 3, 7]);
1515
eq(S.takeWhile(S.even, [3, 3, 3, 7, 6, 3, 5, 4]), []);

0 commit comments

Comments
 (0)