Simple FunctionRegistry cleanup

This commit is contained in:
Ozzie Gooen 2022-05-21 11:41:12 -04:00
parent 7e2437bfc0
commit 40bf7443c9
4 changed files with 62 additions and 49 deletions

View File

@ -56,8 +56,8 @@ module FRType = {
| FRTypeOption(v) => `option(${toString(v)})`
}
let rec matchWithExpressionValue = (input: t, r: expressionValue): option<frValue> =>
switch (input, r) {
let rec matchWithExpressionValue = (t: t, r: expressionValue): option<frValue> =>
switch (t, r) {
| (FRTypeNumber, EvNumber(f)) => Some(FRValueNumber(f))
| (FRTypeDistOrNumber, EvNumber(f)) => Some(FRValueDistOrNumber(FRValueNumber(f)))
| (FRTypeDistOrNumber, EvDistribution(Symbolic(#Float(f)))) =>
@ -94,6 +94,11 @@ module FRType = {
}
}
/*
This module, Matcher, is fairly lengthy. However, only two functions from it
are meant to be used outside of it. These are findMatches and matchToDef in Matches.Registry.
The rest of it is just called from those two functions.
*/
module Matcher = {
module MatchSimple = {
type t = DifferentName | SameNameDifferentArguments | FullMatch
@ -185,21 +190,18 @@ module Matcher = {
}
module Registry = {
let findExactMatches = (r: registry, fnName: string, args: array<expressionValue>) => {
let _findExactMatches = (r: registry, fnName: string, args: array<expressionValue>) => {
let functionMatchPairs = r->E.A2.fmap(l => (l, Function.match(l, fnName, args)))
let getFullMatch = E.A.getBy(functionMatchPairs, ((_, match: Function.match)) =>
Match.isFullMatch(match)
)
let fullMatch: option<RegistryMatch.match> = getFullMatch->E.O.bind(((fn, match)) =>
let fullMatch = functionMatchPairs->E.A.getBy(((_, match)) => Match.isFullMatch(match))
fullMatch->E.O.bind(((fn, match)) =>
switch match {
| FullMatch(index) => Some(RegistryMatch.makeMatch(fn.name, index))
| _ => None
}
)
fullMatch
}
let findNameMatches = (r: registry, fnName: string, args: array<expressionValue>) => {
let _findNameMatches = (r: registry, fnName: string, args: array<expressionValue>) => {
let functionMatchPairs = r->E.A2.fmap(l => (l, Function.match(l, fnName, args)))
let getNameMatches =
functionMatchPairs
@ -219,10 +221,10 @@ module Matcher = {
}
let findMatches = (r: registry, fnName: string, args: array<expressionValue>) => {
switch findExactMatches(r, fnName, args) {
switch _findExactMatches(r, fnName, args) {
| Some(r) => Match.FullMatch(r)
| None =>
switch findNameMatches(r, fnName, args) {
switch _findNameMatches(r, fnName, args) {
| Some(r) => Match.SameNameDifferentArguments(r)
| None => Match.DifferentName
}
@ -241,7 +243,10 @@ module Matcher = {
module FnDefinition = {
type t = fnDefinition
let defToString = (t: t) => t.inputs->E.A2.fmap(FRType.toString)->E.A2.joinWith(", ")
let toString = (t: t) => {
let inputs = t.inputs->E.A2.fmap(FRType.toString)->E.A2.joinWith(", ")
t.name ++ `(${inputs})`
}
let run = (t: t, args: array<expressionValue>) => {
let argValues = FRType.matchWithExpressionValueArray(t.inputs, args)
@ -251,7 +256,7 @@ module FnDefinition = {
}
}
let make = (~name, ~inputs, ~run): fnDefinition => {
let make = (~name, ~inputs, ~run): t => {
name: name,
inputs: inputs,
run: run,
@ -259,7 +264,9 @@ module FnDefinition = {
}
module Function = {
let make = (~name, ~definitions): function => {
type t = function
let make = (~name, ~definitions): t => {
name: name,
definitions: definitions,
}
@ -278,7 +285,8 @@ module Registry = {
matches
->E.A2.fmap(matchToDef)
->E.A.O.concatSomes
->E.A2.fmap(r => `[${fnName}(${FnDefinition.defToString(r)})]`)
->E.A2.fmap(FnDefinition.toString)
->E.A2.fmap(r => `[${r}]`)
->E.A2.joinWith("; ")
`There are function matches for ${fnName}(), but with different arguments: ${defs}`
}

View File

@ -9,44 +9,43 @@ module Wrappers = {
}
module Prepare = {
let recordWithTwoArgsToValues = (inputs: array<frValue>): result<array<frValue>, string> =>
type ts = array<frValue>
type err = string
module ToValueArray = {
module Record = {
let twoArgs = (inputs: ts): result<ts, err> =>
switch inputs {
| [FRValueRecord([(_, n1), (_, n2)])] => Ok([n1, n2])
| _ => Error(impossibleError)
}
let twoNumberInputs = (inputs: array<frValue>): result<(float, float), string> => {
switch inputs {
| [FRValueNumber(n1), FRValueNumber(n2)] => Ok(n1, n2)
| _ => Error(impossibleError)
}
}
let twoDistOrNumber = (values: array<frValue>): result<
(frValueDistOrNumber, frValueDistOrNumber),
string,
> => {
module ToValueTuple = {
let twoDistOrNumber = (values: ts): result<(frValueDistOrNumber, frValueDistOrNumber), err> => {
switch values {
| [FRValueDistOrNumber(a1), FRValueDistOrNumber(a2)] => Ok(a1, a2)
| _ => Error(impossibleError)
}
}
let twoDistOrNumberFromRecord = (values: array<frValue>) =>
values->recordWithTwoArgsToValues->E.R.bind(twoDistOrNumber)
module Record = {
let twoDistOrNumber = (values: ts): result<(frValueDistOrNumber, frValueDistOrNumber), err> =>
values->ToValueArray.Record.twoArgs->E.R.bind(twoDistOrNumber)
}
}
}
module Process = {
let twoDistsOrNumbersToDist = (
~fn: ((float, float)) => result<DistributionTypes.genericDist, string>,
~values: (frValueDistOrNumber, frValueDistOrNumber),
) => {
): result<DistributionTypes.genericDist, string> => {
let toSampleSet = r => GenericDist.toSampleSetDist(r, 1000)
let sampleSetToExpressionValue = (
b: Belt.Result.t<QuriSquiggleLang.SampleSetDist.t, QuriSquiggleLang.DistributionTypes.error>,
) =>
let sampleSetToExpressionValue = (b: Belt.Result.t<SampleSetDist.t, DistributionTypes.error>) =>
switch b {
| Ok(r) => Ok(ReducerInterface_ExpressionValue.EvDistribution(SampleSet(r)))
| Ok(r) => Ok(DistributionTypes.SampleSet(r))
| Error(d) => Error(DistributionTypes.Error.toString(d))
}
@ -56,9 +55,11 @@ module Process = {
| Error(r) => Error(Operation.Other(r))
}
let singleVarSample = (a, fn) => {
let singleVarSample = (dist, fn) => {
let sampleSetResult =
toSampleSet(a) |> E.R2.bind(dist =>
dist
->toSampleSet
->E.R.bind(dist =>
SampleSetDist.samplesMap(
~fn=f => fn(f)->mapFnResult,
dist,
@ -68,7 +69,7 @@ module Process = {
}
switch values {
| (FRValueNumber(a1), FRValueNumber(a2)) => fn((a1, a2))->E.R2.fmap(Wrappers.evDistribution)
| (FRValueNumber(a1), FRValueNumber(a2)) => fn((a1, a2))
| (FRValueDist(a1), FRValueNumber(a2)) => singleVarSample(a1, r => fn((r, a2)))
| (FRValueNumber(a1), FRValueDist(a2)) => singleVarSample(a2, r => fn((a1, r)))
| (FRValueDist(a1), FRValueDist(a2)) => {
@ -89,17 +90,20 @@ module Process = {
~fn: ((float, float)) => result<SymbolicDistTypes.symbolicDist, string>,
~values,
) => {
twoDistsOrNumbersToDist(~fn=r => r->fn->E.R2.fmap(Wrappers.symbolic), ~values)
let newFn = r => fn(r)->E.R2.fmap(Wrappers.symbolic)
twoDistsOrNumbersToDist(~fn=newFn, ~values)
}
}
module TwoArgDist = {
let process = (~fn, r) =>
r->E.R.bind(Process.twoDistsOrNumbersToDistUsingSymbolicDist(~fn, ~values=_))
r
->E.R.bind(Process.twoDistsOrNumbersToDistUsingSymbolicDist(~fn, ~values=_))
->E.R2.fmap(Wrappers.evDistribution)
let mkRegular = (name, fn) => {
FnDefinition.make(~name, ~inputs=[FRTypeDistOrNumber, FRTypeDistOrNumber], ~run=inputs =>
inputs->Prepare.twoDistOrNumber->process(~fn)
inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn)
)
}
@ -107,7 +111,7 @@ module TwoArgDist = {
FnDefinition.make(
~name,
~inputs=[FRTypeRecord([("p5", FRTypeDistOrNumber), ("p95", FRTypeDistOrNumber)])],
~run=inputs => inputs->Prepare.twoDistOrNumberFromRecord->process(~fn),
~run=inputs => inputs->Prepare.ToValueTuple.Record.twoDistOrNumber->process(~fn),
)
}
@ -115,7 +119,7 @@ module TwoArgDist = {
FnDefinition.make(
~name,
~inputs=[FRTypeRecord([("mean", FRTypeDistOrNumber), ("stdev", FRTypeDistOrNumber)])],
~run=inputs => inputs->Prepare.twoDistOrNumberFromRecord->process(~fn),
~run=inputs => inputs->Prepare.ToValueTuple.Record.twoDistOrNumber->process(~fn),
)
}
}

View File

@ -1,7 +1,7 @@
open FunctionRegistry_Core
open FunctionRegistry_Helpers
let twoArgs = (fn, (a1, a2)) => fn(a1, a2)
let twoArgs = E.Tuple2.toFnCall
module NormalFn = {
let fnName = "normal"
@ -56,4 +56,4 @@ let more = [
),
]
let allFunctions = [NormalFn.toFn, LognormalFn.toFn]
let allFunctions = E.A.append([NormalFn.toFn, LognormalFn.toFn], more)

View File

@ -52,6 +52,7 @@ module Tuple2 = {
let (_, b) = v
b
}
let toFnCall = (fn, (a1, a2)) => fn(a1, a2)
}
module O = {