Repository: sanctuary-js/sanctuary (js)

Issue:
boolean :: a -> a -> Boolean -> a
We have [`S.ifElse`][1], but we currently lack straightforward case folding for the `Boolean` type ([`S.maybe`][2] and [`S.either`][3] provide case folding for `Maybe a` and `Either a b` respectively).

I think `S.boolean` would be a good addition to the library.

```javascript
> S.boolean ('false') ('true') (false)
'false'

> S.boolean ('false') ('true') (true)
'true'
```

The one thing I very much dislike about the function is that one must learn that the constructors are essentially defined in `false | true` order rather than in `true | false` order. This is arbitrary, and does not match the argument order of `S.ifElse`. If we decide to add this function we should make it consistent with Haskell's [`bool`][4], so some confusion is unavoidable.


[1]: https://sanctuary.js.org/#ifElse
[2]: https://sanctuary.js.org/#maybe
[3]: https://sanctuary.js.org/#either
[4]: https://hackage.haskell.org/package/base-4.11.1.0/docs/Data-Bool.html#v:bool


Pull request description:
logic: add S.boolean
Closes #577


Patch:
diff --git a/index.js b/index.js
index 9ddfe13..250a44d 100644
--- a/index.js
+++ b/index.js
@@ -2767,6 +2767,31 @@
     impl: B (not)
   };
 
+  //# boolean :: a -> a -> Boolean -> a
+  //.
+  //. Case analysis for the `Boolean` type. `boolean (x) (y) (b)` evaluates
+  //. to `x` if `b` is `false`; to `y` if `b` is `true`.
+  //.
+  //. ```javascript
+  //. > S.boolean ('no') ('yes') (false)
+  //. 'no'
+  //.
+  //. > S.boolean ('no') ('yes') (true)
+  //. 'yes'
+  //. ```
+  function boolean(x) {
+    return function(y) {
+      return function(b) {
+        return b ? y : x;
+      };
+    };
+  }
+  _.boolean = {
+    consts: {},
+    types: [a, a, $.Boolean, a],
+    impl: boolean
+  };
+
   //# 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/boolean.js b/test/boolean.js
new file mode 100644
index 0000000..2e5ab76
--- /dev/null
+++ b/test/boolean.js
@@ -0,0 +1,17 @@
+'use strict';
+
+var S = require ('..');
+
+var eq = require ('./internal/eq');
+
+
+test ('boolean', function() {
+
+  eq (typeof S.boolean) ('function');
+  eq (S.boolean.length) (1);
+  eq (S.show (S.boolean)) ('boolean :: a -> a -> Boolean -> a');
+
+  eq (S.boolean ('no') ('yes') (false)) ('no');
+  eq (S.boolean ('no') ('yes') (true)) ('yes');
+
+});