Moved list functions into FunctionRegistry

This commit is contained in:
Ozzie Gooen 2022-07-19 10:35:31 -07:00
parent 835ce6b81f
commit f8d6db61c5
5 changed files with 148 additions and 63 deletions

View File

@ -1,15 +1,6 @@
open Jest open Jest
open Reducer_TestHelpers open Reducer_TestHelpers
describe("map reduce", () => {
testEvalToBe("double(x)=2*x; arr=[1,2,3]; map(arr, double)", "Ok([2,4,6])")
testEvalToBe("myadd(acc,x)=acc+x; arr=[1,2,3]; reduce(arr, 0, myadd)", "Ok(6)")
testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; reduce(arr, 0, change)", "Ok(15)")
testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; reduceReverse(arr, 0, change)", "Ok(9)")
testEvalToBe("arr=[1,2,3]; reverse(arr)", "Ok([3,2,1])")
testEvalToBe("check(x)=(x==2);arr=[1,2,3]; filter(arr,check)", "Ok([2])")
})
Skip.describe("map reduce (sam)", () => { Skip.describe("map reduce (sam)", () => {
testEvalToBe("addone(x)=x+1; map(2, addone)", "Error???") testEvalToBe("addone(x)=x+1; map(2, addone)", "Error???")
testEvalToBe("addone(x)=x+1; map(2, {x: addone})", "Error???") testEvalToBe("addone(x)=x+1; map(2, {x: addone})", "Error???")

View File

@ -16,6 +16,12 @@ describe("FunctionRegistry Library", () => {
testEvalToBe("List.first([3,5,8])", "Ok(3)") testEvalToBe("List.first([3,5,8])", "Ok(3)")
testEvalToBe("List.last([3,5,8])", "Ok(8)") testEvalToBe("List.last([3,5,8])", "Ok(8)")
testEvalToBe("List.reverse([3,5,8])", "Ok([8,5,3])") testEvalToBe("List.reverse([3,5,8])", "Ok([8,5,3])")
testEvalToBe("double(x)=2*x; arr=[1,2,3]; List.map(arr, double)", "Ok([2,4,6])")
testEvalToBe("myadd(acc,x)=acc+x; arr=[1,2,3]; List.reduce(arr, 0, myadd)", "Ok(6)")
testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; List.reduce(arr, 0, change)", "Ok(15)")
testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; List.reduceReverse(arr, 0, change)", "Ok(9)")
testEvalToBe("check(x)=(x==2);arr=[1,2,3]; List.filter(arr,check)", "Ok([2])")
testEvalToBe("arr=[1,2,3]; List.reverse(arr)", "Ok([3,2,1])")
testEvalToBe("Dist.normal(5,2)", "Ok(Normal(5,2))") testEvalToBe("Dist.normal(5,2)", "Ok(Normal(5,2))")
testEvalToBe("normal(5,2)", "Ok(Normal(5,2))") testEvalToBe("normal(5,2)", "Ok(Normal(5,2))")
testEvalToBe("normal({mean:5,stdev:2})", "Ok(Normal(5,2))") testEvalToBe("normal({mean:5,stdev:2})", "Ok(Normal(5,2))")

View File

@ -23,13 +23,67 @@ module Internals = {
let reverse = (array: array<internalExpressionValue>): internalExpressionValue => IEvArray( let reverse = (array: array<internalExpressionValue>): internalExpressionValue => IEvArray(
Belt.Array.reverse(array), Belt.Array.reverse(array),
) )
let map = (array: array<internalExpressionValue>, environment, eLambdaValue, reducer): result<
ReducerInterface_InternalExpressionValue.t,
Reducer_ErrorValue.errorValue,
> => {
let rMappedList = array->E.A.reduceReverse(Ok(list{}), (rAcc, elem) =>
rAcc->E.R.bind(_, acc => {
let rNewElem = Reducer_Expression_Lambda.doLambdaCall(
eLambdaValue,
list{elem},
environment,
reducer,
)
rNewElem->E.R2.fmap(newElem => list{newElem, ...acc})
})
)
rMappedList->E.R2.fmap(mappedList => mappedList->Belt.List.toArray->Wrappers.evArray)
}
let reduce = (aValueArray, initialValue, aLambdaValue, environment, reducer) => {
aValueArray->E.A.reduce(Ok(initialValue), (rAcc, elem) =>
rAcc->E.R.bind(_, acc =>
Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer)
)
)
}
let reduceReverse = (aValueArray, initialValue, aLambdaValue, environment, reducer) => {
aValueArray->Belt.Array.reduceReverse(Ok(initialValue), (rAcc, elem) =>
rAcc->Belt.Result.flatMap(acc =>
Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer)
)
)
}
let filter = (aValueArray, aLambdaValue, environment, reducer) => {
let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) =>
rAcc->E.R.bind(_, acc => {
let rNewElem = Reducer_Expression_Lambda.doLambdaCall(
aLambdaValue,
list{elem},
environment,
reducer,
)
rNewElem->E.R2.fmap(newElem =>
switch newElem {
| IEvBool(true) => list{elem, ...acc}
| _ => acc
}
)
})
)
rMappedList->E.R2.fmap(mappedList => mappedList->Belt.List.toArray->Wrappers.evArray)
}
} }
let library = [ let library = [
Function.make( Function.make(
~name="make", ~name="make",
~nameSpace, ~nameSpace,
~requiresNamespace, ~requiresNamespace=true,
~output=EvtArray, ~output=EvtArray,
~examples=[`List.make(2, "testValue")`], ~examples=[`List.make(2, "testValue")`],
~definitions=[ ~definitions=[
@ -51,7 +105,7 @@ let library = [
Function.make( Function.make(
~name="upTo", ~name="upTo",
~nameSpace, ~nameSpace,
~requiresNamespace, ~requiresNamespace=true,
~output=EvtArray, ~output=EvtArray,
~examples=[`List.upTo(1,4)`], ~examples=[`List.upTo(1,4)`],
~definitions=[ ~definitions=[
@ -70,7 +124,7 @@ let library = [
Function.make( Function.make(
~name="first", ~name="first",
~nameSpace, ~nameSpace,
~requiresNamespace, ~requiresNamespace=true,
~examples=[`List.first([1,4,5])`], ~examples=[`List.first([1,4,5])`],
~definitions=[ ~definitions=[
FnDefinition.make( FnDefinition.make(
@ -89,7 +143,7 @@ let library = [
Function.make( Function.make(
~name="last", ~name="last",
~nameSpace, ~nameSpace,
~requiresNamespace, ~requiresNamespace=true,
~examples=[`List.last([1,4,5])`], ~examples=[`List.last([1,4,5])`],
~definitions=[ ~definitions=[
FnDefinition.make( FnDefinition.make(
@ -125,4 +179,87 @@ let library = [
], ],
(), (),
), ),
Function.make(
~name="map",
~nameSpace,
~output=EvtArray,
~requiresNamespace=false,
~examples=[`List.map([1,4,5], {|x| x+1})`],
~definitions=[
FnDefinition.make(
~name="map",
~inputs=[FRTypeArray(FRTypeAny), FRTypeLambda],
~run=(inputs, _, env, reducer) =>
switch inputs {
| [IEvArray(array), IEvLambda(lambda)] =>
Internals.map(array, env, lambda, reducer)->E.R2.errMap(_ => "Error!")
| _ => Error(impossibleError)
},
(),
),
],
(),
),
Function.make(
~name="reduce",
~nameSpace,
~requiresNamespace=false,
~examples=[`List.reduce([1,4,5], 2, {|acc, el| acc+el})`],
~definitions=[
FnDefinition.make(
~name="reduce",
~inputs=[FRTypeArray(FRTypeAny), FRTypeAny, FRTypeLambda],
~run=(inputs, _, env, reducer) =>
switch inputs {
| [IEvArray(array), initialValue, IEvLambda(lambda)] =>
Internals.reduce(array, initialValue, lambda, env, reducer)->E.R2.errMap(_ => "Error!")
| _ => Error(impossibleError)
},
(),
),
],
(),
),
Function.make(
~name="reduceReverse",
~nameSpace,
~requiresNamespace=false,
~examples=[`List.reduceReverse([1,4,5], 2, {|acc, el| acc-el})`],
~definitions=[
FnDefinition.make(
~name="reduceReverse",
~inputs=[FRTypeArray(FRTypeAny), FRTypeAny, FRTypeLambda],
~run=(inputs, _, env, reducer) =>
switch inputs {
| [IEvArray(array), initialValue, IEvLambda(lambda)] =>
Internals.reduceReverse(array, initialValue, lambda, env, reducer)->E.R2.errMap(_ =>
"Error!"
)
| _ => Error(impossibleError)
},
(),
),
],
(),
),
Function.make(
~name="filter",
~nameSpace,
~requiresNamespace=false,
~examples=[`List.filter([1,4,5], {|x| x>3})`],
~definitions=[
FnDefinition.make(
~name="filter",
~inputs=[FRTypeArray(FRTypeAny), FRTypeLambda],
~run=(inputs, _, env, reducer) =>
switch inputs {
| [IEvArray(array), IEvLambda(lambda)] =>
Internals.filter(array, lambda, env, reducer)->E.R2.errMap(_ => "Error!")
| _ => Error(impossibleError)
},
(),
),
],
(),
),
] ]

View File

@ -95,31 +95,6 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
let doExportBindings = (bindings: nameSpace) => bindings->Bindings.toExpressionValue->Ok let doExportBindings = (bindings: nameSpace) => bindings->Bindings.toExpressionValue->Ok
let doKeepArray = (aValueArray, aLambdaValue) => {
let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) =>
rAcc->Result.flatMap(acc => {
let rNewElem = Lambda.doLambdaCall(aLambdaValue, list{elem}, environment, reducer)
rNewElem->Result.map(newElem =>
switch newElem {
| IEvBool(true) => list{elem, ...acc}
| _ => acc
}
)
})
)
rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->IEvArray)
}
let doMapArray = (aValueArray, aLambdaValue) => {
let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) =>
rAcc->Result.flatMap(acc => {
let rNewElem = Lambda.doLambdaCall(aLambdaValue, list{elem}, environment, reducer)
rNewElem->Result.map(newElem => list{newElem, ...acc})
})
)
rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->IEvArray)
}
module SampleMap = { module SampleMap = {
type t = SampleSetDist.t type t = SampleSetDist.t
let doLambdaCall = (aLambdaValue, list) => let doLambdaCall = (aLambdaValue, list) =>
@ -172,22 +147,6 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
} }
} }
let doReduceArray = (aValueArray, initialValue, aLambdaValue) => {
aValueArray->Belt.Array.reduce(Ok(initialValue), (rAcc, elem) =>
rAcc->Result.flatMap(acc =>
Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer)
)
)
}
let doReduceReverseArray = (aValueArray, initialValue, aLambdaValue) => {
aValueArray->Belt.Array.reduceReverse(Ok(initialValue), (rAcc, elem) =>
rAcc->Result.flatMap(acc =>
Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer)
)
)
}
switch call { switch call {
| ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex) | ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex)
| ("$_atIndex_$", [IEvBindings(dict), IEvString(sIndex)]) => moduleAtIndex(dict, sIndex) | ("$_atIndex_$", [IEvBindings(dict), IEvString(sIndex)]) => moduleAtIndex(dict, sIndex)
@ -226,10 +185,6 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
doAddString(aValueString, bValueString) doAddString(aValueString, bValueString)
| ("inspect", [value, IEvString(label)]) => inspectLabel(value, label) | ("inspect", [value, IEvString(label)]) => inspectLabel(value, label)
| ("inspect", [value]) => inspect(value) | ("inspect", [value]) => inspect(value)
| ("filter", [IEvArray(aValueArray), IEvLambda(aLambdaValue)]) =>
doKeepArray(aValueArray, aLambdaValue)
| ("map", [IEvArray(aValueArray), IEvLambda(aLambdaValue)]) =>
doMapArray(aValueArray, aLambdaValue)
| ("mapSamples", [IEvDistribution(SampleSet(dist)), IEvLambda(aLambdaValue)]) => | ("mapSamples", [IEvDistribution(SampleSet(dist)), IEvLambda(aLambdaValue)]) =>
SampleMap.map1(dist, aLambdaValue) SampleMap.map1(dist, aLambdaValue)
| ( | (
@ -253,11 +208,6 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
SampleMap.map3(dist1, dist2, dist3, aLambdaValue) SampleMap.map3(dist1, dist2, dist3, aLambdaValue)
| ("mapSamplesN", [IEvArray(aValueArray), IEvLambda(aLambdaValue)]) => | ("mapSamplesN", [IEvArray(aValueArray), IEvLambda(aLambdaValue)]) =>
SampleMap.mapN(aValueArray, aLambdaValue) SampleMap.mapN(aValueArray, aLambdaValue)
| ("reduce", [IEvArray(aValueArray), initialValue, IEvLambda(aLambdaValue)]) =>
doReduceArray(aValueArray, initialValue, aLambdaValue)
| ("reduceReverse", [IEvArray(aValueArray), initialValue, IEvLambda(aLambdaValue)]) =>
doReduceReverseArray(aValueArray, initialValue, aLambdaValue)
| ("reverse", [IEvArray(aValueArray)]) => aValueArray->Belt.Array.reverse->IEvArray->Ok
| (_, [IEvBool(_)]) | (_, [IEvBool(_)])
| (_, [IEvNumber(_)]) | (_, [IEvNumber(_)])
| (_, [IEvString(_)]) | (_, [IEvString(_)])

View File

@ -546,6 +546,7 @@ module A = {
let slice = Belt.Array.slice let slice = Belt.Array.slice
let init = Array.init let init = Array.init
let reduce = Belt.Array.reduce let reduce = Belt.Array.reduce
let reduceReverse = Belt.Array.reduceReverse
let reducei = Belt.Array.reduceWithIndex let reducei = Belt.Array.reduceWithIndex
let some = Belt.Array.some let some = Belt.Array.some
let isEmpty = r => length(r) < 1 let isEmpty = r => length(r) < 1