Reorganized Output module in GenericOperation

This commit is contained in:
Ozzie Gooen 2022-03-31 13:26:29 -04:00
parent d82615cef0
commit 4702cf3e5e
4 changed files with 79 additions and 67 deletions

View File

@ -12,9 +12,10 @@ let normalDist20: GenericDist_Types.genericDist = #Symbolic(#Normal({mean: 20.0,
let uniformDist: GenericDist_Types.genericDist = #Symbolic(#Uniform({low: 9.0, high: 10.0})) let uniformDist: GenericDist_Types.genericDist = #Symbolic(#Uniform({low: 9.0, high: 10.0}))
let {toFloat, toDist, toString, toError} = module(GenericDist_GenericOperation.Output) let {toFloat, toDist, toString, toError} = module(GenericDist_GenericOperation.Output)
let {run, outputMap} = module(GenericDist_GenericOperation) let {run} = module(GenericDist_GenericOperation)
let {fmap} = module(GenericDist_GenericOperation.Output)
let run = run(params) let run = run(params)
let outputMap = outputMap(params) let outputMap = fmap(params)
let toExt: option<'a> => 'a = E.O.toExt( let toExt: option<'a> => 'a = E.O.toExt(
"Should be impossible to reach (This error is in test file)", "Should be impossible to reach (This error is in test file)",
) )

View File

