shenanigans

This commit is contained in:
alex 2022-01-25 17:03:22 +00:00
parent d15ac42969
commit f696cd554f
3 changed files with 108 additions and 55 deletions

View File

@ -5,6 +5,10 @@ var removeUndefineds = function(xs) {
return xs.filter(x => x != undefined)
}
function flatten(arr) {
return [].concat(...arr)
}
// Returns the start of the cycle.
Fraction.prototype.sam = function() {
return Fraction(Math.floor(this))
@ -36,6 +40,18 @@ Fraction.prototype.gte = function(other) {
return this.compare(other) >= 0
}
Fraction.prototype.max = function(other) {
return this.gt(other) ? this : other
}
Fraction.prototype.min = function(other) {
return this.lt(other) ? this : other
}
Fraction.prototype.show = function () {
return this.n + "/" + this.d
}
class TimeSpan {
constructor(begin, end) {
this.begin = Fraction(begin)
@ -71,8 +87,8 @@ class TimeSpan {
intersection(other) {
// Intersection of two timespans, returns None if they don't intersect.
intersect_begin = Math.max(this.begin, other.begin)
intersect_end = Math.min(this.end, other.end)
var intersect_begin = this.begin.max(other.begin)
var intersect_end = this.end.min(other.end)
if (intersect_begin.gt(intersect_end)) {
return(undefined)
@ -92,12 +108,12 @@ class TimeSpan {
intersection_e(other) {
// Like 'sect', but raises an exception if the timespans don't intersect.
result = this.intersection(other)
if (result.equals(None)) {
var result = this.intersection(other)
if (result == undefined) {
// TODO - raise exception
// raise ValueError(f'TimeSpan {self} and TimeSpan {other} do not intersect')
}
return(result)
return result
}
get midpoint() {
@ -107,6 +123,10 @@ class TimeSpan {
equals(other) {
return this.begin.equals(other.begin) && this.end.equals(other.end)
}
show() {
return this.begin.show() + " -> " + this.end.show()
}
}
class Hap {
@ -158,6 +178,10 @@ class Hap {
&& this.value === other.value
)
}
show() {
return "(" + (this.whole == undefined ? "~" : this.whole.show()) + ", " + this.part.show() + ", " + this.value + ")"
}
}
class Pattern {
@ -170,7 +194,7 @@ class Pattern {
// easier to express, as all events are then constrained to happen within
// a cycle.
var query = function(span) {
return span.spanCycles.map(subspan => this.query(subspan)).concat
return flatten(span.spanCycles.map(subspan => this.query(subspan)))
}
return new Pattern(query)
}
@ -200,16 +224,16 @@ class Pattern {
withValue(func) {
// Returns a new pattern, with the function applied to the value of
// each event. It has the alias 'fmap'.
return new Pattern(this.query(span).map(hap => hap.withValue(func)))
return new Pattern(span => this.query(span).map(hap => hap.withValue(func)))
}
// alias
fmap(func) {
this.withValue(func)
return this.withValue(func)
}
_filterEvents(event_test) {
return new Pattern(span => this.query(span).filter(event_test))
return new Pattern(span => this.query(span).filter(event_tespanCyclesst))
}
_filterValues(self, value_test) {
@ -227,18 +251,18 @@ class Pattern {
// Assumes 'this' is a pattern of functions, and given a function to
// resolve wholes, applies a given pattern of values to that
// pattern of functions.
pat_func = this
var pat_func = this
query = function(span) {
event_funcs = pat_func.query(span)
event_vals = pat_val.query(span)
var event_funcs = pat_func.query(span)
var event_vals = pat_val.query(span)
apply = function(event_func, event_val) {
s = event_func.part.intersection(event_val.part)
var s = event_func.part.intersection(event_val.part)
if (s === undefined) {
return undefined
}
return new Hap(whole_func(event_func.whole, event_val.whole), s, event_func.value(event_val.value))
}
return event_funcs.map(event_func => removeUndefineds(event_vals.map(event_val => apply(event_func, event_val)))).concat
return flatten(event_funcs.map(event_func => removeUndefineds(event_vals.map(event_val => apply(event_func, event_val)))))
}
return new Pattern(query)
}
@ -255,43 +279,53 @@ class Pattern {
}
appLeft(pat_val) {
pat_func = this
var query = function(span) {
events = []
for (event_func in pat_func.query(span)) {
event_vals = pat_val.query(event_func.part)
for (event_val in event_vals) {
new_whole = event_func.whole
new_part = event_func.part.intersection_e(event_val.part)
new_value = event_func.value(event_val.value)
events.push(new Event(new_whole, new_part, new_value))
}
}
return events
}
return Pattern(query)
}
var pat_func = this
appRight(pat_val) {
pat_func = this
var query = function(span) {
events = []
for (event_val in pat_val.query(span)) {
event_funcs = pat_func.query(event_val.part)
for (event_func in event_funcs) {
new_whole = event_val.whole
new_part = event_func.part.intersection_e(event_val.part)
new_value = event_func.value(event_val.value)
events.push(new Event(new_whole, new_part, new_value))
var haps = []
for (var hap_func of pat_func.query(span)) {
var event_vals = pat_val.query(hap_func.part)
for (var hap_val of event_vals) {
var new_whole = hap_func.whole
var new_part = hap_func.part.intersection_e(hap_val.part)
var new_value = hap_func.value(hap_val.value)
var hap = new Hap(new_whole, new_part, new_value)
haps.push(hap)
}
}
return events
return haps
}
return new Pattern(query)
}
// def __add__(self, other):
// return self.fmap(lambda x: lambda y: x + y).app_left(reify(other))
appRight(pat_val) {
var pat_func = this
var query = function(span) {
var haps = []
for (var hap_val of pat_val.query(span)) {
var hap_funcs = pat_func.query(hap_val.part)
for (var hap_func of hap_funcs) {
var new_whole = hap_val.whole
var new_part = hap_func.part.intersection_e(hap_val.part)
var new_value = hap_func.value(hap_val.value)
var hap = new Hap(new_whole, new_part, new_value)
haps.push(hap)
}
}
return haps
}
return new Pattern(query)
}
add(other) {
// TODO - reify other
return this.fmap(x => y => x + y).appLeft(other)
}
get firstCycle() {
return this.query(new TimeSpan(Fraction(0), Fraction(1)))
}
// def __radd__(self, other):
// return self.__add__(other)

24
package-lock.json generated
View File

@ -379,9 +379,9 @@
"integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg=="
},
"node_modules/@sindresorhus/is": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.3.0.tgz",
"integrity": "sha512-wwOvh0eO3PiTEivGJWiZ+b946SlMSb4pe+y+Ur/4S87cwo09pYi+FWHHnbrM3W9W7cBYKDqQXcrFYjYUCOJUEQ==",
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.4.0.tgz",
"integrity": "sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ==",
"engines": {
"node": ">=10"
},
@ -438,9 +438,9 @@
}
},
"node_modules/@types/node": {
"version": "17.0.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.10.tgz",
"integrity": "sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog=="
"version": "17.0.12",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.12.tgz",
"integrity": "sha512-4YpbAsnJXWYK/fpTVFlMIcUIho2AYCi4wg5aNPrG1ng7fn/1/RZfCIpRCiBX+12RVa34RluilnvCqD+g3KiSiA=="
},
"node_modules/@types/parse-json": {
"version": "4.0.0",
@ -4800,9 +4800,9 @@
}
},
"@sindresorhus/is": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.3.0.tgz",
"integrity": "sha512-wwOvh0eO3PiTEivGJWiZ+b946SlMSb4pe+y+Ur/4S87cwo09pYi+FWHHnbrM3W9W7cBYKDqQXcrFYjYUCOJUEQ=="
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.4.0.tgz",
"integrity": "sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ=="
},
"@szmarczak/http-timer": {
"version": "4.0.6",
@ -4847,9 +4847,9 @@
}
},
"@types/node": {
"version": "17.0.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.10.tgz",
"integrity": "sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog=="
"version": "17.0.12",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.12.tgz",
"integrity": "sha512-4YpbAsnJXWYK/fpTVFlMIcUIho2AYCi4wg5aNPrG1ng7fn/1/RZfCIpRCiBX+12RVa34RluilnvCqD+g3KiSiA=="
},
"@types/parse-json": {
"version": "4.0.0",

View File

@ -15,6 +15,15 @@ describe('TimeSpan', function() {
assert.equal(new TimeSpan(Fraction(0),Fraction(2)).spanCycles.length, 2)
})
})
describe('intersection_e', function () {
var a = new TimeSpan(Fraction(0), Fraction(2))
var b = new TimeSpan(Fraction(1), Fraction(3))
var c = new TimeSpan(Fraction(1), Fraction(2))
var d = new TimeSpan(Fraction(1), Fraction(2))
it('Should create an intersection', function () {
assert.equal(a.intersection_e(b).equals(c), true)
})
})
});
describe('Hap', function() {
@ -47,4 +56,14 @@ describe('Pattern', function() {
assert.equal(pure("hello").query(new TimeSpan(Fraction(0.5), Fraction(2.5))).length, 3)
})
})
describe('fmap()', function () {
it('Can add things', function () {
assert.equal(pure(3).fmap(x => x + 4).firstCycle[0].value, 7)
})
})
describe('add()', function () {
it('Can add things', function() {
assert.equal(pure(3).add(pure(4)).query(new TimeSpan(Fraction(0), Fraction(1)))[0].value, 7)
})
})
})