open FunctionRegistry_Core open FunctionRegistry_Helpers let nameSpace = "Danger" let requiresNamespace = true module NumberToNumber = { let make = (name, fn) => FnDefinition.make( ~name, ~inputs=[FRTypeNumber], ~run=(_, inputs, _, _) => { inputs ->getOrError(0) ->E.R.bind(Prepare.oneNumber) ->E.R2.fmap(fn) ->E.R2.fmap(Wrappers.evNumber) }, (), ) } module TwoNumbersToNumber = { let make = (name, fn) => FnDefinition.make( ~name, ~inputs=[FRTypeNumber, FRTypeNumber], ~run=(_, inputs, _, _) => { inputs->Prepare.ToValueTuple.twoNumbers->E.R2.fmap(fn)->E.R2.fmap(Wrappers.evNumber) }, (), ) } module ThreeNumbersToNumber = { let make = (name, fn) => FnDefinition.make( ~name, ~inputs=[FRTypeNumber, FRTypeNumber, FRTypeNumber], ~run=(_, inputs, _, _) => { inputs->Prepare.ToValueTuple.threeNumbers->E.R2.fmap(fn)->E.R2.fmap(Wrappers.evNumber) }, (), ) } module FunctionToNumberZero = { let make = (name, fn) => FnDefinition.make( ~name, ~inputs=[FRTypeLambda], ~run=(_, inputs, _, _) => { Ok(0.0)->E.R2.fmap(Wrappers.evNumber) }, (), ) } module Internals = { let factorial = Stdlib.Math.factorial let choose = ((n, k)) => factorial(n) /. (factorial(n -. k) *. factorial(k)) let pow = (base, exp) => Js.Math.pow_float(~base, ~exp) let binomial = ((n, k, p)) => choose((n, k)) *. pow(p, k) *. pow(1.0 -. p, n -. k) let applyFunctionAtPoint = (aLambda, internalNumber: internalExpressionValue, environment , reducer): result< ReducerInterface_InternalExpressionValue.t, Reducer_ErrorValue.errorValue, > => { let x = internalNumber let result = Reducer_Expression_Lambda.doLambdaCall( aLambda, list{x}, environment, reducer, ) result } } let library = [ Function.make( ~name="laplace", ~nameSpace, ~requiresNamespace, ~output=EvtNumber, ~examples=[`Danger.laplace(1, 20)`], ~definitions=[ TwoNumbersToNumber.make("laplace", ((successes, trials)) => (successes +. 1.0) /. (trials +. 2.0) ), ], (), ), Function.make( ~name="factorial", ~nameSpace, ~requiresNamespace, ~output=EvtNumber, ~examples=[`Danger.factorial(20)`], ~definitions=[NumberToNumber.make("factorial", Internals.factorial)], (), ), Function.make( ~name="choose", ~nameSpace, ~requiresNamespace, ~output=EvtNumber, ~examples=[`Danger.choose(1, 20)`], ~definitions=[TwoNumbersToNumber.make("choose", Internals.choose)], (), ), Function.make( ~name="binomial", ~nameSpace, ~requiresNamespace, ~output=EvtNumber, ~examples=[`Danger.binomial(1, 20, 0.5)`], ~definitions=[ThreeNumbersToNumber.make("binomial", Internals.binomial)], (), ), Function.make( ~name="functionToZero", ~nameSpace, ~requiresNamespace, ~output=EvtNumber, ~examples=[`Danger.functionToZero({|x| x})`], ~definitions=[FunctionToNumberZero.make("functionToZero", x => x)], (), ), Function.make( ~name="applyFunctionAtPoint", ~nameSpace, ~output=EvtArray, ~requiresNamespace=false, ~examples=[`Danger.applyFunctionAtPoint({|x| x+1}, 1)`], ~definitions=[ FnDefinition.make( ~name="applyFunctionAtPoint", ~inputs=[FRTypeLambda, FRTypeNumber], ~run=(inputs, _, env, reducer) => switch inputs { | [IEvLambda(aLambda), point] => Internals.applyFunctionAtPoint(aLambda, point, env, reducer)->E.R2.errMap(_ => "Error!") | _ => Error(impossibleError) }, (), ), ], (), ), ]