squiggle/src/symbolic/MathJsParser.re

58 lines
1.4 KiB
ReasonML
Raw Normal View History

open Jstat;
type arg =
| Value(float)
| Fn(fn)
and fn = {
name: string,
args: array(arg),
};
let rec parseMathjs = (j: Js.Json.t) => {
Json.Decode.(
switch (field("mathjs", string, j)) {
| "FunctionNode" =>
let args = j |> field("args", array(parseMathjs));
Some(
Fn({
name: j |> field("fn", field("name", string)),
args: args |> E.A.O.concatSomes,
}),
);
| "ConstantNode" => Some(Value(field("value", float, j)))
| _ => None
}
);
};
let normal = (r): result(bigDist, string) =>
r
|> (
fun
| [|Value(mean), Value(stdev)|] => Ok(`Dist(`Normal({mean, stdev})))
| _ => Error("Wrong number of variables in normal distribution")
);
let rec toValue = (r): result(bigDist, string) =>
r
|> (
fun
| Value(_) => Error("Top level can't be value")
| Fn({name: "normal", args}) => normal(args)
| Fn({name: "mm", args}) => {
let dists: array(dist) =
args
|> E.A.fmap(toValue)
|> E.A.fmap(
fun
| Ok(`Dist(`Normal({mean, stdev}))) =>
Some(`Normal({mean, stdev}))
| _ => None,
)
|> E.A.O.concatSomes;
let inputs = dists |> E.A.fmap(r => (r, 1.0));
Ok(`PointwiseCombination(inputs));
}
| Fn({name}) => Error(name ++ ": name not found")
);