Fixed minor bugs
This commit is contained in:
parent
31e4f97820
commit
c39d749a1d
|
@ -4,6 +4,7 @@ import AceEditor from "react-ace";
|
||||||
import "ace-builds/src-noconflict/mode-golang";
|
import "ace-builds/src-noconflict/mode-golang";
|
||||||
import "ace-builds/src-noconflict/theme-github";
|
import "ace-builds/src-noconflict/theme-github";
|
||||||
import "ace-builds/src-noconflict/ext-language_tools";
|
import "ace-builds/src-noconflict/ext-language_tools";
|
||||||
|
import "ace-builds/src-noconflict/keybinding-vim";
|
||||||
|
|
||||||
function onChange(newValue) {
|
function onChange(newValue) {
|
||||||
console.log("change", newValue);
|
console.log("change", newValue);
|
||||||
|
@ -20,6 +21,7 @@ export class CodeEditor extends React.Component {
|
||||||
mode="golang"
|
mode="golang"
|
||||||
height="400px"
|
height="400px"
|
||||||
width="100%"
|
width="100%"
|
||||||
|
keyboardHandler="vim"
|
||||||
theme="github"
|
theme="github"
|
||||||
showGutter={false}
|
showGutter={false}
|
||||||
highlightActiveLine={false}
|
highlightActiveLine={false}
|
||||||
|
|
|
@ -163,6 +163,8 @@ module DemoDist = {
|
||||||
switch (response1) {
|
switch (response1) {
|
||||||
| Ok(`DistPlus(distPlus1)) =>
|
| Ok(`DistPlus(distPlus1)) =>
|
||||||
<DistPlusPlot distPlus={DistPlus.T.normalize(distPlus1)} />
|
<DistPlusPlot distPlus={DistPlus.T.normalize(distPlus1)} />
|
||||||
|
| Ok(`Float(f)) =>
|
||||||
|
<ForetoldComponents.NumberShower number=f precision=3 />
|
||||||
| Ok(`Function((f, a), env)) =>
|
| Ok(`Function((f, a), env)) =>
|
||||||
// Problem: When it gets the function, it doesn't save state about previous commands
|
// Problem: When it gets the function, it doesn't save state about previous commands
|
||||||
let foo: DistPlusRenderer.Inputs.inputs = {
|
let foo: DistPlusRenderer.Inputs.inputs = {
|
||||||
|
@ -181,7 +183,7 @@ module DemoDist = {
|
||||||
|> E.R.bind(_, a =>
|
|> E.R.bind(_, a =>
|
||||||
switch (a) {
|
switch (a) {
|
||||||
| `DistPlus(d) => Ok((r, DistPlus.T.normalize(d)))
|
| `DistPlus(d) => Ok((r, DistPlus.T.normalize(d)))
|
||||||
| _ => Error("")
|
| n => {Js.log2("Error here",n); Error("wrong type")}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,13 +3,21 @@ open Distributions;
|
||||||
type t = DistTypes.continuousShape;
|
type t = DistTypes.continuousShape;
|
||||||
let getShape = (t: t) => t.xyShape;
|
let getShape = (t: t) => t.xyShape;
|
||||||
let interpolation = (t: t) => t.interpolation;
|
let interpolation = (t: t) => t.interpolation;
|
||||||
let make = (~interpolation=`Linear, ~integralSumCache=None, ~integralCache=None, xyShape): t => {
|
let make =
|
||||||
|
(
|
||||||
|
~interpolation=`Linear,
|
||||||
|
~integralSumCache=None,
|
||||||
|
~integralCache=None,
|
||||||
|
xyShape,
|
||||||
|
)
|
||||||
|
: t => {
|
||||||
xyShape,
|
xyShape,
|
||||||
interpolation,
|
interpolation,
|
||||||
integralSumCache,
|
integralSumCache,
|
||||||
integralCache,
|
integralCache,
|
||||||
};
|
};
|
||||||
let shapeMap = (fn, {xyShape, interpolation, integralSumCache, integralCache}: t): t => {
|
let shapeMap =
|
||||||
|
(fn, {xyShape, interpolation, integralSumCache, integralCache}: t): t => {
|
||||||
xyShape: fn(xyShape),
|
xyShape: fn(xyShape),
|
||||||
interpolation,
|
interpolation,
|
||||||
integralSumCache,
|
integralSumCache,
|
||||||
|
@ -19,10 +27,14 @@ let lastY = (t: t) => t |> getShape |> XYShape.T.lastY;
|
||||||
let oShapeMap =
|
let oShapeMap =
|
||||||
(fn, {xyShape, interpolation, integralSumCache, integralCache}: t)
|
(fn, {xyShape, interpolation, integralSumCache, integralCache}: t)
|
||||||
: option(DistTypes.continuousShape) =>
|
: option(DistTypes.continuousShape) =>
|
||||||
fn(xyShape) |> E.O.fmap(make(~interpolation, ~integralSumCache, ~integralCache));
|
fn(xyShape)
|
||||||
|
|> E.O.fmap(make(~interpolation, ~integralSumCache, ~integralCache));
|
||||||
|
|
||||||
let emptyIntegral: DistTypes.continuousShape = {
|
let emptyIntegral: DistTypes.continuousShape = {
|
||||||
xyShape: {xs: [|neg_infinity|], ys: [|0.0|]},
|
xyShape: {
|
||||||
|
xs: [|neg_infinity|],
|
||||||
|
ys: [|0.0|],
|
||||||
|
},
|
||||||
interpolation: `Linear,
|
interpolation: `Linear,
|
||||||
integralSumCache: Some(0.0),
|
integralSumCache: Some(0.0),
|
||||||
integralCache: None,
|
integralCache: None,
|
||||||
|
@ -35,14 +47,18 @@ let empty: DistTypes.continuousShape = {
|
||||||
};
|
};
|
||||||
|
|
||||||
let stepwiseToLinear = (t: t): t =>
|
let stepwiseToLinear = (t: t): t =>
|
||||||
make(~integralSumCache=t.integralSumCache, ~integralCache=t.integralCache, XYShape.Range.stepwiseToLinear(t.xyShape));
|
make(
|
||||||
|
~integralSumCache=t.integralSumCache,
|
||||||
|
~integralCache=t.integralCache,
|
||||||
|
XYShape.Range.stepwiseToLinear(t.xyShape),
|
||||||
|
);
|
||||||
|
|
||||||
// Note: This results in a distribution with as many points as the sum of those in t1 and t2.
|
// Note: This results in a distribution with as many points as the sum of those in t1 and t2.
|
||||||
let combinePointwise =
|
let combinePointwise =
|
||||||
(
|
(
|
||||||
~integralSumCachesFn=(_, _) => None,
|
~integralSumCachesFn=(_, _) => None,
|
||||||
~integralCachesFn: (t, t) => option(t) =(_, _) => None,
|
~integralCachesFn: (t, t) => option(t)=(_, _) => None,
|
||||||
~distributionType: DistTypes.distributionType = `PDF,
|
~distributionType: DistTypes.distributionType=`PDF,
|
||||||
fn: (float, float) => float,
|
fn: (float, float) => float,
|
||||||
t1: DistTypes.continuousShape,
|
t1: DistTypes.continuousShape,
|
||||||
t2: DistTypes.continuousShape,
|
t2: DistTypes.continuousShape,
|
||||||
|
@ -62,19 +78,22 @@ let combinePointwise =
|
||||||
|
|
||||||
// If combining stepwise and linear, we must convert the stepwise to linear first,
|
// If combining stepwise and linear, we must convert the stepwise to linear first,
|
||||||
// i.e. add a point at the bottom of each step
|
// i.e. add a point at the bottom of each step
|
||||||
let (t1, t2) = switch (t1.interpolation, t2.interpolation) {
|
let (t1, t2) =
|
||||||
| (`Linear, `Linear) => (t1, t2);
|
switch (t1.interpolation, t2.interpolation) {
|
||||||
| (`Stepwise, `Stepwise) => (t1, t2);
|
| (`Linear, `Linear) => (t1, t2)
|
||||||
| (`Linear, `Stepwise) => (t1, stepwiseToLinear(t2));
|
| (`Stepwise, `Stepwise) => (t1, t2)
|
||||||
| (`Stepwise, `Linear) => (stepwiseToLinear(t1), t2);
|
| (`Linear, `Stepwise) => (t1, stepwiseToLinear(t2))
|
||||||
};
|
| (`Stepwise, `Linear) => (stepwiseToLinear(t1), t2)
|
||||||
|
};
|
||||||
|
|
||||||
let extrapolation = switch (distributionType) {
|
let extrapolation =
|
||||||
| `PDF => `UseZero
|
switch (distributionType) {
|
||||||
| `CDF => `UseOutermostPoints
|
| `PDF => `UseZero
|
||||||
};
|
| `CDF => `UseOutermostPoints
|
||||||
|
};
|
||||||
|
|
||||||
let interpolator = XYShape.XtoY.continuousInterpolator(t1.interpolation, extrapolation);
|
let interpolator =
|
||||||
|
XYShape.XtoY.continuousInterpolator(t1.interpolation, extrapolation);
|
||||||
|
|
||||||
make(
|
make(
|
||||||
~integralSumCache=combinedIntegralSum,
|
~integralSumCache=combinedIntegralSum,
|
||||||
|
@ -103,10 +122,7 @@ let updateIntegralSumCache = (integralSumCache, t: t): t => {
|
||||||
integralSumCache,
|
integralSumCache,
|
||||||
};
|
};
|
||||||
|
|
||||||
let updateIntegralCache = (integralCache, t: t): t => {
|
let updateIntegralCache = (integralCache, t: t): t => {...t, integralCache};
|
||||||
...t,
|
|
||||||
integralCache,
|
|
||||||
};
|
|
||||||
|
|
||||||
let reduce =
|
let reduce =
|
||||||
(
|
(
|
||||||
|
@ -116,11 +132,13 @@ let reduce =
|
||||||
continuousShapes,
|
continuousShapes,
|
||||||
) =>
|
) =>
|
||||||
continuousShapes
|
continuousShapes
|
||||||
|> E.A.fold_left(combinePointwise(~integralSumCachesFn, ~integralCachesFn, fn), empty);
|
|> E.A.fold_left(
|
||||||
|
combinePointwise(~integralSumCachesFn, ~integralCachesFn, fn),
|
||||||
|
empty,
|
||||||
|
);
|
||||||
|
|
||||||
let mapY = (~integralSumCacheFn=_ => None,
|
let mapY =
|
||||||
~integralCacheFn=_ => None,
|
(~integralSumCacheFn=_ => None, ~integralCacheFn=_ => None, ~fn, t: t) => {
|
||||||
~fn, t: t) => {
|
|
||||||
make(
|
make(
|
||||||
~interpolation=t.interpolation,
|
~interpolation=t.interpolation,
|
||||||
~integralSumCache=t.integralSumCache |> E.O.bind(_, integralSumCacheFn),
|
~integralSumCache=t.integralSumCache |> E.O.bind(_, integralSumCacheFn),
|
||||||
|
@ -130,13 +148,15 @@ let mapY = (~integralSumCacheFn=_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let rec scaleBy = (~scale=1.0, t: t): t => {
|
let rec scaleBy = (~scale=1.0, t: t): t => {
|
||||||
let scaledIntegralSumCache = E.O.bind(t.integralSumCache, v => Some(scale *. v));
|
let scaledIntegralSumCache =
|
||||||
let scaledIntegralCache = E.O.bind(t.integralCache, v => Some(scaleBy(~scale, v)));
|
E.O.bind(t.integralSumCache, v => Some(scale *. v));
|
||||||
|
let scaledIntegralCache =
|
||||||
|
E.O.bind(t.integralCache, v => Some(scaleBy(~scale, v)));
|
||||||
|
|
||||||
t
|
t
|
||||||
|> mapY(~fn=(r: float) => r *. scale)
|
|> mapY(~fn=(r: float) => r *. scale)
|
||||||
|> updateIntegralSumCache(scaledIntegralSumCache)
|
|> updateIntegralSumCache(scaledIntegralSumCache)
|
||||||
|> updateIntegralCache(scaledIntegralCache)
|
|> updateIntegralCache(scaledIntegralCache);
|
||||||
};
|
};
|
||||||
|
|
||||||
module T =
|
module T =
|
||||||
|
@ -171,20 +191,22 @@ module T =
|
||||||
|> XYShape.Zipped.filterByX(x => x >= lc && x <= rc);
|
|> XYShape.Zipped.filterByX(x => x >= lc && x <= rc);
|
||||||
|
|
||||||
let leftNewPoint =
|
let leftNewPoint =
|
||||||
leftCutoff |> E.O.dimap(lc => [|(lc -. epsilon_float, 0.)|], _ => [||]);
|
leftCutoff
|
||||||
|
|> E.O.dimap(lc => [|(lc -. epsilon_float, 0.)|], _ => [||]);
|
||||||
let rightNewPoint =
|
let rightNewPoint =
|
||||||
rightCutoff |> E.O.dimap(rc => [|(rc +. epsilon_float, 0.)|], _ => [||]);
|
rightCutoff
|
||||||
|
|> E.O.dimap(rc => [|(rc +. epsilon_float, 0.)|], _ => [||]);
|
||||||
|
|
||||||
let truncatedZippedPairsWithNewPoints =
|
let truncatedZippedPairsWithNewPoints =
|
||||||
E.A.concatMany([|leftNewPoint, truncatedZippedPairs, rightNewPoint|]);
|
E.A.concatMany([|leftNewPoint, truncatedZippedPairs, rightNewPoint|]);
|
||||||
let truncatedShape =
|
let truncatedShape =
|
||||||
XYShape.T.fromZippedArray(truncatedZippedPairsWithNewPoints);
|
XYShape.T.fromZippedArray(truncatedZippedPairsWithNewPoints);
|
||||||
|
|
||||||
make(truncatedShape)
|
make(truncatedShape);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: This should work with stepwise plots.
|
// TODO: This should work with stepwise plots.
|
||||||
let integral = (t) =>
|
let integral = t =>
|
||||||
switch (getShape(t) |> XYShape.T.isEmpty, t.integralCache) {
|
switch (getShape(t) |> XYShape.T.isEmpty, t.integralCache) {
|
||||||
| (true, _) => emptyIntegral
|
| (true, _) => emptyIntegral
|
||||||
| (false, Some(cache)) => cache
|
| (false, Some(cache)) => cache
|
||||||
|
@ -253,22 +275,37 @@ let combineAlgebraicallyWithDiscrete =
|
||||||
if (XYShape.T.isEmpty(t1s) || XYShape.T.isEmpty(t2s)) {
|
if (XYShape.T.isEmpty(t1s) || XYShape.T.isEmpty(t2s)) {
|
||||||
empty;
|
empty;
|
||||||
} else {
|
} else {
|
||||||
let continuousAsLinear = switch (t1.interpolation) {
|
let continuousAsLinear =
|
||||||
| `Linear => t1;
|
switch (t1.interpolation) {
|
||||||
| `Stepwise => stepwiseToLinear(t1)
|
| `Linear => t1
|
||||||
};
|
| `Stepwise => stepwiseToLinear(t1)
|
||||||
|
};
|
||||||
|
|
||||||
let combinedShape = AlgebraicShapeCombination.combineShapesContinuousDiscrete(op, continuousAsLinear |> getShape, t2s);
|
let combinedShape =
|
||||||
|
AlgebraicShapeCombination.combineShapesContinuousDiscrete(
|
||||||
let combinedIntegralSum =
|
op,
|
||||||
Common.combineIntegralSums(
|
continuousAsLinear |> getShape,
|
||||||
(a, b) => Some(a *. b),
|
t2s,
|
||||||
t1.integralSumCache,
|
|
||||||
t2.integralSumCache,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let combinedIntegralSum =
|
||||||
|
switch (op) {
|
||||||
|
| `Multiply
|
||||||
|
| `Divide =>
|
||||||
|
Common.combineIntegralSums(
|
||||||
|
(a, b) => Some(a *. b),
|
||||||
|
t1.integralSumCache,
|
||||||
|
t2.integralSumCache,
|
||||||
|
)
|
||||||
|
| _ => None
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: It could make sense to automatically transform the integrals here (shift or scale)
|
// TODO: It could make sense to automatically transform the integrals here (shift or scale)
|
||||||
make(~interpolation=t1.interpolation, ~integralSumCache=combinedIntegralSum, combinedShape)
|
make(
|
||||||
|
~interpolation=t1.interpolation,
|
||||||
|
~integralSumCache=combinedIntegralSum,
|
||||||
|
combinedShape,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -346,6 +346,7 @@ let rec toLeaf =
|
||||||
|> E.R.bind(_, toLeaf(evaluationParams))
|
|> E.R.bind(_, toLeaf(evaluationParams))
|
||||||
| `FunctionCall(name, args) =>
|
| `FunctionCall(name, args) =>
|
||||||
callableFunction(evaluationParams, name, args)
|
callableFunction(evaluationParams, name, args)
|
||||||
|
|> E.R.bind(_, toLeaf(evaluationParams))
|
||||||
| `MultiModal(r) =>
|
| `MultiModal(r) =>
|
||||||
let components =
|
let components =
|
||||||
r
|
r
|
||||||
|
@ -363,6 +364,7 @@ let rec toLeaf =
|
||||||
(acc, x) => {`PointwiseCombination((`Add, acc, x))},
|
(acc, x) => {`PointwiseCombination((`Add, acc, x))},
|
||||||
E.A.unsafe_get(components, 0),
|
E.A.unsafe_get(components, 0),
|
||||||
);
|
);
|
||||||
Ok(`Render(`Normalize(pointwiseSum)));
|
Ok(`Normalize(pointwiseSum))
|
||||||
|
|> E.R.bind(_, toLeaf(evaluationParams))
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,6 +38,11 @@ module ExpressionTree = {
|
||||||
| `SymbolicDist(`Float(x)) => Some(x)
|
| `SymbolicDist(`Float(x)) => Some(x)
|
||||||
| _ => None
|
| _ => None
|
||||||
|
|
||||||
|
let toFloatIfNeeded = (node:node) => switch(node |> getFloat){
|
||||||
|
| Some(float) => `SymbolicDist(`Float(float))
|
||||||
|
| None => node
|
||||||
|
}
|
||||||
|
|
||||||
type samplingInputs = {
|
type samplingInputs = {
|
||||||
sampleCount: int,
|
sampleCount: int,
|
||||||
outputXYPoints: int,
|
outputXYPoints: int,
|
||||||
|
|
|
@ -112,7 +112,10 @@ module Internals = {
|
||||||
ins := addVariable(ins^, name, node);
|
ins := addVariable(ins^, name, node);
|
||||||
None;
|
None;
|
||||||
}
|
}
|
||||||
| `Expression(node) => Some(runNode(ins^, node) |> E.R.fmap(r => (ins^.environment, r))),
|
| `Expression(node) =>
|
||||||
|
Some(
|
||||||
|
runNode(ins^, node) |> E.R.fmap(r => (ins^.environment, r)),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|> E.A.O.concatSomes
|
|> E.A.O.concatSomes
|
||||||
|> E.A.R.firstErrorOrOpen;
|
|> E.A.R.firstErrorOrOpen;
|
||||||
|
@ -142,12 +145,13 @@ let renderIfNeeded =
|
||||||
|> (
|
|> (
|
||||||
fun
|
fun
|
||||||
| `MultiModal(_) as n
|
| `MultiModal(_) as n
|
||||||
|
| `Normalize(_) as n
|
||||||
| `SymbolicDist(_) as n => {
|
| `SymbolicDist(_) as n => {
|
||||||
`Render(n)
|
`Render(n)
|
||||||
|> Internals.runNode(Internals.distPlusRenderInputsToInputs(inputs))
|
|> Internals.runNode(Internals.distPlusRenderInputsToInputs(inputs))
|
||||||
|> (
|
|> (
|
||||||
fun
|
fun
|
||||||
| Ok(`RenderedDist(n)) => Ok(`RenderedDist(n))
|
| Ok(`RenderedDist(_)) as r => r
|
||||||
| Error(r) => Error(r)
|
| Error(r) => Error(r)
|
||||||
| _ => Error("Didn't render, but intended to")
|
| _ => Error("Didn't render, but intended to")
|
||||||
);
|
);
|
||||||
|
@ -159,7 +163,7 @@ let run = (inputs: Inputs.inputs) => {
|
||||||
inputs
|
inputs
|
||||||
|> Internals.distPlusRenderInputsToInputs
|
|> Internals.distPlusRenderInputsToInputs
|
||||||
|> Internals.inputsToLeaf
|
|> Internals.inputsToLeaf
|
||||||
|> E.R.bind(_, ((lastIns,r)) =>
|
|> E.R.bind(_, ((lastIns, r)) =>
|
||||||
r
|
r
|
||||||
|> renderIfNeeded(inputs)
|
|> renderIfNeeded(inputs)
|
||||||
|> (
|
|> (
|
||||||
|
@ -176,7 +180,37 @@ let run = (inputs: Inputs.inputs) => {
|
||||||
|> E.R.fmap(Internals.outputToDistPlus(inputs));
|
|> E.R.fmap(Internals.outputToDistPlus(inputs));
|
||||||
};
|
};
|
||||||
|
|
||||||
let exportDistPlus = (inputs, env:ProbExample.ExpressionTypes.ExpressionTree.environment, node: ExpressionTypes.ExpressionTree.node) =>
|
let exportDistPlus =
|
||||||
|
(
|
||||||
|
inputs,
|
||||||
|
env: ProbExample.ExpressionTypes.ExpressionTree.environment,
|
||||||
|
node: ExpressionTypes.ExpressionTree.node,
|
||||||
|
) =>
|
||||||
|
node
|
||||||
|
|> renderIfNeeded(inputs)
|
||||||
|
|> E.R.bind(
|
||||||
|
_,
|
||||||
|
fun
|
||||||
|
| `RenderedDist(Discrete({xyShape: {xs: [|x|], ys: [|1.0|]}})) =>
|
||||||
|
Ok(`Float(x))
|
||||||
|
| `SymbolicDist(`Float(x)) => Ok(`Float(x))
|
||||||
|
| `RenderedDist(n) =>
|
||||||
|
Ok(`DistPlus(Internals.outputToDistPlus(inputs, n)))
|
||||||
|
| `Function(n) => Ok(`Function((n, env)))
|
||||||
|
| n =>
|
||||||
|
Error(
|
||||||
|
"Didn't output a rendered distribution. Format:"
|
||||||
|
++ ExpressionTree.toString(n),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// This isn't ok with floats, which can't be done in a function easily
|
||||||
|
let exportDistPlus2 =
|
||||||
|
(
|
||||||
|
inputs,
|
||||||
|
env: ProbExample.ExpressionTypes.ExpressionTree.environment,
|
||||||
|
node: ExpressionTypes.ExpressionTree.node,
|
||||||
|
) =>
|
||||||
node
|
node
|
||||||
|> renderIfNeeded(inputs)
|
|> renderIfNeeded(inputs)
|
||||||
|> E.R.bind(
|
|> E.R.bind(
|
||||||
|
@ -184,7 +218,7 @@ let exportDistPlus = (inputs, env:ProbExample.ExpressionTypes.ExpressionTree.env
|
||||||
fun
|
fun
|
||||||
| `RenderedDist(n) =>
|
| `RenderedDist(n) =>
|
||||||
Ok(`DistPlus(Internals.outputToDistPlus(inputs, n)))
|
Ok(`DistPlus(Internals.outputToDistPlus(inputs, n)))
|
||||||
| `Function(n) => Ok(`Function(n, env))
|
| `Function(n) => Ok(`Function((n, env)))
|
||||||
| n =>
|
| n =>
|
||||||
Error(
|
Error(
|
||||||
"Didn't output a rendered distribution. Format:"
|
"Didn't output a rendered distribution. Format:"
|
||||||
|
@ -196,7 +230,7 @@ let run2 = (inputs: Inputs.inputs) => {
|
||||||
inputs
|
inputs
|
||||||
|> Internals.distPlusRenderInputsToInputs
|
|> Internals.distPlusRenderInputsToInputs
|
||||||
|> Internals.inputsToLeaf
|
|> Internals.inputsToLeaf
|
||||||
|> E.R.bind(_,((a,b)) => exportDistPlus(inputs,a,b))
|
|> E.R.bind(_, ((a, b)) => exportDistPlus(inputs, a, b));
|
||||||
};
|
};
|
||||||
|
|
||||||
let runFunction =
|
let runFunction =
|
||||||
|
@ -213,5 +247,5 @@ let runFunction =
|
||||||
fnInputs,
|
fnInputs,
|
||||||
fn,
|
fn,
|
||||||
);
|
);
|
||||||
output |> E.R.bind(_, exportDistPlus(ins, inputs.environment));
|
output |> E.R.bind(_, exportDistPlus2(ins, inputs.environment));
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user