diff --git a/index.js b/index.js index 97d792a8..496bd765 100644 --- a/index.js +++ b/index.js @@ -1296,7 +1296,8 @@ //. Takes a default value and a Maybe, and returns the Maybe's value //. if the Maybe is a Just; the default value otherwise. //. - //. See also [`maybeToNullable`](#maybeToNullable). + //. See also [`fromMaybe_`](#fromMaybe_) and + //. [`maybeToNullable`](#maybeToNullable). //. //. ```javascript //. > S.fromMaybe(0, S.Just(42)) @@ -1310,6 +1311,25 @@ } S.fromMaybe = def('fromMaybe', {}, [a, $Maybe(a), a], fromMaybe); + //# fromMaybe_ :: (() -> a) -> Maybe a -> a + //. + //. Variant of [`fromMaybe`](#fromMaybe) which takes a thunk so the default + //. value is only computed if required. + //. + //. ```javascript + //. > function fib(n) { return n <= 1 ? n : fib(n - 2) + fib(n - 1); } + //. + //. > S.fromMaybe_(() => fib(30), S.Just(1000000)) + //. 1000000 + //. + //. > S.fromMaybe_(() => fib(30), S.Nothing) + //. 832040 + //. ``` + function fromMaybe_(thunk, maybe) { + return maybe.isJust ? maybe.value : thunk(); + } + S.fromMaybe_ = def('fromMaybe_', {}, [$.Function, $Maybe(a), a], fromMaybe_); + //# maybeToNullable :: Maybe a -> Nullable a //. //. Returns the given Maybe's value if the Maybe is a Just; `null` otherwise. @@ -1373,10 +1393,7 @@ //. is only computed if required. //. //. ```javascript - //. > global.fib = function fib(n) { - //. . return n <= 1 ? n : fib(n - 2) + fib(n - 1); - //. . } - //. fib + //. > function fib(n) { return n <= 1 ? n : fib(n - 2) + fib(n - 1); } //. //. > S.maybe_(() => fib(30), Math.sqrt, S.Just(1000000)) //. 1000 @@ -1384,8 +1401,8 @@ //. > S.maybe_(() => fib(30), Math.sqrt, S.Nothing) //. 832040 //. ``` - function maybe_(f, g, maybe) { - return maybe.isJust ? g(maybe.value) : f(); + function maybe_(thunk, f, maybe) { + return maybe.isJust ? f(maybe.value) : thunk(); } S.maybe_ = def('maybe_', {}, [$.Function, $.Function, $Maybe(a), b], maybe_); diff --git a/package.json b/package.json index 8ca89dda..b19077ff 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ }, "devDependencies": { "browserify": "13.1.x", - "doctest": "0.10.x", + "doctest": "0.11.x", "eslint": "2.9.x", "fantasy-land": "0.3.0", "istanbul": "0.4.x", diff --git a/test/fromMaybe_.js b/test/fromMaybe_.js new file mode 100644 index 00000000..1483c3cc --- /dev/null +++ b/test/fromMaybe_.js @@ -0,0 +1,47 @@ +'use strict'; + +var R = require('ramda'); + +var S = require('..'); + +var eq = require('./internal/eq'); +var throws = require('./internal/throws'); + + +test('fromMaybe_', function() { + + eq(typeof S.fromMaybe_, 'function'); + eq(S.fromMaybe_.length, 2); + + throws(function() { S.fromMaybe_(0); }, + TypeError, + 'Invalid value\n' + + '\n' + + 'fromMaybe_ :: Function -> Maybe a -> a\n' + + ' ^^^^^^^^\n' + + ' 1\n' + + '\n' + + '1) 0 :: Number, FiniteNumber, Integer, ValidNumber\n' + + '\n' + + 'The value at position 1 is not a member of ‘Function’.\n'); + + throws(function() { S.fromMaybe_(R.always(0), [1, 2, 3]); }, + TypeError, + 'Invalid value\n' + + '\n' + + 'fromMaybe_ :: Function -> Maybe a -> a\n' + + ' ^^^^^^^\n' + + ' 1\n' + + '\n' + + '1) [1, 2, 3] :: Array Number, Array FiniteNumber, Array NonZeroFiniteNumber, Array Integer, Array ValidNumber\n' + + '\n' + + 'The value at position 1 is not a member of ‘Maybe a’.\n'); + + eq(S.fromMaybe_(R.always(0), S.Nothing), 0); + eq(S.fromMaybe_(R.always(0), S.Just(42)), 42); + + var count = 0; + eq(S.fromMaybe_(function() { return count += 1; }, S.Just(42)), 42); + eq(count, 0); + +});