Added map3 to samplesMap

This commit is contained in:
Ozzie Gooen 2022-05-27 09:24:06 -04:00
parent f61dc08f03
commit d3a2f391a7
3 changed files with 63 additions and 8 deletions

View File

@ -100,7 +100,25 @@ let map2 = (~fn: (float, float) => result<float, Operation.Error.t>, ~t1: t, ~t2
t,
Operation.Error.t,
> => {
let samples = Belt.Array.zip(get(t1), get(t2))->E.A2.fmap(((a, b)) => fn(a, b))
let samples = E.A.zip(get(t1), get(t2))->E.A2.fmap(((a, b)) => fn(a, b))
// This assertion should never be reached. In order for it to be reached, one
// of the input parameters would need to be a sample set distribution with less
// than 6 samples. Which should be impossible due to the smart constructor.
// I could prove this to the type system (say, creating a {first: float, second: float, ..., fifth: float, rest: array<float>}
// But doing so would take too much time, so I'll leave it as an assertion
E.A.R.firstErrorOrOpen(samples)->E.R2.fmap(x =>
E.R.toExnFnString(Error.sampleSetErrorToString, make(x))
)
}
let map3 = (
~fn: (float, float, float) => result<float, Operation.Error.t>,
~t1: t,
~t2: t,
~t3: t,
): result<t, Operation.Error.t> => {
let samples = E.A.zip3(get(t1), get(t2), get(t3))->E.A2.fmap(((a, b, c)) => fn(a, b, c))
// This assertion should never be reached. In order for it to be reached, one
// of the input parameters would need to be a sample set distribution with less

View File

@ -101,15 +101,33 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->EvArray)
}
let doMapSampleSetDist = (sampleSetDist: SampleSetDist.t, aLambdaValue) => {
let fn = r =>
switch Lambda.doLambdaCall(aLambdaValue, list{EvNumber(r)}, environment, reducer) {
module SampleMap = {
type t = SampleSetDist.t
let doLambdaCall = (aLambdaValue, list) =>
switch Lambda.doLambdaCall(aLambdaValue, list, environment, reducer) {
| Ok(EvNumber(f)) => Ok(f)
| _ => Error(Operation.SampleMapNeedsNtoNFunction)
}
switch SampleSetDist.samplesMap(~fn, sampleSetDist) {
| Ok(r) => Ok(EvDistribution(SampleSet(r)))
| Error(r) => Error(REDistributionError(SampleSetError(r)))
let toType = r =>
switch r {
| Ok(r) => Ok(EvDistribution(SampleSet(r)))
| Error(r) => Error(REDistributionError(SampleSetError(r)))
}
let map1 = (sampleSetDist: t, aLambdaValue) => {
let fn = r => doLambdaCall(aLambdaValue, list{EvNumber(r)})
toType(SampleSetDist.samplesMap(~fn, sampleSetDist))
}
let map2 = (t1: t, t2: t, aLambdaValue) => {
let fn = (a, b) => doLambdaCall(aLambdaValue, list{EvNumber(a), EvNumber(b)})
SampleSetDist.map2(~fn, ~t1, ~t2)->E.R2.errMap(SampleSetDist.Error.fromOperationError)->toType
}
let map3 = (t1: t, t2: t, t3: t, aLambdaValue) => {
let fn = (a, b, c) => doLambdaCall(aLambdaValue, list{EvNumber(a), EvNumber(b), EvNumber(c)})
SampleSetDist.map3(~fn, ~t1, ~t2, ~t3)->E.R2.errMap(SampleSetDist.Error.fromOperationError)->toType
}
}
@ -143,7 +161,22 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
doKeepArray(aValueArray, aLambdaValue)
| ("map", [EvArray(aValueArray), EvLambda(aLambdaValue)]) => doMapArray(aValueArray, aLambdaValue)
| ("mapSamples", [EvDistribution(SampleSet(dist)), EvLambda(aLambdaValue)]) =>
doMapSampleSetDist(dist, aLambdaValue)
SampleMap.map1(dist, aLambdaValue)
| (
"mapSamples2",
[EvDistribution(SampleSet(dist1)), EvDistribution(SampleSet(dist2)), EvLambda(aLambdaValue)],
) =>
SampleMap.map2(dist1, dist2, aLambdaValue)
| (
"mapSamples3",
[
EvDistribution(SampleSet(dist1)),
EvDistribution(SampleSet(dist2)),
EvDistribution(SampleSet(dist3)),
EvLambda(aLambdaValue),
],
) =>
SampleMap.map3(dist1, dist2, dist3, aLambdaValue)
| ("reduce", [EvArray(aValueArray), initialValue, EvLambda(aLambdaValue)]) =>
doReduceArray(aValueArray, initialValue, aLambdaValue)
| ("reduceReverse", [EvArray(aValueArray), initialValue, EvLambda(aLambdaValue)]) =>

View File

@ -567,6 +567,10 @@ module A = {
let tail = Belt.Array.sliceToEnd(_, 1)
let zip = Belt.Array.zip
let zip3 = (a, b, c) =>
Belt.Array.zip(a, b)
-> Belt.Array.zip(c)
-> Belt.Array.map((((v1, v2), v3)) => (v1, v2, v3))
// This zips while taking the longest elements of each array.
let zipMaxLength = (array1, array2) => {
let maxLength = Int.max(length(array1), length(array2))