fix typescript errors, basic playground features work

This commit is contained in:
Vyacheslav Matyukhin 2022-08-27 23:50:03 +04:00
parent 32cefb40da
commit feeb9e85f1
No known key found for this signature in database
GPG Key ID: 3D2A774C5489F96C
15 changed files with 167 additions and 214 deletions

View File

@ -3,9 +3,9 @@ import {
Distribution,
result,
DistributionError,
SquiggleValue,
resultMap,
SquiggleRecord,
environment,
} from "@quri/squiggle-lang";
import { Vega } from "react-vega";
import { ErrorAlert } from "./Alert";
@ -28,6 +28,7 @@ export type DistributionPlottingSettings = {
export type DistributionChartProps = {
plot: Plot;
environment: environment;
width?: number;
height: number;
} & DistributionPlottingSettings;
@ -44,16 +45,24 @@ export function makePlot(record: SquiggleRecord): Plot | void {
}
export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
const { plot, height, showSummary, width, logX, actions = false } = props;
const {
plot,
environment,
height,
showSummary,
width,
logX,
actions = false,
} = props;
const [sized] = useSize((size) => {
let shapes = flattenResult(
plot.distributions.map((x) =>
resultMap(x.distribution.pointSet(), (pointSet) => ({
const shapes = flattenResult(
plot.distributions.map((x) => {
return resultMap(x.distribution.pointSet(environment), (pointSet) => ({
...pointSet.asShape(),
name: x.name,
// color: x.color, // not supported yet
}))
)
}));
})
);
if (shapes.tag === "Error") {
return (
@ -93,7 +102,10 @@ export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
)}
<div className="flex justify-center">
{showSummary && plot.distributions.length === 1 && (
<SummaryTable distribution={plot.distributions[0].distribution} />
<SummaryTable
distribution={plot.distributions[0].distribution}
environment={environment}
/>
)}
</div>
</div>
@ -118,18 +130,22 @@ const Cell: React.FC<{ children: React.ReactNode }> = ({ children }) => (
type SummaryTableProps = {
distribution: Distribution;
environment: environment;
};
const SummaryTable: React.FC<SummaryTableProps> = ({ distribution }) => {
const mean = distribution.mean();
const stdev = distribution.stdev();
const p5 = distribution.inv(0.05);
const p10 = distribution.inv(0.1);
const p25 = distribution.inv(0.25);
const p50 = distribution.inv(0.5);
const p75 = distribution.inv(0.75);
const p90 = distribution.inv(0.9);
const p95 = distribution.inv(0.95);
const SummaryTable: React.FC<SummaryTableProps> = ({
distribution,
environment,
}) => {
const mean = distribution.mean(environment);
const stdev = distribution.stdev(environment);
const p5 = distribution.inv(environment, 0.05);
const p10 = distribution.inv(environment, 0.1);
const p25 = distribution.inv(environment, 0.25);
const p50 = distribution.inv(environment, 0.5);
const p75 = distribution.inv(environment, 0.75);
const p90 = distribution.inv(environment, 0.9);
const p95 = distribution.inv(environment, 0.95);
const hasResult = (x: result<number, DistributionError>): boolean =>
x.tag === "Ok";

View File

@ -1,5 +1,5 @@
import * as React from "react";
import { LambdaValue, environment, runForeign } from "@quri/squiggle-lang";
import { Lambda, environment } from "@quri/squiggle-lang";
import { FunctionChart1Dist } from "./FunctionChart1Dist";
import { FunctionChart1Number } from "./FunctionChart1Number";
import { DistributionPlottingSettings } from "./DistributionChart";
@ -12,7 +12,7 @@ export type FunctionChartSettings = {
};
interface FunctionChartProps {
fn: LambdaValue;
fn: Lambda;
chartSettings: FunctionChartSettings;
distributionPlotSettings: DistributionPlottingSettings;
environment: environment;
@ -33,6 +33,8 @@ export const FunctionChart: React.FC<FunctionChartProps> = ({
</MessageAlert>
);
}
return <div>NOT IMPLEMENTED IN 0.4 YET</div>;
/*
const result1 = runForeign(fn, [chartSettings.start], environment);
const result2 = runForeign(fn, [chartSettings.stop], environment);
const getValidResult = () => {
@ -48,9 +50,7 @@ export const FunctionChart: React.FC<FunctionChartProps> = ({
if (validResult.tag === "Error") {
return (
<ErrorAlert heading="Error">
{errorValueToString(validResult.value)}
</ErrorAlert>
<ErrorAlert heading="Error">{validResult.value.toString()}</ErrorAlert>
);
}
@ -82,4 +82,5 @@ export const FunctionChart: React.FC<FunctionChartProps> = ({
</MessageAlert>
);
}
*/
};

View File

@ -1,16 +1,7 @@
import * as React from "react";
import _ from "lodash";
import type { Spec } from "vega";
import {
Distribution,
result,
lambdaValue,
environment,
runForeign,
squiggleExpression,
errorValue,
errorValueToString,
} from "@quri/squiggle-lang";
import { Distribution, result, Lambda, environment } from "@quri/squiggle-lang";
import { createClassFromSpec } from "react-vega";
import * as percentilesSpec from "../vega-specs/spec-percentiles.json";
import {
@ -46,7 +37,7 @@ export type FunctionChartSettings = {
};
interface FunctionChart1DistProps {
fn: lambdaValue;
fn: Lambda;
chartSettings: FunctionChartSettings;
distributionPlotSettings: DistributionPlottingSettings;
environment: environment;
@ -80,6 +71,8 @@ type errors = _.Dictionary<
type point = { x: number; value: result<Distribution, string> };
let getPercentiles = ({ chartSettings, fn, environment }) => {
throw new Error("NOT IMPLEMENTED IN 0.4 YET");
/*
let chartPointsToRender = _rangeByCount(
chartSettings.start,
chartSettings.stop,
@ -104,7 +97,7 @@ let getPercentiles = ({ chartSettings, fn, environment }) => {
} else {
return {
x,
value: { tag: "Error", value: errorValueToString(result.value) },
value: { tag: "Error", value: result.value.toString() },
};
}
});
@ -149,6 +142,7 @@ let getPercentiles = ({ chartSettings, fn, environment }) => {
});
return { percentiles, errors: groupedErrors };
*/
};
export const FunctionChart1Dist: React.FC<FunctionChart1DistProps> = ({
@ -167,6 +161,9 @@ export const FunctionChart1Dist: React.FC<FunctionChart1DistProps> = ({
}
const signalListeners = { mousemove: handleHover, mouseout: handleOut };
return <div>NOT IMPLEMENTED IN 0.4 YET</div>;
/*
//TODO: This custom error handling is a bit hacky and should be improved.
let mouseItem: result<squiggleExpression, errorValue> = !!mouseOverlay
? runForeign(fn, [mouseOverlay], environment)
@ -217,4 +214,5 @@ export const FunctionChart1Dist: React.FC<FunctionChart1DistProps> = ({
)}
</>
);
*/
};

View File

@ -1,13 +1,7 @@
import * as React from "react";
import _ from "lodash";
import type { Spec } from "vega";
import {
result,
lambdaValue,
environment,
runForeign,
errorValueToString,
} from "@quri/squiggle-lang";
import { result, Lambda, environment } from "@quri/squiggle-lang";
import { createClassFromSpec } from "react-vega";
import * as lineChartSpec from "../vega-specs/spec-line-chart.json";
import { ErrorAlert } from "./Alert";
@ -30,7 +24,7 @@ export type FunctionChartSettings = {
};
interface FunctionChart1NumberProps {
fn: lambdaValue;
fn: Lambda;
chartSettings: FunctionChartSettings;
environment: environment;
height: number;
@ -39,6 +33,8 @@ interface FunctionChart1NumberProps {
type point = { x: number; value: result<number, string> };
let getFunctionImage = ({ chartSettings, fn, environment }) => {
throw new Error("NOT IMPLEMENTED IN 0.4 YET");
/*
let chartPointsToRender = _rangeByCount(
chartSettings.start,
chartSettings.stop,
@ -62,7 +58,7 @@ let getFunctionImage = ({ chartSettings, fn, environment }) => {
} else {
return {
x,
value: { tag: "Error", value: errorValueToString(result.value) },
value: { tag: "Error", value: result.value.toString() },
};
}
});
@ -82,6 +78,7 @@ let getFunctionImage = ({ chartSettings, fn, environment }) => {
}, initialPartition);
return { errors, functionImage };
*/
};
export const FunctionChart1Number: React.FC<FunctionChart1NumberProps> = ({
@ -90,6 +87,8 @@ export const FunctionChart1Number: React.FC<FunctionChart1NumberProps> = ({
environment,
height,
}: FunctionChart1NumberProps) => {
return <div>NOT IMPLEMENTED IN 0.4 YET</div>;
/*
let getFunctionImageMemoized = React.useMemo(
() => getFunctionImage({ chartSettings, fn, environment }),
[environment, fn]
@ -113,4 +112,5 @@ export const FunctionChart1Number: React.FC<FunctionChart1NumberProps> = ({
))}
</>
);
*/
};

View File

@ -1,21 +1,21 @@
import React from "react";
import { SquiggleEditor } from "./SquiggleEditor";
// import { SquiggleEditor } from "./SquiggleEditor";
import type { SquiggleEditorProps } from "./SquiggleEditor";
import { runPartial, defaultBindings } from "@quri/squiggle-lang";
import type {
result,
errorValue,
bindings as bindingsType,
} from "@quri/squiggle-lang";
// import { runPartial, defaultBindings } from "@quri/squiggle-lang";
// import type {
// result,
// errorValue,
// bindings as bindingsType,
// } from "@quri/squiggle-lang";
function resultDefault(x: result<bindingsType, errorValue>): bindingsType {
switch (x.tag) {
case "Ok":
return x.value;
case "Error":
return defaultBindings;
}
}
// function resultDefault(x: result<bindingsType, errorValue>): bindingsType {
// switch (x.tag) {
// case "Ok":
// return x.value;
// case "Error":
// return defaultBindings;
// }
// }
export type SquiggleEditorWithImportedBindingsProps = SquiggleEditorProps & {
bindingsImportUrl: string;
@ -24,29 +24,30 @@ export type SquiggleEditorWithImportedBindingsProps = SquiggleEditorProps & {
export const SquiggleEditorWithImportedBindings: React.FC<
SquiggleEditorWithImportedBindingsProps
> = (props) => {
const { bindingsImportUrl, ...editorProps } = props;
const [bindingsResult, setBindingsResult] = React.useState({
tag: "Ok",
value: defaultBindings,
} as result<bindingsType, errorValue>);
React.useEffect(() => {
async function retrieveBindings(fileName: string) {
let contents = await fetch(fileName).then((response) => {
return response.text();
});
setBindingsResult(
runPartial(
contents,
editorProps.bindings,
editorProps.environment,
editorProps.jsImports
)
);
}
retrieveBindings(bindingsImportUrl);
}, [bindingsImportUrl]);
const deliveredBindings = resultDefault(bindingsResult);
return (
<SquiggleEditor {...{ ...editorProps, bindings: deliveredBindings }} />
);
return <div>NOT IMPLEMENTED IN 0.4 YET</div>;
// const { bindingsImportUrl, ...editorProps } = props;
// const [bindingsResult, setBindingsResult] = React.useState({
// tag: "Ok",
// value: defaultBindings,
// } as result<bindingsType, errorValue>);
// React.useEffect(() => {
// async function retrieveBindings(fileName: string) {
// let contents = await fetch(fileName).then((response) => {
// return response.text();
// });
// setBindingsResult(
// runPartial(
// contents,
// editorProps.bindings,
// editorProps.environment,
// editorProps.jsImports
// )
// );
// }
// retrieveBindings(bindingsImportUrl);
// }, [bindingsImportUrl]);
// const deliveredBindings = resultDefault(bindingsResult);
// return (
// <SquiggleEditor {...{ ...editorProps, bindings: deliveredBindings }} />
// );
};

View File

@ -1,4 +1,4 @@
import React from "react";
import React, { useContext } from "react";
import {
DistributionTag,
SquiggleValue,
@ -12,6 +12,7 @@ import { VariableBox } from "./VariableBox";
import { ItemSettingsMenu } from "./ItemSettingsMenu";
import { hasMassBelowZero } from "../../lib/distributionUtils";
import { MergedItemSettings } from "./utils";
import { ViewerContext } from "./ViewerContext";
/*
// DISABLED FOR 0.4 branch, for now
@ -66,6 +67,8 @@ export const ExpressionViewer: React.FC<Props> = ({
expression,
width,
}) => {
const { getMergedSettings } = useContext(ViewerContext);
if (typeof expression !== "object") {
return (
<VariableList path={path} heading="Error">
@ -95,13 +98,15 @@ export const ExpressionViewer: React.FC<Props> = ({
: ""
}`}
renderSettingsMenu={({ onChange }) => {
const shape = expression.value.pointSet();
const shape = expression.value.pointSet(
getMergedSettings(path).environment
);
return (
<ItemSettingsMenu
path={path}
onChange={onChange}
disableLogX={
shape.tag === "Ok" && hasMassBelowZero(shape.value)
shape.tag === "Ok" && hasMassBelowZero(shape.value.asShape())
}
withFunctionSettings={false}
/>
@ -112,6 +117,7 @@ export const ExpressionViewer: React.FC<Props> = ({
return (
<DistributionChart
plot={defaultPlot(expression.value)}
environment={settings.environment}
{...settings.distributionPlotSettings}
height={settings.height}
width={width}
@ -200,9 +206,9 @@ export const ExpressionViewer: React.FC<Props> = ({
>
{(settings) => (
<>
<div className="text-amber-700 bg-amber-100 rounded-md font-mono p-1 pl-2 mb-3 mt-1 text-sm">{`function(${expression.value.parameters.join(
","
)})`}</div>
<div className="text-amber-700 bg-amber-100 rounded-md font-mono p-1 pl-2 mb-3 mt-1 text-sm">{`function(${expression.value
.parameters()
.join(",")})`}</div>
<FunctionChart
fn={expression.value}
chartSettings={settings.chartSettings}
@ -272,12 +278,15 @@ export const ExpressionViewer: React.FC<Props> = ({
return (
<VariableBox
path={path}
heading={"Plot"}
heading="Plot"
renderSettingsMenu={({ onChange }) => {
let disableLogX = plot.distributions.some((x) => {
let pointSet = x.distribution.pointSet();
let pointSet = x.distribution.pointSet(
getMergedSettings(path).environment
);
return (
pointSet.tag === "Ok" && hasMassBelowZero(pointSet.value)
pointSet.tag === "Ok" &&
hasMassBelowZero(pointSet.value.asShape())
);
});
return (
@ -294,6 +303,7 @@ export const ExpressionViewer: React.FC<Props> = ({
return (
<DistributionChart
plot={plot}
environment={settings.environment}
{...settings.distributionPlotSettings}
height={settings.height}
width={width}
@ -306,14 +316,16 @@ export const ExpressionViewer: React.FC<Props> = ({
return (
<VariableList path={path} heading="Record">
{(_) =>
Object.entries(expression.value).map(([key, r]) => (
<ExpressionViewer
key={key}
path={[...path, key]}
expression={r}
width={width !== undefined ? width - 20 : width}
/>
))
expression.value
.entries()
.map(([key, r]) => (
<ExpressionViewer
key={key}
path={[...path, key]}
expression={r}
width={width !== undefined ? width - 20 : width}
/>
))
}
</VariableList>
);

View File

@ -1,5 +1,6 @@
import * as RSDistribution from "../rescript/ForTS/ForTS_Distribution/ForTS_Distribution.gen";
import { distributionTag as Tag } from "../rescript/ForTS/ForTS_Distribution/ForTS_Distribution_tag";
import { environment } from "../rescript/ForTS/ForTS__Types.gen";
import { DistributionError } from "./DistributionError";
import { wrapPointSetDist } from "./PointSetDist";
import { resultMap2 } from "./types";
@ -21,8 +22,7 @@ abstract class AbstractDistribution {
this._value = value;
}
pointSet() {
const env: any = "TODO";
pointSet(env: environment) {
const innerResult = RSDistribution.toPointSet(this._value, env);
return resultMap2(
innerResult,
@ -35,16 +35,28 @@ abstract class AbstractDistribution {
RSDistribution.toString(this._value);
}
mean() {
return RSDistribution.mean(this._value);
mean(env: environment) {
return resultMap2(
RSDistribution.mean({ env }, this._value),
(v: number) => v,
(e: RSDistribution.distributionError) => new DistributionError(e)
);
}
inv(n: number) {
return RSDistribution.inv(this._value, n);
inv(env: environment, n: number) {
return resultMap2(
RSDistribution.inv({ env }, this._value, n),
(v: number) => v,
(e: RSDistribution.distributionError) => new DistributionError(e)
);
}
stdev() {
return RSDistribution.stdev(this._value);
stdev(env: environment) {
return resultMap2(
RSDistribution.stdev({ env }, this._value),
(v: number) => v,
(e: RSDistribution.distributionError) => new DistributionError(e)
);
}
}

View File

@ -8,4 +8,8 @@ export class Lambda {
constructor(_value: T) {
this._value = _value;
}
parameters() {
return RSLambda.parameters(this._value);
}
}

View File

@ -5,7 +5,7 @@ import { pointSetDistributionTag as Tag } from "../rescript/ForTS/ForTS_Distribu
type T = RSPointSetDist.pointSetDistribution;
export type point = { x: number; y: number };
type shape = {
export type shape = {
continuous: point[];
discrete: point[];
};

View File

@ -1,6 +1,6 @@
import * as RSSquiggleValue from "../rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.gen";
import { squiggleValueTag as Tag } from "../rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag";
import { Distribution, wrapDistribution } from "./Distribution";
import { wrapDistribution } from "./Distribution";
import { Lambda } from "./Lambda";
import { LambdaDeclaration } from "./LambdaDeclaration";
import { NameSpace } from "./NameSpace";

View File

@ -1,93 +0,0 @@
import * as RSDistribution from "../rescript/ForTS/ForTS_Distribution/ForTS_Distribution.gen";
import { distributionTag as Tag } from "../rescript/ForTS/ForTS_Distribution/ForTS_Distribution_tag";
import { DistributionError } from "./DistributionError";
import { wrapPointSetDist } from "./PointSetDist";
import { resultMap2 } from "./types";
type T = RSDistribution.distribution;
export { Tag };
export const wrapDistribution = (value: T): Distribution => {
const tag = RSDistribution.getTag(value);
return new tagToClass[tag](value);
};
abstract class AbstractDistribution {
abstract tag: Tag;
_value: T;
constructor(value: T) {
this._value = value;
}
pointSet() {
const env: any = "TODO";
const innerResult = RSDistribution.toPointSet(this._value, env);
return resultMap2(
innerResult,
wrapPointSetDist,
(v: RSDistribution.distributionError) => new DistributionError(v)
);
}
toString() {
RSDistribution.toString(this._value);
}
mean() {
return RSDistribution.mean(this._value);
}
inv(n: number) {
return RSDistribution.inv(this._value, n);
}
stdev() {
return RSDistribution.stdev(this._value);
}
}
const valueMethod = <IR>(
_this: AbstractDistribution,
rsMethod: (v: T) => IR | null | undefined
) => {
const value = rsMethod(_this._value);
if (!value) throw new Error("Internal casting error");
return value;
};
export class PointSetDistribution extends AbstractDistribution {
tag = Tag.DtPointSet;
value() {
return valueMethod(this, RSDistribution.getPointSet);
}
}
export class SampleSetDistribution extends AbstractDistribution {
tag = Tag.DtSampleSet;
value() {
return valueMethod(this, RSDistribution.getSampleSet);
}
}
export class SymbolicDistribution extends AbstractDistribution {
tag = Tag.DtSymbolic;
value() {
return valueMethod(this, RSDistribution.getSymbolic);
}
}
const tagToClass = {
[Tag.DtPointSet]: PointSetDistribution,
[Tag.DtSampleSet]: SampleSetDistribution,
[Tag.DtSymbolic]: SymbolicDistribution,
} as const;
export type Distribution =
| PointSetDistribution
| SampleSetDistribution
| SymbolicDistribution;

View File

@ -15,9 +15,13 @@ import { Project } from "./Project";
import { SquiggleValue, Tag as SquiggleValueTag } from "./SquiggleValue";
export { result } from "../rescript/ForTS/ForTS_Result_tag";
export { Project, SquiggleValue };
export { Distribution, Tag as DistributionTag } from "./Distribution";
export {
Distribution as Distribution,
Tag as DistributionTag,
} from "./Distribution";
export { DistributionError } from "./DistributionError";
export { Record as SquiggleRecord } from "./Record";
export { Lambda } from "./Lambda";
export { SquiggleValueTag };
export {
environment,
@ -25,6 +29,7 @@ export {
} from "../rescript/ForTS/ForTS_Distribution/ForTS_Distribution.gen";
export { ErrorValue } from "./ErrorValue";
export { resultMap } from "./types";
export { shape } from "./PointSetDist";
// import * as _ from "lodash";
// import type {

View File

@ -10,13 +10,13 @@ type environment = ForTS_Distribution_Environment.environment //use
@genType
let defaultEnvironment: environment = DistributionOperation.defaultEnv
@module("ForTS_Distribution_tag") @scope("distributionTag")
@module("./ForTS_Distribution_tag") @scope("distributionTag")
external dtPointSet_: int = "DtPointSet"
@module("ForTS_Distribution_tag") @scope("distributionTag")
@module("./ForTS_Distribution_tag") @scope("distributionTag")
external dtSampleSet_: int = "DtSampleSet"
@module("ForTS_Distribution_tag") @scope("distributionTag")
@module("./ForTS_Distribution_tag") @scope("distributionTag")
external dtSymbolic_: int = "DtSymbolic"
@genType.import("./ForTS_Distribution_tag")

View File

@ -3,13 +3,13 @@
@genType type discreteShape = PointSetTypes.discreteShape
@genType type mixedShape = PointSetTypes.mixedShape
@module("ForTS_Distribution_PointSetDistribution_tag") @scope("pointSetDistributionTag")
@module("./ForTS_Distribution_PointSetDistribution_tag") @scope("pointSetDistributionTag")
external pstMixed_: int = "PstMixed"
@module("ForTS_Distribution_PointSetDistribution_tag") @scope("pointSetDistributionTag")
@module("./ForTS_Distribution_PointSetDistribution_tag") @scope("pointSetDistributionTag")
external pstDiscrete_: int = "PstDiscrete"
@module("ForTS_Distribution_PointSetDistribution_tag") @scope("pointSetDistributionTag")
@module("./ForTS_Distribution_PointSetDistribution_tag") @scope("pointSetDistributionTag")
external pstContinuous_: int = "PstContinuous"
@genType.import("./ForTS_Distribution_PointSetDistribution_tag")

View File

@ -8,6 +8,3 @@ let toString = (v: squiggleValue_Lambda): string =>
let parameters = (v: squiggleValue_Lambda): array<string> => {
v.parameters
}
@genType
let getParameters = parameters