import {Vector} from './Vector.js' import {Returns, ReturnType, Undefined} from '#core/Type.js' import {Any, match} from '#core/TypePatterns.js' export const promoteUnary = name => match(Vector, (math, V, strategy) => { const compOp = math.resolve(name, V.Component, strategy) return Returns(Vector(ReturnType(compOp)), v => v.map(elt => compOp(elt))) }) export const distributeFirst = name => match( [Vector, Any], (math, [V, E], strategy) => { const compOp = math.resolve(name, [V.Component, E], strategy) return Returns( Vector(ReturnType(compOp)), (v, e) => v.map(f => compOp(f, e))) }) export const distributeSecond = name => match( [Any, Vector], (math, [E, V], strategy) => { const compOp = math.resolve(name, [E, V.Component], strategy) return Returns( Vector(ReturnType(compOp)), (e, v) => v.map(f => compOp(e, f))) }) export const promoteBinary = name => [ distributeFirst(name), distributeSecond(name), match([Vector, Vector], (math, [V, W], strategy) => { const VComp = V.Component const WComp = W.Component // special case: if the vector nesting depths do not match, // we operate between the elements of the deeper one and the entire // more shallow one: if (V.vectorDepth > W.vectorDepth) { const compOp = math.resolve(name, [VComp, W], strategy) return Returns( Vector(ReturnType(compOp)), (v, w) => v.map(f => compOp(f, w))) } if (V.vectorDepth < W.vectorDepth) { const compOp = math.resolve(name, [V, WComp], strategy) return Returns( Vector(ReturnType(compOp)), (v, w) => w.map(f => compOp(v, f))) } const compOp = math.resolve(name, [VComp, WComp], strategy) const opNoV = math.resolve(name, [Undefined, WComp], strategy) const opNoW = math.resolve(name, [VComp, Undefined], strategy) return Returns( Vector(ReturnType(compOp)), (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 }) }) ]