import {Vector} from './Vector.js' import {NotAType, Returns, Undefined} from '#core/Type.js' import {Any, match} from '#core/TypePatterns.js' export const promoteUnary = name => match(Vector, (math, V, strategy) => { if (V.Component === NotAType) { // have to resolve element by element :-( return Returns(V, v => v.map( elt => math.resolve(name, math.typeOf(elt), strategy)(elt))) } const compOp = math.resolve(name, V.Component, strategy) return Returns(Vector(compOp.returns), v => v.map(elt => compOp(elt))) }) export const promoteBinary = name => [ match([Vector, Any], (math, [V, E], strategy) => { const VComp = V.Component if (VComp === NotAType) { return Returns(V, (v, e) => v.map( f => math.resolve(name, [math.typeOf(f), E], strategy)(f, e))) } const compOp = math.resolve(name, [VComp, E], strategy) return Returns( Vector(compOp.returns), (v, e) => v.map(f => compOp(f, e))) }), match([Any, Vector], (math, [E, V], strategy) => { const VComp = V.Component if (VComp === NotAType) { return Returns(V, (e, v) => v.map( f => math.resolve(name, [E, math.typeOf(f)], strategy)(e, f))) } const compOp = math.resolve(name, [E, VComp], strategy) return Returns( Vector(compOp.returns, (e, v) => v.map(f => compOp(e, f)))) }), match([Vector, Vector], (math, [V, W], strategy) => { const VComp = V.Component const WComp = W.Component let compOp let opNoV let opNoW let ReturnType if (VComp === NotAType || WComp === NotAType) { const typ = math.typeOf compOp = (v, w) => { return math.resolve(name, [typ(v), typ(w)], strategy)(v, w) } opNoV = compOp opNoW = compOp ReturnType = Vector(NotAType) } else { compOp = math.resolve(name, [VComp, WComp], strategy) opNoV = math.resolve(name, [Undefined, WComp], strategy) opNoW = math.resolve(name, [VComp, Undefined], strategy) ReturnType = Vector(compOp.returns) } return Returns( ReturnType, (v, w) => { const vInc = Number(v.length > 1) const wInc = Number(w.length >= v.length || w.length > 1) const retval = [] let vIx = 0 let wIx = 0 while ((vInc && vIx < v.length) || (wInc && wIx < w.length) ) { if (vIx >= v.length) { retval.push(opNoV(undefined, w[wIx])) } else if (wIx >= w.length) { retval.push(opNoW(v[vIx], undefined)) } else retval.push(compOp(v[vIx], w[wIx])) vIx += vInc wIx += wInc } return retval }) }) ]