Add pattern composers, implements #82

This commit is contained in:
alex 2022-04-21 14:13:26 +01:00
parent 36d1a68b9a
commit b370c405da
2 changed files with 60 additions and 25 deletions

View File

@ -275,14 +275,14 @@ const generic_params = [
const _name = (name, ...pats) => sequence(...pats).withValue((x) => ({ [name]: x })); const _name = (name, ...pats) => sequence(...pats).withValue((x) => ({ [name]: x }));
const _unionise = (func) => const _setter = (func) =>
function (...pats) { function (...pats) {
return this.union(func(...pats)); return this.set(func(...pats));
}; };
generic_params.forEach(([type, name, description]) => { generic_params.forEach(([type, name, description]) => {
controls[name] = (...pats) => _name(name, ...pats); controls[name] = (...pats) => _name(name, ...pats);
Pattern.prototype[name] = _unionise(controls[name]); Pattern.prototype[name] = _setter(controls[name]);
}); });
export default controls; export default controls;

View File

@ -247,9 +247,24 @@ export class Pattern {
); );
} }
_opleft(other, func) { _opLeft(other, func) {
return this.fmap(func).appLeft(reify(other)); return this.fmap(func).appLeft(reify(other));
} }
_opRight(other, func) {
return this.fmap(func).appRight(reify(other));
}
_opBoth(other, func) {
return this.fmap(func).appBoth(reify(other));
}
_opSqueeze(other, func) {
const otherPat = reify(other);
return this.fmap((a) => otherPat.fmap((b) => func(a)(b)))._squeezeJoin();
}
_opSqueezeFlip(other, func) {
const thisPat = this;
const otherPat = reify(other);
return otherPat.fmap((a) => thisPat.fmap((b) => func(a)(b)))._squeezeJoin();
}
_asNumber(silent = false) { _asNumber(silent = false) {
return this._withEvent((event) => { return this._withEvent((event) => {
@ -275,22 +290,6 @@ export class Pattern {
})._removeUndefineds(); })._removeUndefineds();
} }
add(other) {
return this._asNumber()._opleft(other, (a) => (b) => a + b);
}
sub(other) {
return this._asNumber()._opleft(other, (a) => (b) => a - b);
}
mul(other) {
return this._asNumber()._opleft(other, (a) => (b) => a * b);
}
div(other) {
return this._asNumber()._opleft(other, (a) => (b) => a / b);
}
round() { round() {
return this._asNumber().fmap((v) => Math.round(v)); return this._asNumber().fmap((v) => Math.round(v));
} }
@ -324,10 +323,6 @@ export class Pattern {
return this._fromBipolar().range(min, max); return this._fromBipolar().range(min, max);
} }
union(other) {
return this._opleft(other, (a) => (b) => Object.assign({}, a, b));
}
_bindWhole(choose_whole, func) { _bindWhole(choose_whole, func) {
const pat_val = this; const pat_val = this;
const query = function (state) { const query = function (state) {
@ -719,6 +714,46 @@ export class Pattern {
_velocity(velocity) { _velocity(velocity) {
return this._withContext((context) => ({ ...context, velocity: (context.velocity || 1) * velocity })); return this._withContext((context) => ({ ...context, velocity: (context.velocity || 1) * velocity }));
} }
add(other) {
return this._asNumber()._opLeft(other, (a) => (b) => a + b);
}
sub(other) {
return this._asNumber()._opLeft(other, (a) => (b) => a - b);
}
mul(other) {
return this._asNumber()._opLeft(other, (a) => (b) => a * b);
}
div(other) {
return this._asNumber()._opLeft(other, (a) => (b) => a / b);
}
}
// pattern composers
const composers = {
set: [(a) => (b) => Object.assign({}, a, b), id],
add: [(a) => (b) => a + b, (x) => x._asNumber()],
sub: [(a) => (b) => a - b, (x) => x._asNumber()],
mul: [(a) => (b) => a * b, (x) => x._asNumber()],
div: [(a) => (b) => a / b, (x) => x._asNumber()],
};
for (const [name, op] of Object.entries(composers)) {
console.log(`Adding ${name}`);
Pattern.prototype[name] = function (other) {
return op[1](this)._opLeft(other, op[0]);
};
Pattern.prototype[name + 'Flip'] = function (other) {
return op[1](this)._opRight(other, op[0]);
};
Pattern.prototype[name + 'Sect'] = function (other) {
return op[1](this)._opBoth(other, op[0]);
};
Pattern.prototype[name + 'Squeeze'] = function (other) {
return op[1](this)._opSqueeze(other, op[0]);
};
} }
// methods of Pattern that get callable factories // methods of Pattern that get callable factories
@ -922,7 +957,7 @@ export const slow = curry((a, pat) => pat.slow(a));
export const struct = curry((a, pat) => pat.struct(a)); export const struct = curry((a, pat) => pat.struct(a));
export const sub = curry((a, pat) => pat.sub(a)); export const sub = curry((a, pat) => pat.sub(a));
export const superimpose = curry((array, pat) => pat.superimpose(...array)); export const superimpose = curry((array, pat) => pat.superimpose(...array));
export const union = curry((a, pat) => pat.union(a)); export const set = curry((a, pat) => pat.set(a));
export const when = curry((binary, f, pat) => pat.when(binary, f)); export const when = curry((binary, f, pat) => pat.when(binary, f));
// problem: curried functions with spread arguments must have pat at the beginning // problem: curried functions with spread arguments must have pat at the beginning