@ -9,57 +9,59 @@ type params = {
xyPointLength: int, xyPointLength: int,
} }
type outputType = type outputType =
| Dist(GenericDist_Types.genericDist) | Dist(GenericDist_Types.genericDist)
| Float(float) | Float(float)
| String(string) | String(string)
| GenDistError(GenericDist_Types.error) | GenDistError(GenericDist_Types.error)
module Output = { /*
let toDist = (o: outputType) => We're going to add another function to this module later, so first define a
switch o { local version, which is not exported.
*/
module OutputLocal = {
type t = outputType
let toError = (t: outputType) =>
switch t {
| GenDistError(d) => Some(d)
| _ => None
}
let toErrorOrUnreachable = (t: t): error => t->toError->E.O2.default((Unreachable: error))
let toDistR = (t: t): result<genericDist, error> =>
switch t {
| Dist(r) => Ok(r)
| e => Error(toErrorOrUnreachable(e))
}
let toDist = (t: t) =>
switch t {
| Dist(d) => Some(d) | Dist(d) => Some(d)
| _ => None | _ => None
} }
let toFloat = (o: outputType) => let toFloat = (t: t) =>
switch o { switch t {
| Float(d) => Some(d) | Float(d) => Some(d)
| _ => None | _ => None
} }
let toString = (o: outputType) => let toString = (t: t) =>
switch o { switch t {
| String(d) => Some(d) | String(d) => Some(d)
| _ => None | _ => None
} }
let toError = (o: outputType) => //This is used to catch errors in other switch statements.
switch o { let fromResult = (r: result<t, error>): outputType =>
| GenDistError(d) => Some(d) switch r {
| _ => None | Ok(t) => t
| Error(e) => GenDistError(e)
} }
} }
let fromResult = (r: result<outputType, error>): outputType =>
switch r {
| Ok(o) => o
| Error(e) => GenDistError(e)
}
//This is used to catch errors in other switch statements.
let _errorMap = (o: outputType): error =>
switch o {
| GenDistError(r) => r
| _ => Unreachable
}
let outputToDistResult = (o: outputType): result<genericDist, error> =>
switch o {
| Dist(r) => Ok(r)
| r => Error(_errorMap(r))
}
let rec run = (extra, fnName: operation): outputType => { let rec run = (extra, fnName: operation): outputType => {
let {sampleCount, xyPointLength} = extra let {sampleCount, xyPointLength} = extra
@ -70,14 +72,14 @@ let rec run = (extra, fnName: operation): outputType => {
let toPointSetFn = r => { let toPointSetFn = r => {
switch reCall(~fnName=#fromDist(#toDist(#toPointSet), r), ()) { switch reCall(~fnName=#fromDist(#toDist(#toPointSet), r), ()) {
| Dist(#PointSet(p)) => Ok(p) | Dist(#PointSet(p)) => Ok(p)
| r => Error(_errorMap(r)) | e => Error(OutputLocal.toErrorOrUnreachable(e))
} }
} }
let toSampleSetFn = r => { let toSampleSetFn = r => {
switch reCall(~fnName=#fromDist(#toDist(#toSampleSet(sampleCount)), r), ()) { switch reCall(~fnName=#fromDist(#toDist(#toSampleSet(sampleCount)), r), ()) {
| Dist(#SampleSet(p)) => Ok(p) | Dist(#SampleSet(p)) => Ok(p)
| r => Error(_errorMap(r)) | e => Error(OutputLocal.toErrorOrUnreachable(e))
} }
} }
@ -85,20 +87,20 @@ let rec run = (extra, fnName: operation): outputType => {
reCall( reCall(
~fnName=#fromDist(#toDistCombination(#Pointwise, #Multiply, #Float(weight)), r), ~fnName=#fromDist(#toDistCombination(#Pointwise, #Multiply, #Float(weight)), r),
(), (),
)->outputToDistResult )->OutputLocal.toDistR
let pointwiseAdd = (r1, r2) => let pointwiseAdd = (r1, r2) =>
reCall( reCall(
~fnName=#fromDist(#toDistCombination(#Pointwise, #Add, #Dist(r2)), r1), ~fnName=#fromDist(#toDistCombination(#Pointwise, #Add, #Dist(r2)), r1),
(), (),
)->outputToDistResult )->OutputLocal.toDistR
let fromDistFn = (subFnName: GenericDist_Types.Operation.fromDist, dist: genericDist) => let fromDistFn = (subFnName: GenericDist_Types.Operation.fromDist, dist: genericDist) =>
switch subFnName { switch subFnName {
| #toFloat(fnName) => | #toFloat(fnName) =>
GenericDist.operationToFloat(dist, ~toPointSetFn, ~operation=fnName) GenericDist.operationToFloat(dist, ~toPointSetFn, ~operation=fnName)
->E.R2.fmap(r => Float(r)) ->E.R2.fmap(r => Float(r))
->fromResult ->OutputLocal.fromResult
| #toString => dist->GenericDist.toString->String | #toString => dist->GenericDist.toString->String
| #toDist(#inspect) => { | #toDist(#inspect) => {
Js.log2("Console log requested: ", dist) Js.log2("Console log requested: ", dist)
@ -108,27 +110,30 @@ let rec run = (extra, fnName: operation): outputType => {
| #toDist(#truncate(leftCutoff, rightCutoff)) => | #toDist(#truncate(leftCutoff, rightCutoff)) =>
GenericDist.truncate(~toPointSetFn, ~leftCutoff, ~rightCutoff, dist, ()) GenericDist.truncate(~toPointSetFn, ~leftCutoff, ~rightCutoff, dist, ())
->E.R2.fmap(r => Dist(r)) ->E.R2.fmap(r => Dist(r))
->fromResult ->OutputLocal.fromResult
| #toDist(#toPointSet) => | #toDist(#toPointSet) =>
dist->GenericDist.toPointSet(xyPointLength)->E.R2.fmap(r => Dist(#PointSet(r)))->fromResult dist
->GenericDist.toPointSet(xyPointLength)
->E.R2.fmap(r => Dist(#PointSet(r)))
->OutputLocal.fromResult
| #toDist(#toSampleSet(n)) => | #toDist(#toSampleSet(n)) =>
dist->GenericDist.sampleN(n)->E.R2.fmap(r => Dist(#SampleSet(r)))->fromResult dist->GenericDist.sampleN(n)->E.R2.fmap(r => Dist(#SampleSet(r)))->OutputLocal.fromResult
| #toDistCombination(#Algebraic, _, #Float(_)) => GenDistError(NotYetImplemented) | #toDistCombination(#Algebraic, _, #Float(_)) => GenDistError(NotYetImplemented)
| #toDistCombination(#Algebraic, operation, #Dist(t2)) => | #toDistCombination(#Algebraic, operation, #Dist(t2)) =>
dist dist
->GenericDist.algebraicCombination(~toPointSetFn, ~toSampleSetFn, ~operation, ~t2) ->GenericDist.algebraicCombination(~toPointSetFn, ~toSampleSetFn, ~operation, ~t2)
->E.R2.fmap(r => Dist(r)) ->E.R2.fmap(r => Dist(r))
->fromResult ->OutputLocal.fromResult
| #toDistCombination(#Pointwise, operation, #Dist(t2)) => | #toDistCombination(#Pointwise, operation, #Dist(t2)) =>
dist dist
->GenericDist.pointwiseCombination(~toPointSetFn, ~operation, ~t2) ->GenericDist.pointwiseCombination(~toPointSetFn, ~operation, ~t2)
->E.R2.fmap(r => Dist(r)) ->E.R2.fmap(r => Dist(r))
->fromResult ->OutputLocal.fromResult
| #toDistCombination(#Pointwise, operation, #Float(float)) => | #toDistCombination(#Pointwise, operation, #Float(float)) =>
dist dist
->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~operation, ~float) ->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~operation, ~float)
->E.R2.fmap(r => Dist(r)) ->E.R2.fmap(r => Dist(r))
->fromResult ->OutputLocal.fromResult
} }
switch fnName { switch fnName {
@ -139,24 +144,28 @@ let rec run = (extra, fnName: operation): outputType => {
dists dists
->GenericDist.mixture(~scaleMultiplyFn=scaleMultiply, ~pointwiseAddFn=pointwiseAdd) ->GenericDist.mixture(~scaleMultiplyFn=scaleMultiply, ~pointwiseAddFn=pointwiseAdd)
->E.R2.fmap(r => Dist(r)) ->E.R2.fmap(r => Dist(r))
->fromResult ->OutputLocal.fromResult
} }
} }
let runFromDist = (extra, fnName, dist) => run(extra, #fromDist(fnName, dist)) let runFromDist = (extra, fnName, dist) => run(extra, #fromDist(fnName, dist))
let runFromFloat = (extra, fnName, float) => run(extra, #fromFloat(fnName, float)) let runFromFloat = (extra, fnName, float) => run(extra, #fromFloat(fnName, float))
let outputMap = ( module Output = {
extra, include OutputLocal
input: outputType,
fn: GenericDist_Types.Operation.singleParamaterFunction, let fmap = (
): outputType => { extra,
let newFnCall: result<operation, error> = switch (fn, input) { input: outputType,
| (#fromDist(fromDist), Dist(o)) => Ok(#fromDist(fromDist, o)) fn: GenericDist_Types.Operation.singleParamaterFunction,
| (#fromFloat(fromDist), Float(o)) => Ok(#fromFloat(fromDist, o)) ): outputType => {
| (_, GenDistError(r)) => Error(r) let newFnCall: result<operation, error> = switch (fn, input) {
| (#fromDist(_), _) => Error(Other("Expected dist, got something else")) | (#fromDist(fromDist), Dist(o)) => Ok(#fromDist(fromDist, o))
| (#fromFloat(_), _) => Error(Other("Expected float, got something else")) | (#fromFloat(fromDist), Float(o)) => Ok(#fromFloat(fromDist, o))
| (_, GenDistError(r)) => Error(r)
| (#fromDist(_), _) => Error(Other("Expected dist, got something else"))
| (#fromFloat(_), _) => Error(Other("Expected float, got something else"))
}
newFnCall->E.R2.fmap(r => run(extra, r))->OutputLocal.fromResult
} }
newFnCall->E.R2.fmap(r => run(extra, r))->fromResult
} }

View File

@ -16,15 +16,13 @@ let runFromDist: (
GenericDist_Types.genericDist, GenericDist_Types.genericDist,
) => outputType ) => outputType
let runFromFloat: (params, GenericDist_Types.Operation.fromDist, float) => outputType let runFromFloat: (params, GenericDist_Types.Operation.fromDist, float) => outputType
let outputMap: (
params,
outputType,
GenericDist_Types.Operation.singleParamaterFunction,
) => outputType
module Output: { module Output: {
let toDist: outputType => option<GenericDist_Types.genericDist> type t = outputType
let toFloat: outputType => option<float> let toDist: t => option<GenericDist_Types.genericDist>
let toString: outputType => option<string> let toDistR: t => result<GenericDist_Types.genericDist, GenericDist_Types.error>
let toError: outputType => option<GenericDist_Types.error> let toFloat: t => option<float>
} let toString: t => option<string>
let toError: t => option<GenericDist_Types.error>
let fmap: (params, t, GenericDist_Types.Operation.singleParamaterFunction) => t
}

View File

@ -98,6 +98,10 @@ module O = {
let max = compare(\">") let max = compare(\">")
} }
module O2 = {
let default = (a,b) => O.default(b,a)
}
/* Functions */ /* Functions */
module F = { module F = {
let apply = (a, e) => a |> e let apply = (a, e) => a |> e