polymorphic variants to neatly constrain types

This commit is contained in:
Quinn Dougherty 2022-07-04 11:24:30 -04:00
parent 4858aa9fe5
commit 7889332052
8 changed files with 154 additions and 143 deletions

View File

@ -34,7 +34,7 @@ describe("sparkline", () => {
expected: DistributionOperation.outputType,
) => {
test(name, () => {
let result = DistributionOperation.run(~env, FromDist(ToString(ToSparkline(20)), dist))
let result = DistributionOperation.run(~env, FromDist(#ToString(ToSparkline(20)), dist))
expect(result)->toEqual(expected)
})
}
@ -81,8 +81,8 @@ describe("sparkline", () => {
describe("toPointSet", () => {
test("on symbolic normal distribution", () => {
let result =
run(FromDist(ToDist(ToPointSet), normalDist5))
->outputMap(FromDist(ToFloat(#Mean)))
run(FromDist(#ToDist(ToPointSet), normalDist5))
->outputMap(FromDist(#ToFloat(#Mean)))
->toFloat
->toExt
expect(result)->toBeSoCloseTo(5.0, ~digits=0)
@ -90,10 +90,10 @@ describe("toPointSet", () => {
test("on sample set", () => {
let result =
run(FromDist(ToDist(ToPointSet), normalDist5))
->outputMap(FromDist(ToDist(ToSampleSet(1000))))
->outputMap(FromDist(ToDist(ToPointSet)))
->outputMap(FromDist(ToFloat(#Mean)))
run(FromDist(#ToDist(ToPointSet), normalDist5))
->outputMap(FromDist(#ToDist(ToSampleSet(1000))))
->outputMap(FromDist(#ToDist(ToPointSet)))
->outputMap(FromDist(#ToFloat(#Mean)))
->toFloat
->toExt
expect(result)->toBeSoCloseTo(5.0, ~digits=-1)

View File

@ -11,7 +11,7 @@ describe("mixture", () => {
let (mean1, mean2) = tup
let meanValue = {
run(Mixture([(mkNormal(mean1, 9e-1), 0.5), (mkNormal(mean2, 9e-1), 0.5)]))->outputMap(
FromDist(ToFloat(#Mean)),
FromDist(#ToFloat(#Mean)),
)
}
meanValue->unpackFloat->expect->toBeSoCloseTo((mean1 +. mean2) /. 2.0, ~digits=-1)
@ -28,7 +28,7 @@ describe("mixture", () => {
let meanValue = {
run(
Mixture([(mkBeta(alpha, beta), betaWeight), (mkExponential(rate), exponentialWeight)]),
)->outputMap(FromDist(ToFloat(#Mean)))
)->outputMap(FromDist(#ToFloat(#Mean)))
}
let betaMean = 1.0 /. (1.0 +. beta /. alpha)
let exponentialMean = 1.0 /. rate
@ -52,7 +52,7 @@ describe("mixture", () => {
(mkUniform(low, high), uniformWeight),
(mkLognormal(mu, sigma), lognormalWeight),
]),
)->outputMap(FromDist(ToFloat(#Mean)))
)->outputMap(FromDist(#ToFloat(#Mean)))
}
let uniformMean = (low +. high) /. 2.0
let lognormalMean = mu +. sigma ** 2.0 /. 2.0

View File

@ -186,8 +186,8 @@ describe("combineAlongSupportOfSecondArgument0", () => {
uniformMakeR(lowPrediction, highPrediction)->E.R2.errMap(s => DistributionTypes.ArgumentError(
s,
))
let answerWrapped = E.R.fmap(a => run(FromDist(ToDist(ToPointSet), a)), answer)
let predictionWrapped = E.R.fmap(a => run(FromDist(ToDist(ToPointSet), a)), prediction)
let answerWrapped = E.R.fmap(a => run(FromDist(#ToDist(ToPointSet), a)), answer)
let predictionWrapped = E.R.fmap(a => run(FromDist(#ToDist(ToPointSet), a)), prediction)
let interpolator = XYShape.XtoY.continuousInterpolator(#Stepwise, #UseZero)
let integrand = PointSetDist_Scoring.WithDistAnswer.integrand

View File

@ -8,34 +8,34 @@ let mkNormal = (mean, stdev) => DistributionTypes.Symbolic(#Normal({mean: mean,
describe("(Symbolic) normalize", () => {
testAll("has no impact on normal distributions", list{-1e8, -1e-2, 0.0, 1e-4, 1e16}, mean => {
let normalValue = mkNormal(mean, 2.0)
let normalizedValue = run(FromDist(ToDist(Normalize), normalValue))
let normalizedValue = run(FromDist(#ToDist(Normalize), normalValue))
normalizedValue->unpackDist->expect->toEqual(normalValue)
})
})
describe("(Symbolic) mean", () => {
testAll("of normal distributions", list{-1e8, -16.0, -1e-2, 0.0, 1e-4, 32.0, 1e16}, mean => {
run(FromDist(ToFloat(#Mean), mkNormal(mean, 4.0)))->unpackFloat->expect->toBeCloseTo(mean)
run(FromDist(#ToFloat(#Mean), mkNormal(mean, 4.0)))->unpackFloat->expect->toBeCloseTo(mean)
})
Skip.test("of normal(0, -1) (it NaNs out)", () => {
run(FromDist(ToFloat(#Mean), mkNormal(1e1, -1e0)))->unpackFloat->expect->ExpectJs.toBeFalsy
run(FromDist(#ToFloat(#Mean), mkNormal(1e1, -1e0)))->unpackFloat->expect->ExpectJs.toBeFalsy
})
test("of normal(0, 1e-8) (it doesn't freak out at tiny stdev)", () => {
run(FromDist(ToFloat(#Mean), mkNormal(0.0, 1e-8)))->unpackFloat->expect->toBeCloseTo(0.0)
run(FromDist(#ToFloat(#Mean), mkNormal(0.0, 1e-8)))->unpackFloat->expect->toBeCloseTo(0.0)
})
testAll("of exponential distributions", list{1e-7, 2.0, 10.0, 100.0}, rate => {
let meanValue = run(
FromDist(ToFloat(#Mean), DistributionTypes.Symbolic(#Exponential({rate: rate}))),
FromDist(#ToFloat(#Mean), DistributionTypes.Symbolic(#Exponential({rate: rate}))),
)
meanValue->unpackFloat->expect->toBeCloseTo(1.0 /. rate) // https://en.wikipedia.org/wiki/Exponential_distribution#Mean,_variance,_moments,_and_median
})
test("of a cauchy distribution", () => {
let meanValue = run(
FromDist(ToFloat(#Mean), DistributionTypes.Symbolic(#Cauchy({local: 1.0, scale: 1.0}))),
FromDist(#ToFloat(#Mean), DistributionTypes.Symbolic(#Cauchy({local: 1.0, scale: 1.0}))),
)
meanValue->unpackFloat->expect->toBeSoCloseTo(1.0098094001641797, ~digits=5)
//-> toBe(GenDistError(Other("Cauchy distributions may have no mean value.")))
@ -48,7 +48,7 @@ describe("(Symbolic) mean", () => {
let (low, medium, high) = tup
let meanValue = run(
FromDist(
ToFloat(#Mean),
#ToFloat(#Mean),
DistributionTypes.Symbolic(#Triangular({low: low, medium: medium, high: high})),
),
)
@ -63,7 +63,7 @@ describe("(Symbolic) mean", () => {
tup => {
let (alpha, beta) = tup
let meanValue = run(
FromDist(ToFloat(#Mean), DistributionTypes.Symbolic(#Beta({alpha: alpha, beta: beta}))),
FromDist(#ToFloat(#Mean), DistributionTypes.Symbolic(#Beta({alpha: alpha, beta: beta}))),
)
meanValue->unpackFloat->expect->toBeCloseTo(1.0 /. (1.0 +. beta /. alpha)) // https://en.wikipedia.org/wiki/Beta_distribution#Mean
},
@ -72,7 +72,7 @@ describe("(Symbolic) mean", () => {
// TODO: When we have our theory of validators we won't want this to be NaN but to be an error.
test("of beta(0, 0)", () => {
let meanValue = run(
FromDist(ToFloat(#Mean), DistributionTypes.Symbolic(#Beta({alpha: 0.0, beta: 0.0}))),
FromDist(#ToFloat(#Mean), DistributionTypes.Symbolic(#Beta({alpha: 0.0, beta: 0.0}))),
)
meanValue->unpackFloat->expect->ExpectJs.toBeFalsy
})
@ -83,7 +83,7 @@ describe("(Symbolic) mean", () => {
tup => {
let (mu, sigma) = tup
let meanValue = run(
FromDist(ToFloat(#Mean), DistributionTypes.Symbolic(#Lognormal({mu: mu, sigma: sigma}))),
FromDist(#ToFloat(#Mean), DistributionTypes.Symbolic(#Lognormal({mu: mu, sigma: sigma}))),
)
meanValue->unpackFloat->expect->toBeCloseTo(Js.Math.exp(mu +. sigma ** 2.0 /. 2.0)) // https://brilliant.org/wiki/log-normal-distribution/
},
@ -95,14 +95,14 @@ describe("(Symbolic) mean", () => {
tup => {
let (low, high) = tup
let meanValue = run(
FromDist(ToFloat(#Mean), DistributionTypes.Symbolic(#Uniform({low: low, high: high}))),
FromDist(#ToFloat(#Mean), DistributionTypes.Symbolic(#Uniform({low: low, high: high}))),
)
meanValue->unpackFloat->expect->toBeCloseTo((low +. high) /. 2.0) // https://en.wikipedia.org/wiki/Continuous_uniform_distribution#Moments
},
)
test("of a float", () => {
let meanValue = run(FromDist(ToFloat(#Mean), DistributionTypes.Symbolic(#Float(7.7))))
let meanValue = run(FromDist(#ToFloat(#Mean), DistributionTypes.Symbolic(#Float(7.7))))
meanValue->unpackFloat->expect->toBeCloseTo(7.7)
})
})

View File

@ -101,14 +101,14 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => {
}
let toPointSetFn = r => {
switch reCall(~functionCallInfo=FromDist(ToDist(ToPointSet), r), ()) {
switch reCall(~functionCallInfo=FromDist(#ToDist(ToPointSet), r), ()) {
| Dist(PointSet(p)) => Ok(p)
| e => Error(OutputLocal.toErrorOrUnreachable(e))
}
}
let toSampleSetFn = r => {
switch reCall(~functionCallInfo=FromDist(ToDist(ToSampleSet(sampleCount)), r), ()) {
switch reCall(~functionCallInfo=FromDist(#ToDist(ToSampleSet(sampleCount)), r), ()) {
| Dist(SampleSet(p)) => Ok(p)
| e => Error(OutputLocal.toErrorOrUnreachable(e))
}
@ -116,13 +116,13 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => {
let scaleMultiply = (r, weight) =>
reCall(
~functionCallInfo=FromDist(ToDistCombination(Pointwise, #Multiply, #Float(weight)), r),
~functionCallInfo=FromDist(#ToDistCombination(Pointwise, #Multiply, #Float(weight)), r),
(),
)->OutputLocal.toDistR
let pointwiseAdd = (r1, r2) =>
reCall(
~functionCallInfo=FromDist(ToDistCombination(Pointwise, #Add, #Dist(r2)), r1),
~functionCallInfo=FromDist(#ToDistCombination(Pointwise, #Add, #Dist(r2)), r1),
(),
)->OutputLocal.toDistR
@ -131,40 +131,40 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => {
dist: genericDist,
): outputType => {
let response = switch subFnName {
| ToFloat(distToFloatOperation) =>
| #ToFloat(distToFloatOperation) =>
GenericDist.toFloatOperation(dist, ~toPointSetFn, ~distToFloatOperation)
->E.R2.fmap(r => Float(r))
->OutputLocal.fromResult
| ToString(ToString) => dist->GenericDist.toString->String
| ToString(ToSparkline(bucketCount)) =>
| #ToString(ToString) => dist->GenericDist.toString->String
| #ToString(ToSparkline(bucketCount)) =>
GenericDist.toSparkline(dist, ~sampleCount, ~bucketCount, ())
->E.R2.fmap(r => String(r))
->OutputLocal.fromResult
| ToDist(Inspect) => {
| #ToDist(Inspect) => {
Js.log2("Console log requested: ", dist)
Dist(dist)
}
| ToDist(Normalize) => dist->GenericDist.normalize->Dist
| ToScore(LogScore(answer, prior)) =>
| #ToDist(Normalize) => dist->GenericDist.normalize->Dist
| #ToScore(LogScore(answer, prior)) =>
GenericDist.Score.logScore(~estimate=Score_Dist(dist), ~answer, ~prior)
->E.R2.fmap(s => Float(s))
->OutputLocal.fromResult
| ToBool(IsNormalized) => dist->GenericDist.isNormalized->Bool
| ToDist(Truncate(leftCutoff, rightCutoff)) =>
| #ToBool(IsNormalized) => dist->GenericDist.isNormalized->Bool
| #ToDist(Truncate(leftCutoff, rightCutoff)) =>
GenericDist.truncate(~toPointSetFn, ~leftCutoff, ~rightCutoff, dist, ())
->E.R2.fmap(r => Dist(r))
->OutputLocal.fromResult
| ToDist(ToSampleSet(n)) =>
| #ToDist(ToSampleSet(n)) =>
dist
->GenericDist.toSampleSetDist(n)
->E.R2.fmap(r => Dist(SampleSet(r)))
->OutputLocal.fromResult
| ToDist(ToPointSet) =>
| #ToDist(ToPointSet) =>
dist
->GenericDist.toPointSet(~xyPointLength, ~sampleCount, ())
->E.R2.fmap(r => Dist(PointSet(r)))
->OutputLocal.fromResult
| ToDist(Scale(#LogarithmWithThreshold(eps), f)) =>
| #ToDist(Scale(#LogarithmWithThreshold(eps), f)) =>
dist
->GenericDist.pointwiseCombinationFloat(
~toPointSetFn,
@ -173,23 +173,23 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => {
)
->E.R2.fmap(r => Dist(r))
->OutputLocal.fromResult
| ToDist(Scale(#Multiply, f)) =>
| #ToDist(Scale(#Multiply, f)) =>
dist
->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~algebraicCombination=#Multiply, ~f)
->E.R2.fmap(r => Dist(r))
->OutputLocal.fromResult
| ToDist(Scale(#Logarithm, f)) =>
| #ToDist(Scale(#Logarithm, f)) =>
dist
->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~algebraicCombination=#Logarithm, ~f)
->E.R2.fmap(r => Dist(r))
->OutputLocal.fromResult
| ToDist(Scale(#Power, f)) =>
| #ToDist(Scale(#Power, f)) =>
dist
->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~algebraicCombination=#Power, ~f)
->E.R2.fmap(r => Dist(r))
->OutputLocal.fromResult
| ToDistCombination(Algebraic(_), _, #Float(_)) => GenDistError(NotYetImplemented)
| ToDistCombination(Algebraic(strategy), arithmeticOperation, #Dist(t2)) =>
| #ToDistCombination(Algebraic(_), _, #Float(_)) => GenDistError(NotYetImplemented)
| #ToDistCombination(Algebraic(strategy), arithmeticOperation, #Dist(t2)) =>
dist
->GenericDist.algebraicCombination(
~strategy,
@ -200,12 +200,12 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => {
)
->E.R2.fmap(r => Dist(r))
->OutputLocal.fromResult
| ToDistCombination(Pointwise, algebraicCombination, #Dist(t2)) =>
| #ToDistCombination(Pointwise, algebraicCombination, #Dist(t2)) =>
dist
->GenericDist.pointwiseCombination(~toPointSetFn, ~algebraicCombination, ~t2)
->E.R2.fmap(r => Dist(r))
->OutputLocal.fromResult
| ToDistCombination(Pointwise, algebraicCombination, #Float(f)) =>
| #ToDistCombination(Pointwise, algebraicCombination, #Float(f)) =>
dist
->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~algebraicCombination, ~f)
->E.R2.fmap(r => Dist(r))
@ -216,8 +216,7 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => {
switch functionCallInfo {
| FromDist(subFnName, dist) => fromDistFn(subFnName, dist)
| FromFloat(subFnName, float) =>
reCall(~functionCallInfo=FromDist(subFnName, GenericDist.fromFloat(float)), ())
| FromFloat(subFnName, x) => reCall(~functionCallInfo=FromFloat(subFnName, x), ())
| Mixture(dists) =>
dists
->GenericDist.mixture(~scaleMultiplyFn=scaleMultiply, ~pointwiseAddFn=pointwiseAdd)

View File

@ -27,7 +27,7 @@ let runFromDist: (
) => outputType
let runFromFloat: (
~env: env,
~functionCallInfo: DistributionTypes.DistributionOperation.fromDist,
~functionCallInfo: DistributionTypes.DistributionOperation.fromFloat,
float,
) => outputType

View File

@ -102,58 +102,82 @@ module DistributionOperation = {
type toScore = LogScore(genericDistOrScalar, option<genericDistOrScalar>)
type fromDist =
| ToFloat(toFloat)
| ToDist(toDist)
| ToScore(toScore)
| ToDistCombination(direction, Operation.Algebraic.t, [#Dist(genericDist) | #Float(float)])
| ToString(toString)
| ToBool(toBool)
type fromFloat = [
| #ToFloat(toFloat)
| #ToDist(toDist)
| #ToDistCombination(direction, Operation.Algebraic.t, [#Dist(genericDist) | #Float(float)])
| #ToString(toString)
| #ToBool(toBool)
]
type fromDist = [
| fromFloat
| #ToScore(toScore)
]
type singleParamaterFunction =
| FromDist(fromDist)
| FromFloat(fromDist)
| FromFloat(fromFloat)
type genericFunctionCallInfo =
| FromDist(fromDist, genericDist)
| FromFloat(fromDist, float)
| FromFloat(fromFloat, float)
| FromSamples(array<float>)
| Mixture(array<(genericDist, float)>)
let distCallToString = (distFunction: fromDist): string =>
switch distFunction {
| ToFloat(#Cdf(r)) => `cdf(${E.Float.toFixed(r)})`
| ToFloat(#Inv(r)) => `inv(${E.Float.toFixed(r)})`
| ToFloat(#Mean) => `mean`
| ToFloat(#Min) => `min`
| ToFloat(#Max) => `max`
| ToFloat(#Stdev) => `stdev`
| ToFloat(#Variance) => `variance`
| ToFloat(#Mode) => `mode`
| ToFloat(#Pdf(r)) => `pdf(${E.Float.toFixed(r)})`
| ToFloat(#Sample) => `sample`
| ToFloat(#IntegralSum) => `integralSum`
| ToScore(_) => `logScore`
| ToDist(Normalize) => `normalize`
| ToDist(ToPointSet) => `toPointSet`
| ToDist(ToSampleSet(r)) => `toSampleSet(${E.I.toString(r)})`
| ToDist(Truncate(_, _)) => `truncate`
| ToDist(Inspect) => `inspect`
| ToDist(Scale(#Power, r)) => `scalePower(${E.Float.toFixed(r)})`
| ToDist(Scale(#Multiply, r)) => `scaleMultiply(${E.Float.toFixed(r)})`
| ToDist(Scale(#Logarithm, r)) => `scaleLog(${E.Float.toFixed(r)})`
| ToDist(Scale(#LogarithmWithThreshold(eps), r)) =>
let floatCallToString = (floatFunction: fromFloat): string =>
switch floatFunction {
| #ToFloat(#Cdf(r)) => `cdf(${E.Float.toFixed(r)})`
| #ToFloat(#Inv(r)) => `inv(${E.Float.toFixed(r)})`
| #ToFloat(#Mean) => `mean`
| #ToFloat(#Min) => `min`
| #ToFloat(#Max) => `max`
| #ToFloat(#Stdev) => `stdev`
| #ToFloat(#Variance) => `variance`
| #ToFloat(#Mode) => `mode`
| #ToFloat(#Pdf(r)) => `pdf(${E.Float.toFixed(r)})`
| #ToFloat(#Sample) => `sample`
| #ToFloat(#IntegralSum) => `integralSum`
| #ToDist(Normalize) => `normalize`
| #ToDist(ToPointSet) => `toPointSet`
| #ToDist(ToSampleSet(r)) => `toSampleSet(${E.I.toString(r)})`
| #ToDist(Truncate(_, _)) => `truncate`
| #ToDist(Inspect) => `inspect`
| #ToDist(Scale(#Power, r)) => `scalePower(${E.Float.toFixed(r)})`
| #ToDist(Scale(#Multiply, r)) => `scaleMultiply(${E.Float.toFixed(r)})`
| #ToDist(Scale(#Logarithm, r)) => `scaleLog(${E.Float.toFixed(r)})`
| #ToDist(Scale(#LogarithmWithThreshold(eps), r)) =>
`scaleLogWithThreshold(${E.Float.toFixed(r)}, epsilon=${E.Float.toFixed(eps)})`
| ToString(ToString) => `toString`
| ToString(ToSparkline(n)) => `sparkline(${E.I.toString(n)})`
| ToBool(IsNormalized) => `isNormalized`
| ToDistCombination(Algebraic(_), _, _) => `algebraic`
| ToDistCombination(Pointwise, _, _) => `pointwise`
| #ToString(ToString) => `toString`
| #ToString(ToSparkline(n)) => `sparkline(${E.I.toString(n)})`
| #ToBool(IsNormalized) => `isNormalized`
| #ToDistCombination(Algebraic(_), _, _) => `algebraic`
| #ToDistCombination(Pointwise, _, _) => `pointwise`
}
let distCallToString = (
distFunction: [
| #ToFloat(toFloat)
| #ToDist(toDist)
| #ToDistCombination(direction, Operation.Algebraic.t, [#Dist(genericDist) | #Float(float)])
| #ToString(toString)
| #ToBool(toBool)
| #ToScore(toScore)
],
): string =>
switch distFunction {
| #ToScore(_) => `logScore`
| #ToFloat(x) => floatCallToString(#ToFloat(x))
| #ToDist(x) => floatCallToString(#ToDist(x))
| #ToString(x) => floatCallToString(#ToString(x))
| #ToBool(x) => floatCallToString(#ToBool(x))
| #ToDistCombination(x, y, z) => floatCallToString(#ToDistCombination(x, y, z))
}
let toString = (d: genericFunctionCallInfo): string =>
switch d {
| FromDist(f, _) | FromFloat(f, _) => distCallToString(f)
| FromDist(f, _) => distCallToString(f)
| FromFloat(f, _) => floatCallToString(f)
| Mixture(_) => `mixture`
| FromSamples(_) => `fromSamples`
}
@ -163,93 +187,93 @@ module Constructors = {
module UsingDists = {
@genType
let mean = (dist): t => FromDist(ToFloat(#Mean), dist)
let stdev = (dist): t => FromDist(ToFloat(#Stdev), dist)
let variance = (dist): t => FromDist(ToFloat(#Variance), dist)
let sample = (dist): t => FromDist(ToFloat(#Sample), dist)
let cdf = (dist, x): t => FromDist(ToFloat(#Cdf(x)), dist)
let inv = (dist, x): t => FromDist(ToFloat(#Inv(x)), dist)
let pdf = (dist, x): t => FromDist(ToFloat(#Pdf(x)), dist)
let normalize = (dist): t => FromDist(ToDist(Normalize), dist)
let isNormalized = (dist): t => FromDist(ToBool(IsNormalized), dist)
let toPointSet = (dist): t => FromDist(ToDist(ToPointSet), dist)
let toSampleSet = (dist, r): t => FromDist(ToDist(ToSampleSet(r)), dist)
let mean = (dist): t => FromDist(#ToFloat(#Mean), dist)
let stdev = (dist): t => FromDist(#ToFloat(#Stdev), dist)
let variance = (dist): t => FromDist(#ToFloat(#Variance), dist)
let sample = (dist): t => FromDist(#ToFloat(#Sample), dist)
let cdf = (dist, x): t => FromDist(#ToFloat(#Cdf(x)), dist)
let inv = (dist, x): t => FromDist(#ToFloat(#Inv(x)), dist)
let pdf = (dist, x): t => FromDist(#ToFloat(#Pdf(x)), dist)
let normalize = (dist): t => FromDist(#ToDist(Normalize), dist)
let isNormalized = (dist): t => FromDist(#ToBool(IsNormalized), dist)
let toPointSet = (dist): t => FromDist(#ToDist(ToPointSet), dist)
let toSampleSet = (dist, r): t => FromDist(#ToDist(ToSampleSet(r)), dist)
let fromSamples = (xs): t => FromSamples(xs)
let truncate = (dist, left, right): t => FromDist(ToDist(Truncate(left, right)), dist)
let inspect = (dist): t => FromDist(ToDist(Inspect), dist)
let truncate = (dist, left, right): t => FromDist(#ToDist(Truncate(left, right)), dist)
let inspect = (dist): t => FromDist(#ToDist(Inspect), dist)
module LogScore = {
let distEstimateDistAnswer = (estimate, answer): t => FromDist(
ToScore(LogScore(Score_Dist(answer), None)),
#ToScore(LogScore(Score_Dist(answer), None)),
estimate,
)
let distEstimateDistAnswerWithPrior = (estimate, answer, prior): t => FromDist(
ToScore(LogScore(Score_Dist(answer), Some(prior))),
#ToScore(LogScore(Score_Dist(answer), Some(prior))),
estimate,
)
let distEstimateScalarAnswer = (estimate, answer): t => FromDist(
ToScore(LogScore(Score_Scalar(answer), None)),
#ToScore(LogScore(Score_Scalar(answer), None)),
estimate,
)
let distEstimateScalarAnswerWithPrior = (estimate, answer, prior): t => FromDist(
ToScore(LogScore(Score_Scalar(answer), Some(prior))),
#ToScore(LogScore(Score_Scalar(answer), Some(prior))),
estimate,
)
}
let scaleMultiply = (dist, n): t => FromDist(ToDist(Scale(#Multiply, n)), dist)
let scalePower = (dist, n): t => FromDist(ToDist(Scale(#Power, n)), dist)
let scaleLogarithm = (dist, n): t => FromDist(ToDist(Scale(#Logarithm, n)), dist)
let scaleMultiply = (dist, n): t => FromDist(#ToDist(Scale(#Multiply, n)), dist)
let scalePower = (dist, n): t => FromDist(#ToDist(Scale(#Power, n)), dist)
let scaleLogarithm = (dist, n): t => FromDist(#ToDist(Scale(#Logarithm, n)), dist)
let scaleLogarithmWithThreshold = (dist, n, eps): t => FromDist(
ToDist(Scale(#LogarithmWithThreshold(eps), n)),
#ToDist(Scale(#LogarithmWithThreshold(eps), n)),
dist,
)
let toString = (dist): t => FromDist(ToString(ToString), dist)
let toSparkline = (dist, n): t => FromDist(ToString(ToSparkline(n)), dist)
let toString = (dist): t => FromDist(#ToString(ToString), dist)
let toSparkline = (dist, n): t => FromDist(#ToString(ToSparkline(n)), dist)
let algebraicAdd = (dist1, dist2: genericDist): t => FromDist(
ToDistCombination(Algebraic(AsDefault), #Add, #Dist(dist2)),
#ToDistCombination(Algebraic(AsDefault), #Add, #Dist(dist2)),
dist1,
)
let algebraicMultiply = (dist1, dist2): t => FromDist(
ToDistCombination(Algebraic(AsDefault), #Multiply, #Dist(dist2)),
#ToDistCombination(Algebraic(AsDefault), #Multiply, #Dist(dist2)),
dist1,
)
let algebraicDivide = (dist1, dist2): t => FromDist(
ToDistCombination(Algebraic(AsDefault), #Divide, #Dist(dist2)),
#ToDistCombination(Algebraic(AsDefault), #Divide, #Dist(dist2)),
dist1,
)
let algebraicSubtract = (dist1, dist2): t => FromDist(
ToDistCombination(Algebraic(AsDefault), #Subtract, #Dist(dist2)),
#ToDistCombination(Algebraic(AsDefault), #Subtract, #Dist(dist2)),
dist1,
)
let algebraicLogarithm = (dist1, dist2): t => FromDist(
ToDistCombination(Algebraic(AsDefault), #Logarithm, #Dist(dist2)),
#ToDistCombination(Algebraic(AsDefault), #Logarithm, #Dist(dist2)),
dist1,
)
let algebraicPower = (dist1, dist2): t => FromDist(
ToDistCombination(Algebraic(AsDefault), #Power, #Dist(dist2)),
#ToDistCombination(Algebraic(AsDefault), #Power, #Dist(dist2)),
dist1,
)
let pointwiseAdd = (dist1, dist2): t => FromDist(
ToDistCombination(Pointwise, #Add, #Dist(dist2)),
#ToDistCombination(Pointwise, #Add, #Dist(dist2)),
dist1,
)
let pointwiseMultiply = (dist1, dist2): t => FromDist(
ToDistCombination(Pointwise, #Multiply, #Dist(dist2)),
#ToDistCombination(Pointwise, #Multiply, #Dist(dist2)),
dist1,
)
let pointwiseDivide = (dist1, dist2): t => FromDist(
ToDistCombination(Pointwise, #Divide, #Dist(dist2)),
#ToDistCombination(Pointwise, #Divide, #Dist(dist2)),
dist1,
)
let pointwiseSubtract = (dist1, dist2): t => FromDist(
ToDistCombination(Pointwise, #Subtract, #Dist(dist2)),
#ToDistCombination(Pointwise, #Subtract, #Dist(dist2)),
dist1,
)
let pointwiseLogarithm = (dist1, dist2): t => FromDist(
ToDistCombination(Pointwise, #Logarithm, #Dist(dist2)),
#ToDistCombination(Pointwise, #Logarithm, #Dist(dist2)),
dist1,
)
let pointwisePower = (dist1, dist2): t => FromDist(
ToDistCombination(Pointwise, #Power, #Dist(dist2)),
#ToDistCombination(Pointwise, #Power, #Dist(dist2)),
dist1,
)
}

View File

@ -34,9 +34,7 @@ module Helpers = {
dist: DistributionTypes.genericDist,
~env: DistributionOperation.env,
) => {
FromDist(DistributionTypes.DistributionOperation.ToFloat(fnCall), dist)
->DistributionOperation.run(~env)
->Some
FromDist(#ToFloat(fnCall), dist)->DistributionOperation.run(~env)->Some
}
let toStringFn = (
@ -44,9 +42,7 @@ module Helpers = {
dist: DistributionTypes.genericDist,
~env: DistributionOperation.env,
) => {
FromDist(DistributionTypes.DistributionOperation.ToString(fnCall), dist)
->DistributionOperation.run(~env)
->Some
FromDist(#ToString(fnCall), dist)->DistributionOperation.run(~env)->Some
}
let toBoolFn = (
@ -54,9 +50,7 @@ module Helpers = {
dist: DistributionTypes.genericDist,
~env: DistributionOperation.env,
) => {
FromDist(DistributionTypes.DistributionOperation.ToBool(fnCall), dist)
->DistributionOperation.run(~env)
->Some
FromDist(#ToBool(fnCall), dist)->DistributionOperation.run(~env)->Some
}
let toDistFn = (
@ -64,18 +58,12 @@ module Helpers = {
dist,
~env: DistributionOperation.env,
) => {
FromDist(DistributionTypes.DistributionOperation.ToDist(fnCall), dist)
->DistributionOperation.run(~env)
->Some
FromDist(#ToDist(fnCall), dist)->DistributionOperation.run(~env)->Some
}
let twoDiststoDistFn = (direction, arithmetic, dist1, dist2, ~env: DistributionOperation.env) => {
FromDist(
DistributionTypes.DistributionOperation.ToDistCombination(
direction,
arithmeticMap(arithmetic),
#Dist(dist2),
),
#ToDistCombination(direction, arithmeticMap(arithmetic), #Dist(dist2)),
dist1,
)->DistributionOperation.run(~env)
}
@ -229,7 +217,7 @@ let dispatchToGenericOutput = (call: IEV.functionCall, env: DistributionOperatio
Some(
DistributionOperation.run(
FromDist(
ToScore(LogScore(DistributionTypes.DistributionOperation.Score_Dist(answer), None)),
#ToScore(LogScore(DistributionTypes.DistributionOperation.Score_Dist(answer), None)),
prediction,
),
~env,
@ -242,7 +230,7 @@ let dispatchToGenericOutput = (call: IEV.functionCall, env: DistributionOperatio
Some(
DistributionOperation.run(
FromDist(
ToScore(
#ToScore(
LogScore(
DistributionTypes.DistributionOperation.Score_Dist(answer),
Some(DistributionTypes.DistributionOperation.Score_Dist(prior)),
@ -267,7 +255,7 @@ let dispatchToGenericOutput = (call: IEV.functionCall, env: DistributionOperatio
) =>
DistributionOperation.run(
FromDist(
ToScore(
#ToScore(
LogScore(
DistributionTypes.DistributionOperation.Score_Scalar(answer),
DistributionTypes.DistributionOperation.Score_Dist(prior)->Some,
@ -284,7 +272,7 @@ let dispatchToGenericOutput = (call: IEV.functionCall, env: DistributionOperatio
) =>
DistributionOperation.run(
FromDist(
ToScore(LogScore(DistributionTypes.DistributionOperation.Score_Scalar(answer), None)),
#ToScore(LogScore(DistributionTypes.DistributionOperation.Score_Scalar(answer), None)),
prediction,
),
~env,