Repository: sanctuary-js/sanctuary (js)

Issue:
complement :: (a -> Boolean) -> a -> Boolean
This is a beautiful implementation:

```javascript
//    complement :: (a -> Boolean) -> a -> Boolean
const complement = S.compose(S.not);
```

We tend not to use curried functions internally, so this is probably not the implementation we should choose. I do enjoy finding uses for partially applying `compose`, though. :)


Pull request description:
Add S.complement
Fixes #342 

Patch:
diff --git a/index.js b/index.js
index ed567f9..433d040 100644
--- a/index.js
+++ b/index.js
@@ -2560,6 +2560,8 @@
   //.
   //. Boolean "not".
   //.
+  //. See also [`complement`](#complement).
+  //.
   //. ```javascript
   //. > S.not(false)
   //. true
@@ -2572,6 +2574,25 @@
   }
   S.not = def('not', {}, [$.Boolean, $.Boolean], not);
 
+  //# complement :: (a -> Boolean) -> a -> Boolean
+  //.
+  //. Takes a unary predicate and a value of any type, and returns the logical
+  //. negation of applying the predicate to the value.
+  //.
+  //. See also [`not`](#not).
+  //.
+  //. ```javascript
+  //. > Number.isInteger(42)
+  //. true
+  //.
+  //. > S.complement(Number.isInteger, 42)
+  //. false
+  //. ```
+  function complement(pred, x) {
+    return !pred(x);
+  }
+  S.complement = def('complement', {}, [Pred(a), a, $.Boolean], complement);
+
   //# ifElse :: (a -> Boolean) -> (a -> b) -> (a -> b) -> a -> b
   //.
   //. Takes a unary predicate, a unary "if" function, a unary "else"


Test patch:
diff --git a/test/complement.js b/test/complement.js
new file mode 100644
index 0000000..2c15895
--- /dev/null
+++ b/test/complement.js
@@ -0,0 +1,17 @@
+'use strict';
+
+var S = require('..');
+
+var eq = require('./internal/eq');
+
+
+test('complement', function() {
+
+  eq(typeof S.complement, 'function');
+  eq(S.complement.length, 2);
+  eq(S.complement.toString(), 'complement :: (a -> Boolean) -> a -> Boolean');
+
+  eq(S.complement(S.odd, 1), false);
+  eq(S.complement(S.odd, 2), true);
+
+});