Repository: sanctuary-js/sanctuary (js)

Issue:
toEither :: a -> b? -> Either a b
Suggested by @raine on [Gitter][1].

```javascript
> S.toEither('Invalid protocol', 'ftp://example.com/'.match(/^(http:|https:)[/][/]/))
Left("Invalid protocol")

> S.toEither('Invalid protocol', 'http://example.com/'.match(/^(http:|https:)[/][/]/))
Right(["http://", "http:"])
```

This would mirror [`S.toMaybe`][2].


[1]: https://gitter.im/plaid/sanctuary
[2]: https://github.com/plaid/sanctuary#toMaybe


Pull request description:
Adds `toEither :: a -> b? -> Either a b`
A function for converting a possibly null-y value to an Either
Closes #83

Patch:
diff --git a/index.js b/index.js
index eb2c50a..275d724 100644
--- a/index.js
+++ b/index.js
@@ -1265,7 +1265,7 @@
 
   //# toMaybe :: a? -> Maybe a
   //.
-  //. Takes a value and returns Nothing if the value is null or undefined;
+  //. Takes a value and returns Nothing if the value is `null` or `undefined`;
   //. Just the value otherwise.
   //.
   //. ```javascript
@@ -1883,6 +1883,31 @@
       [b, $Either(a, b), b],
       function(x, either) { return either.isRight ? either.value : x; });
 
+  //# toEither :: a -> b? -> Either a b
+  //.
+  //. Converts an arbitrary value to an Either: a Left if the value is `null`
+  //. or `undefined`; a Right otherwise. The first argument specifies the
+  //. value of the Left in the "failure" case.
+  //.
+  //. ```javascript
+  //. > S.toEither('XYZ', null)
+  //. Left('XYZ')
+  //.
+  //. > S.toEither('XYZ', 'ABC')
+  //. Right('ABC')
+  //.
+  //. > R.map(R.head, S.toEither('Invalid protocol', 'ftp://example.com/'.match(/^https?:/)))
+  //. Left('Invalid protocol')
+  //.
+  //. > R.map(R.head, S.toEither('Invalid protocol', 'https://example.com/'.match(/^https?:/)))
+  //. Right('https:')
+  //. ```
+  S.toEither =
+  def('toEither',
+      {},
+      [a, b, $Either(a, b)],
+      function(x, y) { return y == null ? Left(x) : Right(y); });
+
   //# either :: (a -> c) -> (b -> c) -> Either a b -> c
   //.
   //. Takes two functions and an Either, and returns the result of


Test patch:
diff --git a/test/toEither.js b/test/toEither.js
new file mode 100644
index 0000000..407fb48
--- /dev/null
+++ b/test/toEither.js
@@ -0,0 +1,23 @@
+'use strict';
+
+var eq = require('./utils').eq;
+var S = require('..');
+
+
+describe('toEither', function() {
+
+  it('is a binary function', function() {
+    eq(typeof S.toEither, 'function');
+    eq(S.toEither.length, 2);
+  });
+
+  it('returns Left of the first argument when second argument is `null`-y', function() {
+    eq(S.toEither('a', null), S.Left('a'));
+    eq(S.toEither('a', undefined), S.Left('a'));
+  });
+
+  it('returns a Right of the second argument when it is not `null`-y', function() {
+    eq(S.toEither('a', 42), S.Right(42));
+  });
+
+});