'use strict'
function curry (fn, arity) {
if (arity === 1) return fn
return function (a, b) {
if (arguments.length === 1) return function (c) { return fn(a, c) }
return fn(a, b)
}
}
/**
* Decorate a function to work with intervals, notes or pitches in
* [array notation](https://github.com/danigb/tonal/tree/next/packages/music-notation)
* with independence of string representations.
*
* This is the base of the pluggable notation system of
* [tonal](https://github.com/danigb/tonal)
*
* @name operation
* @function
* @param {Function} parse - the parser
* @param {Function} str - the string builder
* @param {Function} fn - the operation to decorate
*
* @example
* var parse = require('music-notation/interval/parse')
* var str = require('music-notation/interval/str')
* var operation = require('music-notation/operation')(parse, str)
* var add = operation(function(a, b) { return [a[0] + b[0], a[1] + b[1]] })
* add('3m', '3M') // => '5P'
*/
module.exports = function op (parse, str, fn) {
if (arguments.length === 2) return function (f) { return op(parse, str, f) }
return curry(function (a, b) {
var ac = parse(a)
var bc = parse(b)
if (!ac && !bc) return fn(a, b)
var v = fn(ac || a, bc || b)
return str(v) || v
}, fn.length)
}
|