Repository: plaid/sanctuary
Pull request #135 (2016-01-28 09:53:30)

Add S.inc and S.dec functions
As discussed in #127. I'll do `mult` and `div` later because I can't face editing all those `Semigroup`/`Monoid` error messages with a hangover. :laughing: 

davidchambers: LGTM, aside from the minor formatting issue.


Patch:
diff --git a/index.js b/index.js
index 302880c..c2cc5c5 100644
--- a/index.js
+++ b/index.js
@@ -2249,6 +2249,34 @@
       [$.FiniteNumber, $.FiniteNumber, $.FiniteNumber],
       function(a, b) { return a - b; });
 
+  //# inc :: FiniteNumber -> FiniteNumber
+  //.
+  //. Increments a (finite) number by one.
+  //.
+  //. ```javascript
+  //. > S.inc(1)
+  //. 2
+  //. ```
+  S.inc =
+  def('inc',
+      {},
+      [$.FiniteNumber, $.FiniteNumber],
+      function(a) { return a + 1; });
+
+  //# dec :: FiniteNumber -> FiniteNumber
+  //.
+  //. Decrements a (finite) number by one.
+  //.
+  //. ```javascript
+  //. > S.dec(2)
+  //. 1
+  //. ```
+  S.dec =
+  def('dec',
+      {},
+      [$.FiniteNumber, $.FiniteNumber],
+      function(a) { return a - 1; });
+
   //. ### Parse
 
   //# parseDate :: String -> Maybe Date


Test patch:
diff --git a/test/index.js b/test/index.js
index a0137e3..1dbf738 100644
--- a/test/index.js
+++ b/test/index.js
@@ -3308,6 +3308,72 @@ describe('number', function() {
 
   });
 
+  describe('inc', function() {
+
+    it('is a unary function', function() {
+      eq(typeof S.inc, 'function');
+      eq(S.inc.length, 1);
+    });
+
+    it('type checks its arguments', function() {
+      assert.throws(function() { S.inc('xxx'); },
+                    errorEq(TypeError,
+                            '‘inc’ expected a value of type FiniteNumber ' +
+                            'as its first argument; received "xxx"'));
+
+      assert.throws(function() { S.inc(Infinity); },
+                    errorEq(TypeError,
+                            '‘inc’ expected a value of type FiniteNumber ' +
+                            'as its first argument; received Infinity'));
+
+      assert.throws(function() { S.inc(-Infinity); },
+                    errorEq(TypeError,
+                            '‘inc’ expected a value of type FiniteNumber ' +
+                            'as its first argument; received -Infinity'));
+    });
+
+    it('increments a number by one', function() {
+      eq(S.inc(1), 2);
+      eq(S.inc(-1), 0);
+      eq(S.inc(1.5), 2.5);
+      eq(S.inc(-1.5), -0.5);
+    });
+
+  });
+
+  describe('dec', function() {
+
+    it('is a unary function', function() {
+      eq(typeof S.dec, 'function');
+      eq(S.dec.length, 1);
+    });
+
+    it('type checks its arguments', function() {
+      assert.throws(function() { S.dec('xxx'); },
+                    errorEq(TypeError,
+                            '‘dec’ expected a value of type FiniteNumber ' +
+                            'as its first argument; received "xxx"'));
+
+      assert.throws(function() { S.dec(Infinity); },
+                    errorEq(TypeError,
+                            '‘dec’ expected a value of type FiniteNumber ' +
+                            'as its first argument; received Infinity'));
+
+      assert.throws(function() { S.dec(-Infinity); },
+                    errorEq(TypeError,
+                            '‘dec’ expected a value of type FiniteNumber ' +
+                            'as its first argument; received -Infinity'));
+    });
+
+    it('decrements a number by one', function() {
+      eq(S.dec(2), 1);
+      eq(S.dec(-1), -2);
+      eq(S.dec(1.5), 0.5);
+      eq(S.dec(-1.5), -2.5);
+    });
+
+  });
+
 });
 
 describe('parse', function() {