diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 3694f142..a6b645f8 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -36,6 +36,15 @@ You need `yarn`.
TODO: fill this out based on all the different packages scripts once they cool down.
+## If you're on NixOS
+
+You'll need to run a command like this in order to get `yarn build` to run, especially in `packages/squiggle-lang`.
+```sh
+patchelf --set-interpreter $(patchelf --print-interpreter $(which mkdir)) ./node_modules/gentype/gentype.exe
+```
+
+See [here](https://github.com/NixOS/nixpkgs/issues/107375)
+
# Pull request protocol
Please work against `staging` branch. **Do not** work against `master`. Please do not merge without approval from some subset of Quinn, Sam, and Ozzie; they will be auto-pinged.
diff --git a/flake.nix b/flake.nix
index fc4595b8..d39ba79a 100644
--- a/flake.nix
+++ b/flake.nix
@@ -44,6 +44,7 @@
yarn2nix
nodePackages.npm
nodejs
+ patchelf
(pkgs.vscode-with-extensions.override {
vscode = pkgs.vscodium;
vscodeExtensions = pkgs.vscode-utils.extensionsFromVscodeMarketplace [
diff --git a/packages/squiggle-lang/__tests__/Symbolic_test.res b/packages/squiggle-lang/__tests__/Symbolic_test.res
new file mode 100644
index 00000000..8ec3be22
--- /dev/null
+++ b/packages/squiggle-lang/__tests__/Symbolic_test.res
@@ -0,0 +1,33 @@
+open Jest
+open Expect
+open Js.Array
+open SymbolicDist
+
+let makeTest = (~only=false, str, item1, item2) =>
+ only
+ ? Only.test(str, () => expect(item1) -> toEqual(item2))
+ : test(str, () => expect(item1) -> toEqual(item2))
+
+let pdfImage = (thePdf, inps) => map(thePdf, inps)
+
+let parameterWiseAdditionHelper = (n1: SymbolicDistTypes.normal, n2: SymbolicDistTypes.normal) => {
+ let normalDistAtSumMeanConstr = Normal.add(n1, n2)
+ let normalDistAtSumMean: SymbolicDistTypes.normal = switch normalDistAtSumMeanConstr {
+ | #Normal(params) => params
+ }
+ x => Normal.pdf(x, normalDistAtSumMean)
+}
+
+describe("Normal distribution with sparklines", () => {
+
+ let normalDistAtMean5: SymbolicDistTypes.normal = {mean: 5.0, stdev: 2.0}
+ let normalDistAtMean10: SymbolicDistTypes.normal = {mean: 10.0, stdev: 2.0}
+ let range20Float = E.A.rangeFloat(0, 20) // [0.0,1.0,2.0,3.0,4.0,...19.0,]
+
+ let pdfNormalDistAtMean5 = x => Normal.pdf(x, normalDistAtMean5)
+ let sparklineMean5 = pdfImage(pdfNormalDistAtMean5, range20Float)
+ makeTest("mean=5", Sparklines.create(sparklineMean5, ()), `▁▂▃▅███▅▃▂▁▁▁▁▁▁▁▁▁▁▁`)
+
+ let sparklineMean15 = normalDistAtMean5 -> parameterWiseAdditionHelper(normalDistAtMean10) -> pdfImage(range20Float)
+ makeTest("parameter-wise addition of two normal distributions", Sparklines.create(sparklineMean15, ()), `▁▁▁▁▁▁▁▁▁▁▂▃▅▇███▇▅▃▂`)
+})
diff --git a/packages/squiggle-lang/src/rescript/utility/E.res b/packages/squiggle-lang/src/rescript/utility/E.res
index d17850fd..71c4c1e4 100644
--- a/packages/squiggle-lang/src/rescript/utility/E.res
+++ b/packages/squiggle-lang/src/rescript/utility/E.res
@@ -1,5 +1,4 @@
open Rationale.Function.Infix
-
module FloatFloatMap = {
module Id = Belt.Id.MakeComparable({
type t = float
@@ -87,6 +86,11 @@ module O = {
let max = compare(\">")
}
+module O2 = {
+ let default = (a, b) => O.default(b, a)
+ let toExn = (a, b) => O.toExn(b, a)
+}
+
/* Functions */
module F = {
let apply = (a, e) => a |> e
@@ -269,6 +273,8 @@ module A = {
))
|> Rationale.Result.return
}
+ let rangeFloat = (~step=1, start, stop) =>
+ Belt.Array.rangeBy(start, stop, ~step) |> fmap(Belt.Int.toFloat)
// This zips while taking the longest elements of each array.
let zipMaxLength = (array1, array2) => {
@@ -322,7 +328,8 @@ module A = {
| r => Some(r)
}
)
- let filter = (o, e) => Js.Array.filter(o, e)
+ let filter = Js.Array.filter
+ let joinWith = Js.Array.joinWith
module O = {
let concatSomes = (optionals: array