From ff3efeac4c6fdb30cadff56f2fdcad2fcdaf08f4 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Tue, 7 Jun 2022 09:40:24 -0700 Subject: [PATCH 01/11] Adding math utility functions --- .../FunctionRegistry_Helpers.res | 35 +++++++- .../FunctionRegistry_Library.res | 80 +++++++++++++++++++ .../squiggle-lang/src/rescript/Utility/E.res | 1 + 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index 7a216f2d..a78726e6 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -5,6 +5,8 @@ let impossibleError = "Wrong inputs / Logically impossible" module Wrappers = { let symbolic = r => DistributionTypes.Symbolic(r) let evDistribution = r => ReducerInterface_ExpressionValue.EvDistribution(r) + let evNumber = r => ReducerInterface_ExpressionValue.EvNumber(r) + let evArray = r => ReducerInterface_ExpressionValue.EvArray(r) let symbolicEvDistribution = r => r->DistributionTypes.Symbolic->evDistribution } @@ -77,6 +79,21 @@ module Prepare = { pairs } } + + let oneNumber = (values: t): result => { + switch values { + | FRValueNumber(a1) => Ok(a1) + | _ => Error(impossibleError) + } + } + + module ToTypedArray = { + let numbers = (inputs: ts): result, err> => { + let openNumbers = (elements: array) => + elements->E.A2.fmap(oneNumber)->E.A.R.firstErrorOrOpen + inputs->E.A.unsafe_get(0)->ToValueArray.Array.openA->E.R.bind(openNumbers) + } + } } module Process = { @@ -183,9 +200,25 @@ module OneArgDist = { ->E.R.bind(Process.DistOrNumberToDist.oneValueUsingSymbolicDist(~fn, ~value=_, ~env)) ->E.R2.fmap(Wrappers.evDistribution) - let make = (name, fn) => { + let make = (name, fn) => FnDefinition.make(~name, ~inputs=[FRTypeDistOrNumber], ~run=(inputs, env) => inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env) ) +} + +module ArrayNumberDist = { + let make = (name, fn) => { + FnDefinition.make(~name, ~inputs=[FRTypeArray(FRTypeNumber)], ~run=(inputs, _) => + Prepare.ToTypedArray.numbers(inputs)->E.R2.fmap(fn) + ) } } + +module NumberToNumber = { + let make = (name, fn) => + FnDefinition.make(~name, ~inputs=[FRTypeNumber], ~run=(inputs, _) => { + let num = + inputs->E.A.unsafe_get(0)->Prepare.oneNumber->E.R2.fmap(fn)->E.R2.fmap(Wrappers.evNumber) + num + }) +} diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index 6230f828..48abbfdb 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -134,4 +134,84 @@ let registry = [ ~name="Bernoulli", ~definitions=[OneArgDist.make("bernoulli", SymbolicDist.Bernoulli.make)], ), + Function.make( + ~name="Floor", + ~definitions=[NumberToNumber.make("floor", Js.Math.floor_float)] + ), + Function.make( + ~name="Ceiling", + ~definitions=[NumberToNumber.make("ceil", Js.Math.ceil_float)] + ), + Function.make( + ~name="Absolute Value", + ~definitions=[NumberToNumber.make("abs", Js.Math.abs_float)] + ), + Function.make( + ~name="Exponent", + ~definitions=[NumberToNumber.make("exp", Js.Math.exp)] + ), + Function.make( + ~name="Log", + ~definitions=[NumberToNumber.make("log", Js.Math.log)] + ), + Function.make( + ~name="Log Base 10", + ~definitions=[NumberToNumber.make("log10", Js.Math.log10)] + ), + Function.make( + ~name="Log Base 2", + ~definitions=[NumberToNumber.make("log2", Js.Math.log2)] + ), + Function.make( + ~name="Round", + ~definitions=[NumberToNumber.make("round", Js.Math.round)] + ), + Function.make( + ~name="Sum", + ~definitions=[ArrayNumberDist.make("sum", r => r->E.A.Floats.sum->Wrappers.evNumber)], + ), + Function.make( + ~name="Product", + ~definitions=[ArrayNumberDist.make("product", r => r->E.A.Floats.product->Wrappers.evNumber)], + ), + Function.make( + ~name="Min", + ~definitions=[ArrayNumberDist.make("min", r => r->E.A.Floats.min->Wrappers.evNumber)], + ), + Function.make( + ~name="Max", + ~definitions=[ArrayNumberDist.make("max", r => r->E.A.Floats.max->Wrappers.evNumber)], + ), + Function.make( + ~name="Mean", + ~definitions=[ArrayNumberDist.make("mean", r => r->E.A.Floats.mean->Wrappers.evNumber)], + ), + Function.make( + ~name="Geometric Mean", + ~definitions=[ArrayNumberDist.make("geomean", r => r->E.A.Floats.geomean->Wrappers.evNumber)], + ), + Function.make( + ~name="Standard Deviation", + ~definitions=[ArrayNumberDist.make("stdev", r => r->E.A.Floats.stdev->Wrappers.evNumber)], + ), + Function.make( + ~name="Variance", + ~definitions=[ArrayNumberDist.make("variance", r => r->E.A.Floats.stdev->Wrappers.evNumber)], + ), + Function.make( + ~name="Sort", + ~definitions=[ + ArrayNumberDist.make("sort", r => + r->E.A.Floats.sort->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray + ), + ], + ), + Function.make( + ~name="Reverse", + ~definitions=[ + ArrayNumberDist.make("reverse", r => + r->Belt_Array.reverse->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray + ), + ], + ), ] diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index 372ad8ab..06acc25d 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -720,6 +720,7 @@ module A = { let variance = Jstat.variance let stdev = Jstat.stdev let sum = Jstat.sum + let product = Jstat.product let random = Js.Math.random_int let floatCompare: (float, float) => int = compare From 0fcf7e197eb84e0d1e621bda6e6861577ae2fb1c Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Tue, 7 Jun 2022 21:08:39 -0700 Subject: [PATCH 02/11] Added listMake and upTo --- .../FunctionRegistry_Core.res | 34 ++++++++++ .../FunctionRegistry_Helpers.res | 7 ++ .../FunctionRegistry_Library.res | 67 +++++++++++-------- .../squiggle-lang/src/rescript/Utility/E.res | 1 + 4 files changed, 80 insertions(+), 29 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index eed48ffc..a0487e80 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -10,8 +10,10 @@ type rec frType = | FRTypeDistOrNumber | FRTypeLambda | FRTypeRecord(frTypeRecord) + | FRTypeDict(frType) | FRTypeArray(frType) | FRTypeString + | FRTypeAny | FRTypeVariant(array) and frTypeRecord = array and frTypeRecordParam = (string, frType) @@ -29,8 +31,11 @@ type rec frValue = | FRValueLambda(ReducerInterface_ExpressionValue.lambdaValue) | FRValueString(string) | FRValueVariant(string) + | FRValueAny(frValue) + | FRValueDict(Js.Dict.t) and frValueRecord = array and frValueRecordParam = (string, frValue) +and frValueDictParam = (string, frValue) and frValueDistOrNumber = FRValueNumber(float) | FRValueDist(DistributionTypes.genericDist) type fnDefinition = { @@ -61,10 +66,28 @@ module FRType = { | FRTypeLambda => `lambda` | FRTypeString => `string` | FRTypeVariant(_) => "variant" + | FRTypeDict(r) => `dict(${toString(r)})` + | FRTypeAny => `any` + } + + let rec toFrValue = (r: expressionValue): option => + switch r { + | EvNumber(f) => Some(FRValueNumber(f)) + | EvDistribution(f) => Some(FRValueDistOrNumber(FRValueDist(f))) + | EvLambda(f) => Some(FRValueLambda(f)) + | EvArray(elements) => + elements->E.A2.fmap(toFrValue)->E.A.O.openIfAllSome->E.O2.fmap(r => FRValueArray(r)) + | EvRecord(record) => + Js.Dict.entries(record) + ->E.A2.fmap(((key, item)) => item->toFrValue->E.O2.fmap(o => (key, o))) + ->E.A.O.openIfAllSome + ->E.O2.fmap(r => FRValueRecord(r)) + | _ => None } let rec matchWithExpressionValue = (t: t, r: expressionValue): option => switch (t, r) { + | (FRTypeAny, f) => toFrValue(f) | (FRTypeNumber, EvNumber(f)) => Some(FRValueNumber(f)) | (FRTypeDistOrNumber, EvNumber(f)) => Some(FRValueDistOrNumber(FRValueNumber(f))) | (FRTypeDistOrNumber, EvDistribution(Symbolic(#Float(f)))) => @@ -77,6 +100,11 @@ module FRType = { let el = elements->E.A2.fmap(matchWithExpressionValue(intendedType)) E.A.O.openIfAllSome(el)->E.O2.fmap(r => FRValueArray(r)) } + | (FRTypeDict(r), EvRecord(record)) => record + ->Js.Dict.entries + ->E.A2.fmap(((key, item)) => matchWithExpressionValue(r, item)->E.O2.fmap(o => (key, o))) + ->E.A.O.openIfAllSome + ->E.O2.fmap(r => FRValueDict(Js.Dict.fromArray(r))) | (FRTypeRecord(recordParams), EvRecord(record)) => { let getAndMatch = (name, input) => E.Dict.get(record, name)->E.O.bind(matchWithExpressionValue(input)) @@ -103,9 +131,15 @@ module FRType = { frValueRecord->E.A2.fmap(((name, value)) => (name, matchReverse(value)))->E.Dict.fromArray EvRecord(record) } + | FRValueDict(frValueRecord) => { + let record = + frValueRecord->Js.Dict.entries->E.A2.fmap(((name, value)) => (name, matchReverse(value)))->E.Dict.fromArray + EvRecord(record) + } | FRValueLambda(l) => EvLambda(l) | FRValueString(string) => EvString(string) | FRValueVariant(string) => EvString(string) + | FRValueAny(f) => matchReverse(f) } let matchWithExpressionValueArray = (inputs: array, args: array): option< diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index a78726e6..29535c05 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -54,6 +54,13 @@ module Prepare = { } } + let threeNumbers = (values: ts): result<(float, float, float), err> => { + switch values { + | [FRValueNumber(a1), FRValueNumber(a2), FRValueNumber(a3)] => Ok(a1, a2, a3) + | _ => Error(impossibleError) + } + } + let oneDistOrNumber = (values: ts): result => { switch values { | [FRValueDistOrNumber(a1)] => Ok(a1) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index 48abbfdb..21d61508 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -134,38 +134,17 @@ let registry = [ ~name="Bernoulli", ~definitions=[OneArgDist.make("bernoulli", SymbolicDist.Bernoulli.make)], ), - Function.make( - ~name="Floor", - ~definitions=[NumberToNumber.make("floor", Js.Math.floor_float)] - ), - Function.make( - ~name="Ceiling", - ~definitions=[NumberToNumber.make("ceil", Js.Math.ceil_float)] - ), + Function.make(~name="Floor", ~definitions=[NumberToNumber.make("floor", Js.Math.floor_float)]), + Function.make(~name="Ceiling", ~definitions=[NumberToNumber.make("ceil", Js.Math.ceil_float)]), Function.make( ~name="Absolute Value", - ~definitions=[NumberToNumber.make("abs", Js.Math.abs_float)] - ), - Function.make( - ~name="Exponent", - ~definitions=[NumberToNumber.make("exp", Js.Math.exp)] - ), - Function.make( - ~name="Log", - ~definitions=[NumberToNumber.make("log", Js.Math.log)] - ), - Function.make( - ~name="Log Base 10", - ~definitions=[NumberToNumber.make("log10", Js.Math.log10)] - ), - Function.make( - ~name="Log Base 2", - ~definitions=[NumberToNumber.make("log2", Js.Math.log2)] - ), - Function.make( - ~name="Round", - ~definitions=[NumberToNumber.make("round", Js.Math.round)] + ~definitions=[NumberToNumber.make("abs", Js.Math.abs_float)], ), + Function.make(~name="Exponent", ~definitions=[NumberToNumber.make("exp", Js.Math.exp)]), + Function.make(~name="Log", ~definitions=[NumberToNumber.make("log", Js.Math.log)]), + Function.make(~name="Log Base 10", ~definitions=[NumberToNumber.make("log10", Js.Math.log10)]), + Function.make(~name="Log Base 2", ~definitions=[NumberToNumber.make("log2", Js.Math.log2)]), + Function.make(~name="Round", ~definitions=[NumberToNumber.make("round", Js.Math.round)]), Function.make( ~name="Sum", ~definitions=[ArrayNumberDist.make("sum", r => r->E.A.Floats.sum->Wrappers.evNumber)], @@ -214,4 +193,34 @@ let registry = [ ), ], ), + Function.make( + ~name="List.make", + ~definitions=[ + //Todo: If the second item is a function with no args, it could be nice to run this function and return the result. + FnDefinition.make(~name="listMake", ~inputs=[FRTypeNumber, FRTypeAny], ~run=(inputs, _) => { + switch inputs { + | [FRValueNumber(number), value] => + Belt.Array.make(E.Float.toInt(number), value) + ->E.A2.fmap(FunctionRegistry_Core.FRType.matchReverse) + ->Wrappers.evArray + ->Ok + | _ => Error(impossibleError) + } + }), + ], + ), + Function.make( + ~name="Range", + ~definitions=[ + FnDefinition.make(~name="upTo", ~inputs=[FRTypeNumber, FRTypeNumber], ~run=(inputs, _) => + inputs + ->Prepare.ToValueTuple.twoNumbers + ->E.R2.fmap(((low, high)) => + E.A.Floats.range(low, high, (high -. low +. 1.0)->E.Float.toInt) + ->E.A2.fmap(Wrappers.evNumber) + ->Wrappers.evArray + ) + ), + ], + ), ] diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index 06acc25d..7dd1d5f2 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -207,6 +207,7 @@ module Float = { let toFixed = Js.Float.toFixed let toString = Js.Float.toString let isFinite = Js.Float.isFinite + let toInt = Belt.Float.toInt } module I = { From 8d1d08eaa033ef57226f8df58cd4251846bd9c62 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Tue, 7 Jun 2022 22:35:40 -0700 Subject: [PATCH 03/11] Simple dict merge and mergeMany --- .../FunctionRegistry_Core.res | 8 +++- .../FunctionRegistry_Helpers.res | 15 ++++++++ .../FunctionRegistry_Library.res | 37 +++++++++++++++++++ .../squiggle-lang/src/rescript/Utility/E.res | 4 ++ 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index a0487e80..82e58eff 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -100,7 +100,8 @@ module FRType = { let el = elements->E.A2.fmap(matchWithExpressionValue(intendedType)) E.A.O.openIfAllSome(el)->E.O2.fmap(r => FRValueArray(r)) } - | (FRTypeDict(r), EvRecord(record)) => record + | (FRTypeDict(r), EvRecord(record)) => + record ->Js.Dict.entries ->E.A2.fmap(((key, item)) => matchWithExpressionValue(r, item)->E.O2.fmap(o => (key, o))) ->E.A.O.openIfAllSome @@ -133,7 +134,10 @@ module FRType = { } | FRValueDict(frValueRecord) => { let record = - frValueRecord->Js.Dict.entries->E.A2.fmap(((name, value)) => (name, matchReverse(value)))->E.Dict.fromArray + frValueRecord + ->Js.Dict.entries + ->E.A2.fmap(((name, value)) => (name, matchReverse(value))) + ->E.Dict.fromArray EvRecord(record) } | FRValueLambda(l) => EvLambda(l) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index 29535c05..ecbb461c 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -7,6 +7,7 @@ module Wrappers = { let evDistribution = r => ReducerInterface_ExpressionValue.EvDistribution(r) let evNumber = r => ReducerInterface_ExpressionValue.EvNumber(r) let evArray = r => ReducerInterface_ExpressionValue.EvArray(r) + let evRecord = r => ReducerInterface_ExpressionValue.EvRecord(r) let symbolicEvDistribution = r => r->DistributionTypes.Symbolic->evDistribution } @@ -94,12 +95,26 @@ module Prepare = { } } + let oneDict = (values: t): result, err> => { + switch values { + | FRValueDict(a1) => Ok(a1) + | _ => Error(impossibleError) + } + } + module ToTypedArray = { let numbers = (inputs: ts): result, err> => { let openNumbers = (elements: array) => elements->E.A2.fmap(oneNumber)->E.A.R.firstErrorOrOpen inputs->E.A.unsafe_get(0)->ToValueArray.Array.openA->E.R.bind(openNumbers) } + + let dicts = (inputs: ts): Belt.Result.t>, err> => { + Js.log2("HIHIHI", "HI") + let openDicts = (elements: array) => elements->E.A2.fmap(oneDict)->E.A.R.firstErrorOrOpen + Js.log2("Inputs?", inputs); + inputs->E.A.unsafe_get(0)->ToValueArray.Array.openA->E.R.bind(openDicts) + } } } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index 21d61508..2d8c09c0 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -193,6 +193,43 @@ let registry = [ ), ], ), + Function.make( + ~name="Dict.merge", + ~definitions=[ + FnDefinition.make( + ~name="merge", + ~inputs=[FRTypeDict(FRTypeAny), FRTypeDict(FRTypeAny)], + ~run=(inputs, _) => { + switch inputs { + | [FRValueDict(d1), FRValueDict(d2)] => { + let newDict = + E.Dict.concat(d1, d2) |> Js.Dict.map((. r) => + FunctionRegistry_Core.FRType.matchReverse(r) + ) + newDict->Wrappers.evRecord->Ok + } + | _ => Error(impossibleError) + } + }, + ), + ], + ), + //TODO: Make sure that two functions cant have the same name. This causes chaos elsewhere. + Function.make( + ~name="Dict.mergeMany", + ~definitions=[ + FnDefinition.make(~name="mergeMany", ~inputs=[FRTypeArray(FRTypeDict(FRTypeAny))], ~run=( + inputs, + _, + ) => + inputs + ->Prepare.ToTypedArray.dicts + ->E.R2.fmap(E.Dict.concatMany) + ->E.R2.fmap(Js.Dict.map((. r) => FunctionRegistry_Core.FRType.matchReverse(r))) + ->E.R2.fmap(Wrappers.evRecord) + ), + ], + ), Function.make( ~name="List.make", ~definitions=[ diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index 7dd1d5f2..d170a930 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -540,6 +540,7 @@ module A = { let hasBy = (r, fn) => Belt.Array.getBy(r, fn) |> O.isSome let fold_left = Array.fold_left let fold_right = Array.fold_right + let concat = Belt.Array.concat let concatMany = Belt.Array.concatMany let keepMap = Belt.Array.keepMap let slice = Belt.Array.slice @@ -874,4 +875,7 @@ module Dict = { let get = Js.Dict.get let keys = Js.Dict.keys let fromArray = Js.Dict.fromArray + let toArray = Js.Dict.entries + let concat = (a, b) => A.concat(toArray(a), toArray(b))->fromArray + let concatMany = ts => ts->A2.fmap(toArray)->A.concatMany->fromArray } From 12cdb4ed3639e174e8b1606632bbb291c3d9e65e Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Wed, 8 Jun 2022 07:24:06 -0700 Subject: [PATCH 04/11] Added dict keys, values, fromList, toList --- .../FunctionRegistry_Core.res | 4 +- .../FunctionRegistry_Helpers.res | 9 ++- .../FunctionRegistry_Library.res | 72 ++++++++++++++++++- 3 files changed, 81 insertions(+), 4 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index 82e58eff..845d2ffc 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -62,7 +62,7 @@ module FRType = { let input = ((name, frType): frTypeRecordParam) => `${name}: ${toString(frType)}` `record({${r->E.A2.fmap(input)->E.A2.joinWith(", ")}})` } - | FRTypeArray(r) => `record(${toString(r)})` + | FRTypeArray(r) => `list(${toString(r)})` | FRTypeLambda => `lambda` | FRTypeString => `string` | FRTypeVariant(_) => "variant" @@ -73,6 +73,7 @@ module FRType = { let rec toFrValue = (r: expressionValue): option => switch r { | EvNumber(f) => Some(FRValueNumber(f)) + | EvString(f) => Some(FRValueString(f)) | EvDistribution(f) => Some(FRValueDistOrNumber(FRValueDist(f))) | EvLambda(f) => Some(FRValueLambda(f)) | EvArray(elements) => @@ -88,6 +89,7 @@ module FRType = { let rec matchWithExpressionValue = (t: t, r: expressionValue): option => switch (t, r) { | (FRTypeAny, f) => toFrValue(f) + | (FRTypeString, EvString(f)) => Some(FRValueString(f)) | (FRTypeNumber, EvNumber(f)) => Some(FRValueNumber(f)) | (FRTypeDistOrNumber, EvNumber(f)) => Some(FRValueDistOrNumber(FRValueNumber(f))) | (FRTypeDistOrNumber, EvDistribution(Symbolic(#Float(f)))) => diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index ecbb461c..b5ff2e75 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -8,6 +8,7 @@ module Wrappers = { let evNumber = r => ReducerInterface_ExpressionValue.EvNumber(r) let evArray = r => ReducerInterface_ExpressionValue.EvArray(r) let evRecord = r => ReducerInterface_ExpressionValue.EvRecord(r) + let evString = r => ReducerInterface_ExpressionValue.EvString(r) let symbolicEvDistribution = r => r->DistributionTypes.Symbolic->evDistribution } @@ -37,6 +38,12 @@ module Prepare = { | FRValueArray(n) => Ok(n) | _ => Error(impossibleError) } + + let arrayOfArrays = (inputs: t): result, err> => + switch inputs { + | FRValueArray(n) => n->E.A2.fmap(openA)->E.A.R.firstErrorOrOpen + | _ => Error(impossibleError) + } } } @@ -110,9 +117,7 @@ module Prepare = { } let dicts = (inputs: ts): Belt.Result.t>, err> => { - Js.log2("HIHIHI", "HI") let openDicts = (elements: array) => elements->E.A2.fmap(oneDict)->E.A.R.firstErrorOrOpen - Js.log2("Inputs?", inputs); inputs->E.A.unsafe_get(0)->ToValueArray.Array.openA->E.R.bind(openDicts) } } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index 2d8c09c0..a2c07acd 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -214,7 +214,7 @@ let registry = [ ), ], ), - //TODO: Make sure that two functions cant have the same name. This causes chaos elsewhere. + //TODO: Make sure that two functions can't have the same name. This causes chaos elsewhere. Function.make( ~name="Dict.mergeMany", ~definitions=[ @@ -230,6 +230,76 @@ let registry = [ ), ], ), + Function.make( + ~name="Dict.keys", + ~definitions=[ + FnDefinition.make(~name="keys", ~inputs=[FRTypeDict(FRTypeAny)], ~run=(inputs, _) => + switch inputs { + | [FRValueDict(d1)] => Js.Dict.keys(d1)->E.A2.fmap(Wrappers.evString)->Wrappers.evArray->Ok + | _ => Error(impossibleError) + } + ), + ], + ), + Function.make( + ~name="Dict.values", + ~definitions=[ + FnDefinition.make(~name="values", ~inputs=[FRTypeDict(FRTypeAny)], ~run=(inputs, _) => + switch inputs { + | [FRValueDict(d1)] => + Js.Dict.values(d1) + ->E.A2.fmap(FunctionRegistry_Core.FRType.matchReverse) + ->Wrappers.evArray + ->Ok + | _ => Error(impossibleError) + } + ), + ], + ), + Function.make( + ~name="Dict.toList", + ~definitions=[ + FnDefinition.make(~name="toList", ~inputs=[FRTypeDict(FRTypeAny)], ~run=(inputs, _) => + switch inputs { + | [FRValueDict(dict)] => + dict + ->Js.Dict.entries + ->E.A2.fmap(((key, value)) => + Wrappers.evArray([ + Wrappers.evString(key), + FunctionRegistry_Core.FRType.matchReverse(value), + ]) + ) + ->Wrappers.evArray + ->Ok + | _ => Error(impossibleError) + } + ), + ], + ), + Function.make( + ~name="Dict.fromList", + ~definitions=[ + FnDefinition.make(~name="fromList", ~inputs=[FRTypeArray(FRTypeArray(FRTypeAny))], ~run=( + inputs, + _, + ) => { + let convertInternalItems = items => + items + ->E.A2.fmap(item => { + switch item { + | [FRValueString(string), value] => + (string, FunctionRegistry_Core.FRType.matchReverse(value))->Ok + | _ => Error(impossibleError) + } + }) + ->E.A.R.firstErrorOrOpen + ->E.R2.fmap(Js.Dict.fromArray) + ->E.R2.fmap(Wrappers.evRecord) + inputs->E.A.unsafe_get(0)->Prepare.ToValueArray.Array.arrayOfArrays |> E.R2.bind(convertInternalItems) + }), + ], + ), Function.make( ~name="List.make", ~definitions=[ From fc407440530bb41f7cb714750818c16fb0644d9d Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Wed, 8 Jun 2022 08:00:06 -0700 Subject: [PATCH 05/11] Simple additions of first, last, cumulative sum, diff --- .../FunctionRegistry_Helpers.res | 11 +++- .../FunctionRegistry_Library.res | 61 +++++++++++++++---- .../squiggle-lang/src/rescript/Utility/E.res | 3 + 3 files changed, 63 insertions(+), 12 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index b5ff2e75..9eb13837 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -236,7 +236,16 @@ module OneArgDist = { module ArrayNumberDist = { let make = (name, fn) => { FnDefinition.make(~name, ~inputs=[FRTypeArray(FRTypeNumber)], ~run=(inputs, _) => - Prepare.ToTypedArray.numbers(inputs)->E.R2.fmap(fn) + Prepare.ToTypedArray.numbers(inputs) + ->E.R.bind(r => E.A.length(r) === 0 ? Error("List is empty") : Ok(r)) + ->E.R.bind(fn) + ) + } + let make2 = (name, fn) => { + FnDefinition.make(~name, ~inputs=[FRTypeArray(FRTypeAny)], ~run=(inputs, _) => + Prepare.ToTypedArray.numbers(inputs) + ->E.R.bind(r => E.A.length(r) === 0 ? Error("List is empty") : Ok(r)) + ->E.R.bind(fn) ) } } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index a2c07acd..12445f71 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -147,41 +147,63 @@ let registry = [ Function.make(~name="Round", ~definitions=[NumberToNumber.make("round", Js.Math.round)]), Function.make( ~name="Sum", - ~definitions=[ArrayNumberDist.make("sum", r => r->E.A.Floats.sum->Wrappers.evNumber)], + ~definitions=[ArrayNumberDist.make("sum", r => r->E.A.Floats.sum->Wrappers.evNumber->Ok)], ), Function.make( ~name="Product", - ~definitions=[ArrayNumberDist.make("product", r => r->E.A.Floats.product->Wrappers.evNumber)], + ~definitions=[ + ArrayNumberDist.make("product", r => r->E.A.Floats.product->Wrappers.evNumber->Ok), + ], ), Function.make( ~name="Min", - ~definitions=[ArrayNumberDist.make("min", r => r->E.A.Floats.min->Wrappers.evNumber)], + ~definitions=[ArrayNumberDist.make("min", r => r->E.A.Floats.min->Wrappers.evNumber->Ok)], ), Function.make( ~name="Max", - ~definitions=[ArrayNumberDist.make("max", r => r->E.A.Floats.max->Wrappers.evNumber)], + ~definitions=[ArrayNumberDist.make("max", r => r->E.A.Floats.max->Wrappers.evNumber->Ok)], ), Function.make( ~name="Mean", - ~definitions=[ArrayNumberDist.make("mean", r => r->E.A.Floats.mean->Wrappers.evNumber)], + ~definitions=[ArrayNumberDist.make("mean", r => r->E.A.Floats.mean->Wrappers.evNumber->Ok)], ), Function.make( ~name="Geometric Mean", - ~definitions=[ArrayNumberDist.make("geomean", r => r->E.A.Floats.geomean->Wrappers.evNumber)], + ~definitions=[ + ArrayNumberDist.make("geomean", r => r->E.A.Floats.geomean->Wrappers.evNumber->Ok), + ], ), Function.make( ~name="Standard Deviation", - ~definitions=[ArrayNumberDist.make("stdev", r => r->E.A.Floats.stdev->Wrappers.evNumber)], + ~definitions=[ArrayNumberDist.make("stdev", r => r->E.A.Floats.stdev->Wrappers.evNumber->Ok)], ), Function.make( ~name="Variance", - ~definitions=[ArrayNumberDist.make("variance", r => r->E.A.Floats.stdev->Wrappers.evNumber)], + ~definitions=[ + ArrayNumberDist.make("variance", r => r->E.A.Floats.stdev->Wrappers.evNumber->Ok), + ], + ), + Function.make( + ~name="First", + ~definitions=[ + ArrayNumberDist.make2("first", r => + r->E.A.first |> E.O.toResult(impossibleError) |> E.R.fmap(Wrappers.evNumber) + ), + ], + ), + Function.make( + ~name="Last", + ~definitions=[ + ArrayNumberDist.make2("last", r => + r->E.A.last |> E.O.toResult(impossibleError) |> E.R.fmap(Wrappers.evNumber) + ), + ], ), Function.make( ~name="Sort", ~definitions=[ ArrayNumberDist.make("sort", r => - r->E.A.Floats.sort->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray + r->E.A.Floats.sort->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray->Ok ), ], ), @@ -189,7 +211,23 @@ let registry = [ ~name="Reverse", ~definitions=[ ArrayNumberDist.make("reverse", r => - r->Belt_Array.reverse->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray + r->Belt_Array.reverse->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray->Ok + ), + ], + ), + Function.make( + ~name="Cumulative Sum", + ~definitions=[ + ArrayNumberDist.make("cumsum", r => + r->E.A.Floats.cumsum->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray->Ok + ), + ], + ), + Function.make( + ~name="Diff", + ~definitions=[ + ArrayNumberDist.make("diff", r => + r->E.A.Floats.diff->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray->Ok ), ], ), @@ -296,7 +334,8 @@ let registry = [ ->E.A.R.firstErrorOrOpen ->E.R2.fmap(Js.Dict.fromArray) ->E.R2.fmap(Wrappers.evRecord) - inputs->E.A.unsafe_get(0)->Prepare.ToValueArray.Array.arrayOfArrays |> E.R2.bind(convertInternalItems) + inputs->E.A.unsafe_get(0)->Prepare.ToValueArray.Array.arrayOfArrays + |> E.R2.bind(convertInternalItems) }), ], ), diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index d170a930..70ca4994 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -751,6 +751,9 @@ module A = { let diff = (t: t): array => Belt.Array.zipBy(t, Belt.Array.sliceToEnd(t, 1), (left, right) => right -. left) + let cumsum = (t: t): array => accumulate((a, b) => a +. b, t) + let cumProd = (t: t): array => accumulate((a, b) => a *. b, t) + exception RangeError(string) let range = (min: float, max: float, n: int): array => switch n { From b48a0575d9348ef70dff05e28b36973739c4841f Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Wed, 8 Jun 2022 08:21:20 -0700 Subject: [PATCH 06/11] Cumprod and formatting --- .../FunctionRegistry/FunctionRegistry_Library.res | 8 ++++++++ .../rescript/ReducerInterface/ReducerInterface_Date.res | 2 +- .../ReducerInterface/ReducerInterface_Duration.res | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index 12445f71..130f4c80 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -223,6 +223,14 @@ let registry = [ ), ], ), + Function.make( + ~name="Cumulative Prod", + ~definitions=[ + ArrayNumberDist.make("cumprod", r => + r->E.A.Floats.cumsum->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray->Ok + ), + ], + ), Function.make( ~name="Diff", ~definitions=[ diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Date.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Date.res index dc04a474..02c3affc 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Date.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Date.res @@ -24,4 +24,4 @@ let dispatch = (call: EV.functionCall, _: DistributionOperation.env): option< EV.EvDate(DateTime.Date.addDuration(d1, d2))->Ok->Some | _ => None } -} \ No newline at end of file +} diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res index a11aa745..4e10dfa0 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res @@ -29,4 +29,4 @@ let dispatch = (call: EV.functionCall, _: DistributionOperation.env): option< EV.EvTimeDuration(DateTime.Duration.divide(d1, d2))->Ok->Some | _ => None } -} \ No newline at end of file +} From 1acd4fc259e5965e8cf7712b6823b54f559a3c86 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 9 Jun 2022 06:34:31 -0700 Subject: [PATCH 07/11] Minor cleanup --- .../FunctionRegistry/FunctionRegistry_Helpers.res | 14 +++++++++----- .../FunctionRegistry/FunctionRegistry_Library.res | 8 ++++---- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index 9eb13837..7d0240eb 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -12,6 +12,8 @@ module Wrappers = { let symbolicEvDistribution = r => r->DistributionTypes.Symbolic->evDistribution } +let getOrError = (a, g) => E.A.get(a, g) |> E.O.toResult(impossibleError) + module Prepare = { type t = frValue type ts = array @@ -113,12 +115,12 @@ module Prepare = { let numbers = (inputs: ts): result, err> => { let openNumbers = (elements: array) => elements->E.A2.fmap(oneNumber)->E.A.R.firstErrorOrOpen - inputs->E.A.unsafe_get(0)->ToValueArray.Array.openA->E.R.bind(openNumbers) + inputs->getOrError(0)->E.R.bind(ToValueArray.Array.openA)->E.R.bind(openNumbers) } let dicts = (inputs: ts): Belt.Result.t>, err> => { let openDicts = (elements: array) => elements->E.A2.fmap(oneDict)->E.A.R.firstErrorOrOpen - inputs->E.A.unsafe_get(0)->ToValueArray.Array.openA->E.R.bind(openDicts) + inputs->getOrError(0)->E.R.bind(ToValueArray.Array.openA)->E.R.bind(openDicts) } } } @@ -253,8 +255,10 @@ module ArrayNumberDist = { module NumberToNumber = { let make = (name, fn) => FnDefinition.make(~name, ~inputs=[FRTypeNumber], ~run=(inputs, _) => { - let num = - inputs->E.A.unsafe_get(0)->Prepare.oneNumber->E.R2.fmap(fn)->E.R2.fmap(Wrappers.evNumber) - num + inputs + ->getOrError(0) + ->E.R.bind(Prepare.oneNumber) + ->E.R2.fmap(fn) + ->E.R2.fmap(Wrappers.evNumber) }) } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index 130f4c80..074e274b 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -31,7 +31,7 @@ module Declaration = { } let inputsTodist = (inputs: array, makeDist) => { - let array = inputs->E.A.unsafe_get(0)->Prepare.ToValueArray.Array.openA + let array = inputs->getOrError(0)->E.R.bind(Prepare.ToValueArray.Array.openA) let xyCoords = array->E.R.bind(xyCoords => xyCoords @@ -72,7 +72,7 @@ let registry = [ ~name="Declaration", ~definitions=[ FnDefinition.make(~name="declareFn", ~inputs=[Declaration.frType], ~run=(inputs, _) => { - inputs->E.A.unsafe_get(0)->Declaration.fromExpressionValue + inputs->getOrError(0)->E.R.bind(Declaration.fromExpressionValue) }), ], ), @@ -342,7 +342,7 @@ let registry = [ ->E.A.R.firstErrorOrOpen ->E.R2.fmap(Js.Dict.fromArray) ->E.R2.fmap(Wrappers.evRecord) - inputs->E.A.unsafe_get(0)->Prepare.ToValueArray.Array.arrayOfArrays + inputs->getOrError(0)->E.R.bind(Prepare.ToValueArray.Array.arrayOfArrays) |> E.R2.bind(convertInternalItems) }), ], @@ -364,7 +364,7 @@ let registry = [ ], ), Function.make( - ~name="Range", + ~name="upTo", ~definitions=[ FnDefinition.make(~name="upTo", ~inputs=[FRTypeNumber, FRTypeNumber], ~run=(inputs, _) => inputs From d812084614722d65e324e3f04e5026c38a564b2b Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Thu, 9 Jun 2022 23:57:45 +0300 Subject: [PATCH 08/11] scoped tailwind preflight, top-level .squiggle wrapper --- packages/components/.storybook/preview.js | 13 +- packages/components/package.json | 4 +- packages/components/postcss.config.js | 2 + packages/components/src/components/Alert.tsx | 9 +- .../src/components/DistributionChart.tsx | 4 +- .../src/components/SquiggleContainer.tsx | 25 + .../src/components/SquiggleEditor.tsx | 71 +-- .../src/components/SquigglePlayground.tsx | 114 ++-- packages/components/src/index.ts | 1 + packages/components/src/styles/base.css | 510 ++++++++++++++++++ packages/components/src/styles/main.css | 8 + packages/components/src/tailwind.css | 4 - packages/components/tailwind.config.js | 1 + packages/components/webpack.config.js | 2 +- packages/website/package.json | 1 - yarn.lock | 325 ++++------- 16 files changed, 775 insertions(+), 319 deletions(-) create mode 100644 packages/components/src/components/SquiggleContainer.tsx create mode 100644 packages/components/src/styles/base.css create mode 100644 packages/components/src/styles/main.css delete mode 100644 packages/components/src/tailwind.css diff --git a/packages/components/.storybook/preview.js b/packages/components/.storybook/preview.js index afd31ccf..a128782c 100644 --- a/packages/components/.storybook/preview.js +++ b/packages/components/.storybook/preview.js @@ -1,4 +1,15 @@ -import "../src/tailwind.css"; +import "../src/styles/main.css"; +import "!style-loader!css-loader!postcss-loader!../src/styles/main.css"; +import { SquiggleContainer } from "../src/components/SquiggleContainer"; + +export const decorators = [ + (Story) => ( + + + + ), +]; + export const parameters = { actions: { argTypesRegex: "^on[A-Z].*" }, controls: { diff --git a/packages/components/package.json b/packages/components/package.json index 62735a76..e5023e10 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -43,6 +43,8 @@ "@types/webpack": "^5.28.0", "cross-env": "^7.0.3", "mini-css-extract-plugin": "^2.6.0", + "postcss-cli": "^9.1.0", + "postcss-import": "^14.1.0", "postcss-loader": "^7.0.0", "react-scripts": "^5.0.1", "style-loader": "^3.3.1", @@ -57,7 +59,7 @@ }, "scripts": { "start": "cross-env REACT_APP_FAST_REFRESH=false && start-storybook -p 6006 -s public", - "build": "tsc -b && tailwindcss -i ./src/tailwind.css -o ./dist/main.css && build-storybook -s public", + "build": "tsc -b && postcss ./src/styles/main.css -o ./dist/main.css && build-storybook -s public", "bundle": "webpack", "all": "yarn bundle && yarn build", "lint": "prettier --check .", diff --git a/packages/components/postcss.config.js b/packages/components/postcss.config.js index 3691aac9..74eecfcd 100644 --- a/packages/components/postcss.config.js +++ b/packages/components/postcss.config.js @@ -1,5 +1,7 @@ module.exports = { plugins: { + "postcss-import": {}, + "tailwindcss/nesting": {}, tailwindcss: {}, autoprefixer: {}, cssnano: {}, diff --git a/packages/components/src/components/Alert.tsx b/packages/components/src/components/Alert.tsx index 590b1cca..bc2e2f92 100644 --- a/packages/components/src/components/Alert.tsx +++ b/packages/components/src/components/Alert.tsx @@ -4,6 +4,7 @@ import { InformationCircleIcon, CheckCircleIcon, } from "@heroicons/react/solid"; +import clsx from "clsx"; export const Alert: React.FC<{ heading: string; @@ -23,18 +24,18 @@ export const Alert: React.FC<{ children, }) => { return ( -
+
diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 276e73d5..4069165b 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -9,6 +9,8 @@ import { Vega, VisualizationSpec } from "react-vega"; import * as chartSpecification from "../vega-specs/spec-distributions.json"; import { ErrorAlert } from "./Alert"; import { useSize } from "react-use"; +import clsx from "clsx"; + import { linearXScale, logXScale, @@ -128,7 +130,7 @@ export const CheckBox: React.FC = ({ onChange={() => onChange(!value)} disabled={disabled} /> - + ); }; diff --git a/packages/components/src/components/SquiggleContainer.tsx b/packages/components/src/components/SquiggleContainer.tsx new file mode 100644 index 00000000..63dbb54a --- /dev/null +++ b/packages/components/src/components/SquiggleContainer.tsx @@ -0,0 +1,25 @@ +import React, { useContext } from "react"; + +type Props = { + children: React.ReactNode; +}; + +type SquiggleContextShape = { + containerized: boolean; +}; +const SquiggleContext = React.createContext({ + containerized: false, +}); + +export const SquiggleContainer: React.FC = ({ children }) => { + const context = useContext(SquiggleContext); + if (context.containerized) { + return <>{children}; + } else { + return ( + +
{children}
+
+ ); + } +}; diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index e35de4f5..a8db78af 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -15,6 +15,7 @@ import { defaultBindings, } from "@quri/squiggle-lang"; import { ErrorAlert } from "./Alert"; +import { SquiggleContainer } from "./SquiggleContainer"; export interface SquiggleEditorProps { /** The input string for squiggle */ @@ -64,29 +65,31 @@ export let SquiggleEditor: React.FC = ({ count: diagramCount, }; return ( -
-
- +
+
+ +
+
- -
+ ); }; @@ -171,18 +174,22 @@ export let SquigglePartial: React.FC = ({ React.useEffect(runSquiggleAndUpdateBindings, [expression]); return ( -
-
- + +
+
+ +
+ {error !== null ? ( + {error} + ) : null}
- {error !== null ? {error} : null} -
+ ); }; diff --git a/packages/components/src/components/SquigglePlayground.tsx b/packages/components/src/components/SquigglePlayground.tsx index e0214af6..84939f62 100644 --- a/packages/components/src/components/SquigglePlayground.tsx +++ b/packages/components/src/components/SquigglePlayground.tsx @@ -10,6 +10,7 @@ import { CogIcon, CurrencyDollarIcon, } from "@heroicons/react/solid"; +import clsx from "clsx"; import { defaultBindings, environment } from "@quri/squiggle-lang"; @@ -17,6 +18,7 @@ import { SquiggleChart } from "./SquiggleChart"; import { CodeEditor } from "./CodeEditor"; import { JsonEditor } from "./JsonEditor"; import { ErrorAlert, SuccessAlert } from "./Alert"; +import { SquiggleContainer } from "./SquiggleContainer"; interface PlaygroundProps { /** The initial squiggle string to put in the playground */ @@ -87,10 +89,6 @@ const schema = yup }) .required(); -function classNames(...classes: string[]) { - return classes.filter(Boolean).join(" "); -} - type StyledTabProps = { name: string; icon: (props: React.ComponentProps<"svg">) => JSX.Element; @@ -102,15 +100,13 @@ const StyledTab: React.FC = ({ name, icon: Icon }) => { {({ selected }) => (