Attempting to continue to flesh out Model
This commit is contained in:
parent
6d94cb3227
commit
949fcd86e6
|
@ -1,133 +1,8 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var $$Array = require("bs-platform/lib/js/array.js");
|
|
||||||
var Curry = require("bs-platform/lib/js/curry.js");
|
|
||||||
var React = require("react");
|
|
||||||
var Antd_Radio = require("bs-ant-design-alt/src/Antd_Radio.js");
|
|
||||||
var Belt_Array = require("bs-platform/lib/js/belt_Array.js");
|
|
||||||
var EAFunds_Data$ProbExample = require("./EAFunds_Data.bs.js");
|
|
||||||
var EAFunds_Model$ProbExample = require("./EAFunds_Model.bs.js");
|
var EAFunds_Model$ProbExample = require("./EAFunds_Model.bs.js");
|
||||||
|
|
||||||
function handleChange(handleChange$1, $$event) {
|
var model = EAFunds_Model$ProbExample.Interface.model;
|
||||||
return Curry._1(handleChange$1, $$event.target.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function get(state, field) {
|
exports.model = model;
|
||||||
switch (field) {
|
/* EAFunds_Model-ProbExample Not a pure module */
|
||||||
case /* Group */0 :
|
|
||||||
return state[/* group */0];
|
|
||||||
case /* Year */1 :
|
|
||||||
return state[/* year */1];
|
|
||||||
case /* Output */2 :
|
|
||||||
return state[/* output */2];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function set(state, field, value) {
|
|
||||||
switch (field) {
|
|
||||||
case /* Group */0 :
|
|
||||||
return /* record */[
|
|
||||||
/* group */value,
|
|
||||||
/* year */state[/* year */1],
|
|
||||||
/* output */state[/* output */2]
|
|
||||||
];
|
|
||||||
case /* Year */1 :
|
|
||||||
return /* record */[
|
|
||||||
/* group */state[/* group */0],
|
|
||||||
/* year */value,
|
|
||||||
/* output */state[/* output */2]
|
|
||||||
];
|
|
||||||
case /* Output */2 :
|
|
||||||
return /* record */[
|
|
||||||
/* group */state[/* group */0],
|
|
||||||
/* year */state[/* year */1],
|
|
||||||
/* output */value
|
|
||||||
];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var Form = {
|
|
||||||
get: get,
|
|
||||||
set: set
|
|
||||||
};
|
|
||||||
|
|
||||||
function EAFunds_Form(Props) {
|
|
||||||
var match = React.useState((function () {
|
|
||||||
return /* record */[
|
|
||||||
/* group */"Animal Welfare Fund",
|
|
||||||
/* year */2021,
|
|
||||||
/* output */"Donations"
|
|
||||||
];
|
|
||||||
}));
|
|
||||||
var setForm = match[1];
|
|
||||||
var form = match[0];
|
|
||||||
var match$1 = React.useState((function () {
|
|
||||||
return "Donations";
|
|
||||||
}));
|
|
||||||
var setProperty = match$1[1];
|
|
||||||
var property = match$1[0];
|
|
||||||
var foundGroup = Belt_Array.getBy(EAFunds_Data$ProbExample.funds, (function (r) {
|
|
||||||
return r[/* name */1] === form[/* group */0];
|
|
||||||
}));
|
|
||||||
var foundProperty;
|
|
||||||
switch (property) {
|
|
||||||
case "Donations" :
|
|
||||||
foundProperty = /* DONATIONS */0;
|
|
||||||
break;
|
|
||||||
case "Payouts" :
|
|
||||||
foundProperty = /* PAYOUTS */1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
foundProperty = undefined;
|
|
||||||
}
|
|
||||||
return React.createElement(React.Fragment, undefined, React.createElement("input", {
|
|
||||||
type: "number",
|
|
||||||
value: form[/* year */1].toString(),
|
|
||||||
onChange: (function (param) {
|
|
||||||
var r = param.target.value;
|
|
||||||
var r$1 = Number(r);
|
|
||||||
if (r$1 >= 2020.0 && r$1 <= 2050.0) {
|
|
||||||
return Curry._1(setForm, (function (param) {
|
|
||||||
return set(form, /* Year */1, r$1);
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
return /* () */0;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}), React.createElement(Antd_Radio.Group.make, {
|
|
||||||
value: form[/* group */0],
|
|
||||||
onChange: (function (param) {
|
|
||||||
var r = param.target.value;
|
|
||||||
return Curry._1(setForm, (function (param) {
|
|
||||||
return set(form, /* Group */0, r);
|
|
||||||
}));
|
|
||||||
}),
|
|
||||||
children: $$Array.map((function (f) {
|
|
||||||
return React.createElement(Antd_Radio.make, {
|
|
||||||
value: f[/* name */1],
|
|
||||||
children: f[/* name */1]
|
|
||||||
});
|
|
||||||
}), EAFunds_Data$ProbExample.funds)
|
|
||||||
}), React.createElement(Antd_Radio.Group.make, {
|
|
||||||
value: property,
|
|
||||||
onChange: (function (param) {
|
|
||||||
return Curry._1(setProperty, param.target.value);
|
|
||||||
}),
|
|
||||||
children: null
|
|
||||||
}, React.createElement(Antd_Radio.make, {
|
|
||||||
value: "Donations",
|
|
||||||
children: "Donations"
|
|
||||||
}), React.createElement(Antd_Radio.make, {
|
|
||||||
value: "Payouts",
|
|
||||||
children: "Payouts"
|
|
||||||
})), foundGroup !== undefined && foundProperty !== undefined ? EAFunds_Model$ProbExample.run(foundGroup[/* group */0], form[/* year */1], foundProperty) : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
var make = EAFunds_Form;
|
|
||||||
|
|
||||||
exports.handleChange = handleChange;
|
|
||||||
exports.Form = Form;
|
|
||||||
exports.make = make;
|
|
||||||
/* react Not a pure module */
|
|
||||||
|
|
|
@ -1,72 +1 @@
|
||||||
open EAFunds_Data;
|
let model = EAFunds_Model.Interface.model;
|
||||||
|
|
||||||
let handleChange = (handleChange, event) =>
|
|
||||||
handleChange(ReactEvent.Form.target(event)##value);
|
|
||||||
|
|
||||||
module Form = [%lenses
|
|
||||||
type state = {
|
|
||||||
group: string,
|
|
||||||
year: float,
|
|
||||||
output: string,
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
[@react.component]
|
|
||||||
let make = () => {
|
|
||||||
let (form, setForm) =
|
|
||||||
React.useState(() =>
|
|
||||||
{Form.group: "Animal Welfare Fund", year: 2021., output: "Donations"}
|
|
||||||
);
|
|
||||||
let (property, setProperty) = React.useState(() => "Donations");
|
|
||||||
let foundGroup =
|
|
||||||
Belt.Array.getBy(EAFunds_Data.funds, r => r.name === form.group);
|
|
||||||
let foundProperty =
|
|
||||||
switch (property) {
|
|
||||||
| "Donations" => Some(DONATIONS)
|
|
||||||
| "Payouts" => Some(PAYOUTS)
|
|
||||||
| _ => None
|
|
||||||
};
|
|
||||||
<>
|
|
||||||
<input
|
|
||||||
type_="number"
|
|
||||||
value={Form.get(form, Year) |> Js.Float.toString}
|
|
||||||
onChange={handleChange(r =>
|
|
||||||
switch (Js.Float.fromString(r)) {
|
|
||||||
| r when r >= 2020.0 && r <= 2050.0 =>
|
|
||||||
setForm(_ => Form.set(form, Form.Year, r))
|
|
||||||
| _ => ()
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Antd.Radio.Group
|
|
||||||
value={Form.get(form, Group)}
|
|
||||||
onChange={handleChange(r =>
|
|
||||||
setForm(_ => Form.set(form, Form.Group, r))
|
|
||||||
)}>
|
|
||||||
{EAFunds_Data.funds
|
|
||||||
|> Array.map(f =>
|
|
||||||
<Antd.Radio value={f.name}>
|
|
||||||
{f.name |> ReasonReact.string}
|
|
||||||
</Antd.Radio>
|
|
||||||
)
|
|
||||||
|> ReasonReact.array}
|
|
||||||
</Antd.Radio.Group>
|
|
||||||
<Antd.Radio.Group
|
|
||||||
value=property onChange={handleChange(r => setProperty(r))}>
|
|
||||||
<Antd.Radio value="Donations">
|
|
||||||
{"Donations" |> ReasonReact.string}
|
|
||||||
</Antd.Radio>
|
|
||||||
<Antd.Radio value="Payouts">
|
|
||||||
{"Payouts" |> ReasonReact.string}
|
|
||||||
</Antd.Radio>
|
|
||||||
</Antd.Radio.Group>
|
|
||||||
{(
|
|
||||||
switch (foundGroup, foundProperty) {
|
|
||||||
| (Some(g), Some(f)) =>
|
|
||||||
EAFunds_Model.run(g.group, Form.get(form, Year), f)
|
|
||||||
| _ => ""
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|> ReasonReact.string}
|
|
||||||
</>;
|
|
||||||
};
|
|
|
@ -34,11 +34,13 @@ let make = () => {
|
||||||
{r.name |> ReasonReact.string}
|
{r.name |> ReasonReact.string}
|
||||||
</th>
|
</th>
|
||||||
<th className="px-4 py-2 border font-normal">
|
<th className="px-4 py-2 border font-normal">
|
||||||
{EAFunds_Model.run(r.group, year, DONATIONS)
|
{EAFunds_Model.go(r.group, year, DONATIONS)
|
||||||
|
|> Model.InputTypes.to_string
|
||||||
|> ReasonReact.string}
|
|> ReasonReact.string}
|
||||||
</th>
|
</th>
|
||||||
<th className="px-4 py-2 border font-normal">
|
<th className="px-4 py-2 border font-normal">
|
||||||
{EAFunds_Model.run(r.group, year, PAYOUTS)
|
{EAFunds_Model.go(r.group, year, PAYOUTS)
|
||||||
|
|> Model.InputTypes.to_string
|
||||||
|> ReasonReact.string}
|
|> ReasonReact.string}
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var Block = require("bs-platform/lib/js/block.js");
|
var Block = require("bs-platform/lib/js/block.js");
|
||||||
var Curry = require("bs-platform/lib/js/curry.js");
|
|
||||||
var CamlinternalOO = require("bs-platform/lib/js/camlinternalOO.js");
|
|
||||||
var Math$ProbExample = require("../Math.bs.js");
|
var Math$ProbExample = require("../Math.bs.js");
|
||||||
var Model$ProbExample = require("../Model.bs.js");
|
var Model$ProbExample = require("../Model.bs.js");
|
||||||
|
|
||||||
|
@ -67,11 +65,11 @@ var PayoutsIfAround = {
|
||||||
currentValue: currentValue
|
currentValue: currentValue
|
||||||
};
|
};
|
||||||
|
|
||||||
function run(group, year, output) {
|
function go(group, year, output) {
|
||||||
return calculateDifference(currentValue(group, output), year, /* record */[
|
return /* FloatCdf */Block.__(3, [calculateDifference(currentValue(group, output), year, /* record */[
|
||||||
/* meanDiff */1.1,
|
/* meanDiff */1.1,
|
||||||
/* stdDiff */1.1
|
/* stdDiff */1.1
|
||||||
]);
|
])]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var model_002 = /* assumptions : :: */[
|
var model_002 = /* assumptions : :: */[
|
||||||
|
@ -102,12 +100,12 @@ var model_003 = /* inputs : :: */[
|
||||||
/* :: */[
|
/* :: */[
|
||||||
/* tuple */[
|
/* tuple */[
|
||||||
"Meta Fund",
|
"Meta Fund",
|
||||||
"metaFund"
|
"meta"
|
||||||
],
|
],
|
||||||
/* :: */[
|
/* :: */[
|
||||||
/* tuple */[
|
/* tuple */[
|
||||||
"Total",
|
"All",
|
||||||
"total"
|
"all"
|
||||||
],
|
],
|
||||||
/* [] */0
|
/* [] */0
|
||||||
]
|
]
|
||||||
|
@ -140,36 +138,71 @@ var model = /* record */[
|
||||||
/* author */"George Harrison",
|
/* author */"George Harrison",
|
||||||
model_002,
|
model_002,
|
||||||
model_003,
|
model_003,
|
||||||
model_004
|
model_004,
|
||||||
|
/* outputConfig : Single */0
|
||||||
];
|
];
|
||||||
|
|
||||||
var class_tables = [
|
function convertChoice(s) {
|
||||||
0,
|
switch (s) {
|
||||||
0,
|
case "animal" :
|
||||||
0
|
return /* Fund */[/* ANIMAL_WELFARE */0];
|
||||||
];
|
case "globalHealth" :
|
||||||
|
return /* Fund */[/* GLOBAL_HEALTH */1];
|
||||||
function run$1(a, i) {
|
case "longTerm" :
|
||||||
if (!class_tables[0]) {
|
return /* Fund */[/* LONG_TERM_FUTURE */2];
|
||||||
var $$class = CamlinternalOO.create_table(0);
|
case "meta" :
|
||||||
var env = CamlinternalOO.new_variable($$class, "");
|
return /* Fund */[/* META */3];
|
||||||
var env_init = function (env$1) {
|
default:
|
||||||
var self = CamlinternalOO.create_object_opt(0, $$class);
|
return /* All */0;
|
||||||
self[env] = env$1;
|
|
||||||
return self;
|
|
||||||
};
|
|
||||||
CamlinternalOO.init_class($$class);
|
|
||||||
class_tables[0] = env_init;
|
|
||||||
}
|
}
|
||||||
return Curry._1(class_tables[0], 0);
|
}
|
||||||
|
|
||||||
|
function run(p) {
|
||||||
|
var match = p[/* assumptions */0];
|
||||||
|
var match$1 = p[/* inputs */1];
|
||||||
|
if (match) {
|
||||||
|
var match$2 = match[0];
|
||||||
|
if (match$2 !== undefined) {
|
||||||
|
var match$3 = match$2;
|
||||||
|
if (match$3.tag) {
|
||||||
|
return ;
|
||||||
|
} else {
|
||||||
|
var match$4 = match[1];
|
||||||
|
if (match$4) {
|
||||||
|
var match$5 = match$4[0];
|
||||||
|
if (match$5 !== undefined && !(match$5.tag || match$4[1] || !match$1)) {
|
||||||
|
var match$6 = match$1[0];
|
||||||
|
if (match$6 !== undefined) {
|
||||||
|
var match$7 = match$6;
|
||||||
|
if (match$7.tag === /* SingleChoice */1 && !match$1[1]) {
|
||||||
|
return go(convertChoice(match$7[0]), match$3[0], /* DONATIONS */0);
|
||||||
|
} else {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var Interface = {
|
var Interface = {
|
||||||
model: model,
|
model: model,
|
||||||
run: run$1
|
convertChoice: convertChoice,
|
||||||
|
run: run
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.PayoutsIfAround = PayoutsIfAround;
|
exports.PayoutsIfAround = PayoutsIfAround;
|
||||||
exports.run = run;
|
exports.go = go;
|
||||||
exports.Interface = Interface;
|
exports.Interface = Interface;
|
||||||
/* model Not a pure module */
|
/* model Not a pure module */
|
||||||
|
|
|
@ -42,18 +42,21 @@ module PayoutsIfAround = {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
let run = (group: group, year: float, output: output) => {
|
let go = (group: group, year: float, output: output) => {
|
||||||
PayoutsIfAround.(
|
PayoutsIfAround.(
|
||||||
|
Model.InputTypes.FloatCdf(
|
||||||
calculateDifference(
|
calculateDifference(
|
||||||
currentValue(group, output),
|
currentValue(group, output),
|
||||||
year,
|
year,
|
||||||
yearlyMeanGrowthRateIfNotClosed(group),
|
yearlyMeanGrowthRateIfNotClosed(group),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
module Interface = {
|
module Interface = {
|
||||||
open Model;
|
open Model;
|
||||||
|
|
||||||
let model = {
|
let model = {
|
||||||
name: "Calculate the payments and payouts of EA Funds based on existing data.",
|
name: "Calculate the payments and payouts of EA Funds based on existing data.",
|
||||||
author: "George Harrison",
|
author: "George Harrison",
|
||||||
|
@ -71,8 +74,8 @@ module Interface = {
|
||||||
("Animal Welfare Fund", "animal"),
|
("Animal Welfare Fund", "animal"),
|
||||||
("Global Health Fund", "globalHealth"),
|
("Global Health Fund", "globalHealth"),
|
||||||
("Long Term Future Fund", "longTerm"),
|
("Long Term Future Fund", "longTerm"),
|
||||||
("Meta Fund", "metaFund"),
|
("Meta Fund", "meta"),
|
||||||
("Total", "total"),
|
("All", "all"),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
(),
|
(),
|
||||||
|
@ -92,7 +95,26 @@ module Interface = {
|
||||||
Output.make(~name="Payments", ~parameterType=FloatCdf, ()),
|
Output.make(~name="Payments", ~parameterType=FloatCdf, ()),
|
||||||
Output.make(~name="Payouts", ~parameterType=FloatCdf, ()),
|
Output.make(~name="Payouts", ~parameterType=FloatCdf, ()),
|
||||||
],
|
],
|
||||||
|
outputConfig: Single,
|
||||||
};
|
};
|
||||||
|
|
||||||
let run = (a, i) => {};
|
let convertChoice = (s: string) =>
|
||||||
|
switch (s) {
|
||||||
|
| "animal" => Fund(ANIMAL_WELFARE)
|
||||||
|
| "globalHealth" => Fund(GLOBAL_HEALTH)
|
||||||
|
| "longTerm" => Fund(LONG_TERM_FUTURE)
|
||||||
|
| "meta" => Fund(META)
|
||||||
|
| _ => All
|
||||||
|
};
|
||||||
|
|
||||||
|
let run = (p: Model.modelParams) => {
|
||||||
|
switch (p.assumptions, p.inputs) {
|
||||||
|
| (
|
||||||
|
[Some(Year(intendedYear)), Some(Year(currentYear))],
|
||||||
|
[Some(SingleChoice(fund))],
|
||||||
|
) =>
|
||||||
|
Some(go(convertChoice(fund), intendedYear, DONATIONS))
|
||||||
|
| _ => None
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
54
src/Model.re
54
src/Model.re
|
@ -1,3 +1,25 @@
|
||||||
|
module InputTypes = {
|
||||||
|
type t =
|
||||||
|
| Year(float)
|
||||||
|
| SingleChoice(string)
|
||||||
|
| FloatPoint(float)
|
||||||
|
| FloatCdf(string);
|
||||||
|
|
||||||
|
type withName = (string, t);
|
||||||
|
let withoutName = ((_, t): withName) => t;
|
||||||
|
type withNames = list(withName);
|
||||||
|
let getName = (r: withNames, name) =>
|
||||||
|
r->Belt.List.getBy(((n, _)) => n == name);
|
||||||
|
let to_string = (t: t) => {
|
||||||
|
switch (t) {
|
||||||
|
| SingleChoice(r) => r
|
||||||
|
| FloatCdf(r) => r
|
||||||
|
| Year(r) => r |> Js.Float.toFixed
|
||||||
|
| FloatPoint(r) => r |> Js.Float.toFixed
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
module IOTypes = {
|
module IOTypes = {
|
||||||
type singleChoice = {
|
type singleChoice = {
|
||||||
options: list((string, string)),
|
options: list((string, string)),
|
||||||
|
@ -50,6 +72,9 @@ module Output = {
|
||||||
parameterType,
|
parameterType,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type outputConfig =
|
||||||
|
| Single;
|
||||||
|
|
||||||
let make = (~name, ~parameterType, ~id=name, ()) => {
|
let make = (~name, ~parameterType, ~id=name, ()) => {
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
|
@ -63,4 +88,33 @@ type model = {
|
||||||
assumptions: list(Input.parameter),
|
assumptions: list(Input.parameter),
|
||||||
inputs: list(Input.parameter),
|
inputs: list(Input.parameter),
|
||||||
outputs: list(Output.parameter),
|
outputs: list(Output.parameter),
|
||||||
|
outputConfig: Output.outputConfig,
|
||||||
|
};
|
||||||
|
|
||||||
|
let gatherInputs = (m: model, a: list(InputTypes.withName)) => {
|
||||||
|
let getItem = (p: Input.parameter) => InputTypes.getName(a, p.id);
|
||||||
|
[
|
||||||
|
m.assumptions |> List.map(getItem),
|
||||||
|
m.inputs |> List.map(getItem),
|
||||||
|
[InputTypes.getName(a, "output")],
|
||||||
|
]
|
||||||
|
|> List.flatten;
|
||||||
|
};
|
||||||
|
|
||||||
|
type modelParams = {
|
||||||
|
assumptions: list(option(InputTypes.t)),
|
||||||
|
inputs: list(option(InputTypes.t)),
|
||||||
|
output: option(InputTypes.t),
|
||||||
|
};
|
||||||
|
|
||||||
|
let response = (m: model, a: list(InputTypes.withName)) => {
|
||||||
|
let getItem = (p: Input.parameter) =>
|
||||||
|
InputTypes.getName(a, p.id)->Belt.Option.map(InputTypes.withoutName);
|
||||||
|
{
|
||||||
|
assumptions: m.assumptions |> List.map(getItem),
|
||||||
|
inputs: m.inputs |> List.map(getItem),
|
||||||
|
output:
|
||||||
|
InputTypes.getName(a, "output")
|
||||||
|
->Belt.Option.map(InputTypes.withoutName),
|
||||||
|
};
|
||||||
};
|
};
|
Loading…
Reference in New Issue
Block a user