Change typescript interface to reducer

This commit is contained in:
Sam Nolan 2022-04-11 13:16:31 +10:00
parent 6565d97f53
commit 61b589d0bd
9 changed files with 117 additions and 80 deletions

View File

@ -1,11 +1,10 @@
import { run, Distribution, resultMap } from "../src/js/index"; import { run, Distribution, resultMap, squiggleExpression } from "../src/js/index";
let testRun = (x: string) => { let testRun = (x: string): squiggleExpression => {
let result = run(x); let result = run(x, {sampleCount: 100, xyPointLength: 100});
if (result.tag == "Ok") { expect(result.tag).toEqual("Ok")
return { tag: "Ok", value: result.value.exports }; if(result.tag === "Ok") {
} else { return result.value
return result;
} }
}; };
@ -16,29 +15,19 @@ function Ok<b>(x: b) {
describe("Simple calculations and results", () => { describe("Simple calculations and results", () => {
test("mean(normal(5,2))", () => { test("mean(normal(5,2))", () => {
expect(testRun("mean(normal(5,2))")).toEqual({ expect(testRun("mean(normal(5,2))")).toEqual({
tag: "Ok", tag: "number",
value: [{ NAME: "Float", VAL: 5 }], value: 5
}); });
}); });
test("10+10", () => { test("10+10", () => {
let foo = testRun("10 + 10"); let foo = testRun("10 + 10");
expect(foo).toEqual({ tag: "Ok", value: [{ NAME: "Float", VAL: 20 }] }); expect(foo).toEqual({ tag: "number", value: 20 });
}); });
}); });
describe("Log function", () => { describe("Log function", () => {
test("log(1) = 0", () => { test("log(1) = 0", () => {
let foo = testRun("log(1)"); let foo = testRun("log(1)");
expect(foo).toEqual({ tag: "Ok", value: [{ NAME: "Float", VAL: 0 }] }); expect(foo).toEqual({ tag: "number", value: 0 });
});
});
describe("Multimodal too many weights error", () => {
test("mm(0,0,[0,0,0])", () => {
let foo = testRun("mm(0,0,[0,0,0])");
expect(foo).toEqual({
tag: "Error",
value: "Function multimodal error: Too many weights provided",
});
}); });
}); });

View File

@ -1,13 +1,10 @@
import { runAll } from "../rescript/ProgramEvaluator.gen"; import * as _ from 'lodash'
import type { import type {
Inputs_SamplingInputs_t as SamplingInputs,
exportEnv, exportEnv,
exportType,
exportDistribution, exportDistribution,
} from "../rescript/ProgramEvaluator.gen"; } from "../rescript/ProgramEvaluator.gen";
export type { SamplingInputs, exportEnv, exportDistribution }; export type { exportEnv, exportDistribution };
export type { t as DistPlus } from "../rescript/OldInterpreter/DistPlus.gen"; import { genericDist, samplingParams, evaluate, expressionValue, errorValue, distributionError } from "../rescript/TypescriptInterface.gen";
import { genericDist, env, error } from "../rescript/TypescriptInterface.gen";
export { makeSampleSetDist } from "../rescript/TypescriptInterface.gen"; export { makeSampleSetDist } from "../rescript/TypescriptInterface.gen";
import { import {
Constructors_mean, Constructors_mean,
@ -36,23 +33,16 @@ import {
Constructors_pointwisePower, Constructors_pointwisePower,
} from "../rescript/Distributions/DistributionOperation/DistributionOperation.gen"; } from "../rescript/Distributions/DistributionOperation/DistributionOperation.gen";
export let defaultSamplingInputs: SamplingInputs = { export type SamplingInputs = {
sampleCount: 10000, readonly sampleCount?: number;
outputXYPoints: 10000, readonly outputXYPoints?: number;
pointDistLength: 1000, readonly kernelWidth?: number;
readonly pointDistLength?: number
};
export let defaultSamplingInputs: samplingParams = {
sampleCount: 10000,
xyPointLength: 10000
}; };
export function run(
squiggleString: string,
samplingInputs?: SamplingInputs,
environment?: exportEnv
): result<exportType, string> {
let si: SamplingInputs = samplingInputs
? samplingInputs
: defaultSamplingInputs;
let env: exportEnv = environment ? environment : [];
return runAll(squiggleString, si, env);
}
type result<a, b> = type result<a, b> =
| { | {
@ -75,147 +65,186 @@ export function resultMap<a, b, c>(
} }
} }
type tagged<a, b> = {tag: a, value: b}
function tag<a,b>(x: a, y: b) : tagged<a, b>{
return { tag: x, value: y}
}
export type squiggleExpression = tagged<"symbol", string> | tagged<"string", string> | tagged<"array", squiggleExpression[]> | tagged<"boolean", boolean> | tagged<"distribution", Distribution> | tagged<"number", number> | tagged<"record", {[key: string]: squiggleExpression }>
export function run(
squiggleString: string,
samplingInputs?: samplingParams,
_environment?: exportEnv
): result<squiggleExpression, errorValue> {
let si: samplingParams = samplingInputs
? samplingInputs
: defaultSamplingInputs;
let result : result<expressionValue, errorValue> = evaluate(squiggleString);
return resultMap(result, x => createTsExport(x, si));
}
function createTsExport(x: expressionValue, sampEnv: samplingParams): squiggleExpression {
switch (x.tag) {
case "EvArray":
return tag("array", x.value.map(x => createTsExport(x, sampEnv)));
case "EvBool":
return tag("boolean", x.value);
case "EvDistribution":
return tag("distribution", new Distribution(x.value, sampEnv));
case "EvNumber":
return tag("number", x.value);
case "EvRecord":
return tag("record", _.mapValues(x.value, x => createTsExport(x, sampEnv)))
}
}
export function resultExn<a, c>(r: result<a, c>): a | c { export function resultExn<a, c>(r: result<a, c>): a | c {
return r.value; return r.value;
} }
export class Distribution { export class Distribution {
t: genericDist; t: genericDist;
env: env; env: samplingParams;
constructor(t: genericDist, env: env) { constructor(t: genericDist, env: samplingParams) {
this.t = t; this.t = t;
this.env = env; this.env = env;
return this; return this;
} }
mapResultDist(r: result<genericDist, error>): result<Distribution, error> { mapResultDist(r: result<genericDist, distributionError>): result<Distribution, distributionError> {
return resultMap(r, (v: genericDist) => new Distribution(v, this.env)); return resultMap(r, (v: genericDist) => new Distribution(v, this.env));
} }
mean(): result<number, error> { mean(): result<number, distributionError> {
return Constructors_mean({ env: this.env }, this.t); return Constructors_mean({ env: this.env }, this.t);
} }
sample(): result<number, error> { sample(): result<number, distributionError> {
return Constructors_sample({ env: this.env }, this.t); return Constructors_sample({ env: this.env }, this.t);
} }
pdf(n: number): result<number, error> { pdf(n: number): result<number, distributionError> {
return Constructors_pdf({ env: this.env }, this.t, n); return Constructors_pdf({ env: this.env }, this.t, n);
} }
cdf(n: number): result<number, error> { cdf(n: number): result<number, distributionError> {
return Constructors_cdf({ env: this.env }, this.t, n); return Constructors_cdf({ env: this.env }, this.t, n);
} }
inv(n: number): result<number, error> { inv(n: number): result<number, distributionError> {
return Constructors_inv({ env: this.env }, this.t, n); return Constructors_inv({ env: this.env }, this.t, n);
} }
normalize(): result<Distribution, error> { normalize(): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_normalize({ env: this.env }, this.t) Constructors_normalize({ env: this.env }, this.t)
); );
} }
toPointSet(): result<Distribution, error> { toPointSet(): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_toPointSet({ env: this.env }, this.t) Constructors_toPointSet({ env: this.env }, this.t)
); );
} }
toSampleSet(n: number): result<Distribution, error> { toSampleSet(n: number): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_toSampleSet({ env: this.env }, this.t, n) Constructors_toSampleSet({ env: this.env }, this.t, n)
); );
} }
truncate(left: number, right: number): result<Distribution, error> { truncate(left: number, right: number): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_truncate({ env: this.env }, this.t, left, right) Constructors_truncate({ env: this.env }, this.t, left, right)
); );
} }
inspect(): result<Distribution, error> { inspect(): result<Distribution, distributionError> {
return this.mapResultDist(Constructors_inspect({ env: this.env }, this.t)); return this.mapResultDist(Constructors_inspect({ env: this.env }, this.t));
} }
toString(): result<string, error> { toString(): result<string, distributionError> {
return Constructors_toString({ env: this.env }, this.t); return Constructors_toString({ env: this.env }, this.t);
} }
toSparkline(n: number): result<string, error> { toSparkline(n: number): result<string, distributionError> {
return Constructors_toSparkline({ env: this.env }, this.t, n); return Constructors_toSparkline({ env: this.env }, this.t, n);
} }
algebraicAdd(d2: Distribution): result<Distribution, error> { algebraicAdd(d2: Distribution): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_algebraicAdd({ env: this.env }, this.t, d2.t) Constructors_algebraicAdd({ env: this.env }, this.t, d2.t)
); );
} }
algebraicMultiply(d2: Distribution): result<Distribution, error> { algebraicMultiply(d2: Distribution): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_algebraicMultiply({ env: this.env }, this.t, d2.t) Constructors_algebraicMultiply({ env: this.env }, this.t, d2.t)
); );
} }
algebraicDivide(d2: Distribution): result<Distribution, error> { algebraicDivide(d2: Distribution): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_algebraicDivide({ env: this.env }, this.t, d2.t) Constructors_algebraicDivide({ env: this.env }, this.t, d2.t)
); );
} }
algebraicSubtract(d2: Distribution): result<Distribution, error> { algebraicSubtract(d2: Distribution): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_algebraicSubtract({ env: this.env }, this.t, d2.t) Constructors_algebraicSubtract({ env: this.env }, this.t, d2.t)
); );
} }
algebraicLogarithm(d2: Distribution): result<Distribution, error> { algebraicLogarithm(d2: Distribution): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_algebraicLogarithm({ env: this.env }, this.t, d2.t) Constructors_algebraicLogarithm({ env: this.env }, this.t, d2.t)
); );
} }
algebraicPower(d2: Distribution): result<Distribution, error> { algebraicPower(d2: Distribution): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_algebraicPower({ env: this.env }, this.t, d2.t) Constructors_algebraicPower({ env: this.env }, this.t, d2.t)
); );
} }
pointwiseAdd(d2: Distribution): result<Distribution, error> { pointwiseAdd(d2: Distribution): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_pointwiseAdd({ env: this.env }, this.t, d2.t) Constructors_pointwiseAdd({ env: this.env }, this.t, d2.t)
); );
} }
pointwiseMultiply(d2: Distribution): result<Distribution, error> { pointwiseMultiply(d2: Distribution): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_pointwiseMultiply({ env: this.env }, this.t, d2.t) Constructors_pointwiseMultiply({ env: this.env }, this.t, d2.t)
); );
} }
pointwiseDivide(d2: Distribution): result<Distribution, error> { pointwiseDivide(d2: Distribution): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_pointwiseDivide({ env: this.env }, this.t, d2.t) Constructors_pointwiseDivide({ env: this.env }, this.t, d2.t)
); );
} }
pointwiseSubtract(d2: Distribution): result<Distribution, error> { pointwiseSubtract(d2: Distribution): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_pointwiseSubtract({ env: this.env }, this.t, d2.t) Constructors_pointwiseSubtract({ env: this.env }, this.t, d2.t)
); );
} }
pointwiseLogarithm(d2: Distribution): result<Distribution, error> { pointwiseLogarithm(d2: Distribution): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_pointwiseLogarithm({ env: this.env }, this.t, d2.t) Constructors_pointwiseLogarithm({ env: this.env }, this.t, d2.t)
); );
} }
pointwisePower(d2: Distribution): result<Distribution, error> { pointwisePower(d2: Distribution): result<Distribution, distributionError> {
return this.mapResultDist( return this.mapResultDist(
Constructors_pointwisePower({ env: this.env }, this.t, d2.t) Constructors_pointwisePower({ env: this.env }, this.t, d2.t)
); );

View File

@ -5,5 +5,6 @@ module Extra = Reducer_Extra
module Js = Reducer_Js module Js = Reducer_Js
module MathJs = Reducer_MathJs module MathJs = Reducer_MathJs
type expressionValue = Reducer_Expression.expressionValue
let evaluate = Expression.eval let evaluate = Expression.eval
let parse = Expression.parse let parse = Expression.parse

View File

@ -6,5 +6,8 @@ module Js = Reducer_Js
module MathJs = Reducer_MathJs module MathJs = Reducer_MathJs
@genType @genType
let evaluate: string => result<Expression.expressionValue, ErrorValue.errorValue> type expressionValue = Reducer_Expression.expressionValue
@genType
let evaluate: string => result<expressionValue, Reducer_ErrorValue.errorValue>
let parse: string => result<Expression.expression, ErrorValue.errorValue> let parse: string => result<Expression.expression, ErrorValue.errorValue>

View File

@ -1,3 +1,4 @@
@genType
type errorValue = type errorValue =
| REArrayIndexNotFound(string, int) | REArrayIndexNotFound(string, int)
| REFunctionExpected(string) | REFunctionExpected(string)

View File

@ -1,7 +1,8 @@
module Result = Belt.Result module Result = Belt.Result
module T = Reducer_Expression_T module T = Reducer_Expression_T
type expression = T.expression type expression = T.expression
type expressionValue = ReducerInterface.ExpressionValue.expressionValue @genType
type expressionValue = ReducerInterface_ExpressionValue.expressionValue
type t = expression type t = expression
let toString: T.expression => Js.String.t let toString: T.expression => Js.String.t
let toStringResult: result<T.expression, 'a> => string let toStringResult: result<T.expression, 'a> => string

View File

@ -5,6 +5,7 @@
module Extra_Array = Reducer_Extra_Array module Extra_Array = Reducer_Extra_Array
module ErrorValue = Reducer_ErrorValue module ErrorValue = Reducer_ErrorValue
@genType
type rec expressionValue = type rec expressionValue =
| EvBool(bool) | EvBool(bool)
| EvNumber(float) | EvNumber(float)

View File

@ -8,20 +8,31 @@ The below few seem to work fine. In the future there's definitely more work to d
*/ */
@genType @genType
type env = DistributionOperation.env type samplingParams = DistributionOperation.env
@genType @genType
type genericDist = GenericDist_Types.genericDist type genericDist = GenericDist_Types.genericDist
@genType @genType
type error = GenericDist_Types.error type distributionError = GenericDist_Types.error
@genType @genType
type resultDist = result<genericDist, error> type resultDist = result<genericDist, distributionError>
@genType @genType
type resultFloat = result<float, error> type resultFloat = result<float, distributionError>
@genType @genType
type resultString = result<string, error> type resultString = result<string, distributionError>
@genType @genType
let makeSampleSetDist = SampleSetDist.make let makeSampleSetDist = SampleSetDist.make
@genType
let evaluate = Reducer.evaluate
@genType
type expressionValue = Reducer_Expression.expressionValue
@genType
type errorValue = Reducer_ErrorValue.errorValue

View File

@ -0,0 +1 @@
export type Dict_t<T> = { [key: string]: T }