diff --git a/src/EAFunds/EAFunds_Form.bs.js b/src/EAFunds/EAFunds_Form.bs.js index 7b06776a..390f1675 100644 --- a/src/EAFunds/EAFunds_Form.bs.js +++ b/src/EAFunds/EAFunds_Form.bs.js @@ -1,133 +1,8 @@ '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"); -function handleChange(handleChange$1, $$event) { - return Curry._1(handleChange$1, $$event.target.value); -} +var model = EAFunds_Model$ProbExample.Interface.model; -function get(state, field) { - switch (field) { - 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 */ +exports.model = model; +/* EAFunds_Model-ProbExample Not a pure module */ diff --git a/src/EAFunds/EAFunds_Form.re b/src/EAFunds/EAFunds_Form.re index 02750e7d..24e2a994 100644 --- a/src/EAFunds/EAFunds_Form.re +++ b/src/EAFunds/EAFunds_Form.re @@ -1,72 +1 @@ -open EAFunds_Data; - -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 - }; - <> - 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)) - | _ => () - } - )} - /> - - setForm(_ => Form.set(form, Form.Group, r)) - )}> - {EAFunds_Data.funds - |> Array.map(f => - - {f.name |> ReasonReact.string} - - ) - |> ReasonReact.array} - - setProperty(r))}> - - {"Donations" |> ReasonReact.string} - - - {"Payouts" |> ReasonReact.string} - - - {( - switch (foundGroup, foundProperty) { - | (Some(g), Some(f)) => - EAFunds_Model.run(g.group, Form.get(form, Year), f) - | _ => "" - } - ) - |> ReasonReact.string} - ; -}; \ No newline at end of file +let model = EAFunds_Model.Interface.model; \ No newline at end of file diff --git a/src/EAFunds/EAFunds_Form2.re b/src/EAFunds/EAFunds_Form2.re index 6d0f9844..30c3f9ec 100644 --- a/src/EAFunds/EAFunds_Form2.re +++ b/src/EAFunds/EAFunds_Form2.re @@ -34,11 +34,13 @@ let make = () => { {r.name |> ReasonReact.string} - {EAFunds_Model.run(r.group, year, DONATIONS) + {EAFunds_Model.go(r.group, year, DONATIONS) + |> Model.InputTypes.to_string |> ReasonReact.string} - {EAFunds_Model.run(r.group, year, PAYOUTS) + {EAFunds_Model.go(r.group, year, PAYOUTS) + |> Model.InputTypes.to_string |> ReasonReact.string} diff --git a/src/EAFunds/EAFunds_Model.bs.js b/src/EAFunds/EAFunds_Model.bs.js index 248540e2..3dd010eb 100644 --- a/src/EAFunds/EAFunds_Model.bs.js +++ b/src/EAFunds/EAFunds_Model.bs.js @@ -1,8 +1,6 @@ 'use strict'; 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 Model$ProbExample = require("../Model.bs.js"); @@ -67,11 +65,11 @@ var PayoutsIfAround = { currentValue: currentValue }; -function run(group, year, output) { - return calculateDifference(currentValue(group, output), year, /* record */[ - /* meanDiff */1.1, - /* stdDiff */1.1 - ]); +function go(group, year, output) { + return /* FloatCdf */Block.__(3, [calculateDifference(currentValue(group, output), year, /* record */[ + /* meanDiff */1.1, + /* stdDiff */1.1 + ])]); } var model_002 = /* assumptions : :: */[ @@ -102,12 +100,12 @@ var model_003 = /* inputs : :: */[ /* :: */[ /* tuple */[ "Meta Fund", - "metaFund" + "meta" ], /* :: */[ /* tuple */[ - "Total", - "total" + "All", + "all" ], /* [] */0 ] @@ -140,36 +138,71 @@ var model = /* record */[ /* author */"George Harrison", model_002, model_003, - model_004 + model_004, + /* outputConfig : Single */0 ]; -var class_tables = [ - 0, - 0, - 0 -]; - -function run$1(a, i) { - if (!class_tables[0]) { - var $$class = CamlinternalOO.create_table(0); - var env = CamlinternalOO.new_variable($$class, ""); - var env_init = function (env$1) { - var self = CamlinternalOO.create_object_opt(0, $$class); - self[env] = env$1; - return self; - }; - CamlinternalOO.init_class($$class); - class_tables[0] = env_init; +function convertChoice(s) { + switch (s) { + case "animal" : + return /* Fund */[/* ANIMAL_WELFARE */0]; + case "globalHealth" : + return /* Fund */[/* GLOBAL_HEALTH */1]; + case "longTerm" : + return /* Fund */[/* LONG_TERM_FUTURE */2]; + case "meta" : + return /* Fund */[/* META */3]; + default: + return /* All */0; } - 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 = { model: model, - run: run$1 + convertChoice: convertChoice, + run: run }; exports.PayoutsIfAround = PayoutsIfAround; -exports.run = run; +exports.go = go; exports.Interface = Interface; /* model Not a pure module */ diff --git a/src/EAFunds/EAFunds_Model.re b/src/EAFunds/EAFunds_Model.re index 9ee92a4f..02e20b2d 100644 --- a/src/EAFunds/EAFunds_Model.re +++ b/src/EAFunds/EAFunds_Model.re @@ -42,18 +42,21 @@ module PayoutsIfAround = { }; }; -let run = (group: group, year: float, output: output) => { +let go = (group: group, year: float, output: output) => { PayoutsIfAround.( - calculateDifference( - currentValue(group, output), - year, - yearlyMeanGrowthRateIfNotClosed(group), + Model.InputTypes.FloatCdf( + calculateDifference( + currentValue(group, output), + year, + yearlyMeanGrowthRateIfNotClosed(group), + ), ) ); }; module Interface = { open Model; + let model = { name: "Calculate the payments and payouts of EA Funds based on existing data.", author: "George Harrison", @@ -71,8 +74,8 @@ module Interface = { ("Animal Welfare Fund", "animal"), ("Global Health Fund", "globalHealth"), ("Long Term Future Fund", "longTerm"), - ("Meta Fund", "metaFund"), - ("Total", "total"), + ("Meta Fund", "meta"), + ("All", "all"), ], }), (), @@ -92,7 +95,26 @@ module Interface = { Output.make(~name="Payments", ~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 + }; + }; }; \ No newline at end of file diff --git a/src/Model.re b/src/Model.re index 5c8e78ed..498b213e 100644 --- a/src/Model.re +++ b/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 = { type singleChoice = { options: list((string, string)), @@ -50,6 +72,9 @@ module Output = { parameterType, }; + type outputConfig = + | Single; + let make = (~name, ~parameterType, ~id=name, ()) => { id, name, @@ -63,4 +88,33 @@ type model = { assumptions: list(Input.parameter), inputs: list(Input.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), + }; }; \ No newline at end of file