diff --git a/index.js b/index.js index e89f1102..a34f143e 100644 --- a/index.js +++ b/index.js @@ -750,6 +750,30 @@ } S.pipe = def('pipe', {}, [$.Array($.Function), a, b], pipe); + //# on :: (b -> b -> c) -> (a -> b) -> a -> a -> c + //. + //. Takes a binary function `f`, a unary function `g`, and two + //. values `x` and `y`. Returns `f(g(x))(g(y))`. + //. + //. See also [`on_`](#on_). + //. + //. ```javascript + //. > S.on(S.concat, S.reverse, [1, 2, 3], [4, 5, 6]) + //. [3, 2, 1, 6, 5, 4] + //. ``` + function on(f, g, x, y) { + return on_(uncurry2(f), g, x, y); + } + S.on = def('on', {}, [$.Function, $.Function, a, a, c], on); + + //# on_ :: ((b, b) -> c) -> (a -> b) -> a -> a -> c + //. + //. Version of [`on`](#on) accepting uncurried functions. + function on_(f, g, x, y) { + return f(g(x), g(y)); + } + S.on_ = def('on_', {}, [$.Function, $.Function, a, a, c], on_); + //. ### Maybe type //. //. The Maybe type represents optional values: a value of type `Maybe a` is diff --git a/test/on.js b/test/on.js new file mode 100644 index 00000000..6b0ffd95 --- /dev/null +++ b/test/on.js @@ -0,0 +1,21 @@ +'use strict'; + +var S = require('..'); + +var eq = require('./internal/eq'); +var rem = require('./internal/rem'); + + +describe('on', function() { + + it('is a quaternary function', function() { + eq(typeof S.on, 'function'); + eq(S.on.length, 4); + }); + + it('passes the last two arguments through the modifying function into the converging function', function() { + eq(S.on(rem, S.prop('x'), {x: 5, y: 5}, {x: 3, y: 3}), 2); + eq(S.on(S.concat, S.reverse)([1, 2, 3], [4, 5, 6]), [3, 2, 1, 6, 5, 4]); + }); + +}); diff --git a/test/on_.js b/test/on_.js new file mode 100644 index 00000000..4a34138e --- /dev/null +++ b/test/on_.js @@ -0,0 +1,20 @@ +'use strict'; + +var S = require('..'); + +var eq = require('./internal/eq'); +var rem_ = require('./internal/rem_'); + + +describe('on_', function() { + + it('is a quaternary function', function() { + eq(typeof S.on_, 'function'); + eq(S.on_.length, 4); + }); + + it('passes the last two arguments through the modifying function into the converging function', function() { + eq(S.on_(rem_, S.prop('x'), {x: 5, y: 5}, {x: 3, y: 3}), 2); + }); + +});