Beginning code for mesh

This commit is contained in:
Ozzie Gooen 2022-07-04 17:14:54 -04:00
parent 8d7e6297cc
commit 597a1dbeae
2 changed files with 111 additions and 21 deletions

View File

@ -1,5 +1,11 @@
@genType @genType
type arg = Float({min: float, max: float}) | Date({min: Js.Date.t, max: Js.Date.t}) type arg =
| Float({min: float, max: float})
| Date({min: Js.Date.t, max: Js.Date.t})
| Bool
| String({options: array<string>})
type argType = [#Float(float) | #Date(Js.Date.t) | #Bool(bool) | #String(array<string>)]
@genType @genType
type declaration<'a> = { type declaration<'a> = {
@ -7,6 +13,91 @@ type declaration<'a> = {
args: array<arg>, args: array<arg>,
} }
module Float = {
let range = (min, max, i) => E.A.Floats.range(min, max, i)
let random = (min, max) => min +. Js.Math.random() *. (max -. min)
}
module Date = {
let range = (min: Js.Date.t, max: Js.Date.t, i) => E.JsDate.range(min, max, i)
let random = (min: Js.Date.t, max: Js.Date.t) =>
Float.random(Js.Date.valueOf(min), Js.Date.valueOf(max))->Js.Date.fromFloat
}
module Bool = {
let range = [true, false]
let random = () => E.Int.random(~min=0, ~max=1) |> E.A.unsafe_get([true, false])
}
module String = {
let range = (options: array<string>, i) => {
if E.A.length(options) < i {
options
} else {
Belt.Array.makeBy(i, _ => E.Int.random(~min=0, ~max=E.A.length(options) - 1))
->E.A.uniq
->E.A2.fmap(E.A.unsafe_get(options))
}
}
let random = (options: array<string>) => {
let i = E.Int.random(~min=0, ~max=E.A.length(options) - 1)
E.A.unsafe_get(options, i)
}
}
module Arg = {
let range = (arg: arg, i) =>
switch arg {
| Float({min, max}) => Float.range(min, max, i)->E.A2.fmap(r => #Float(r))
| Date({min, max}) => Date.range(min, max, i)->E.A2.fmap(r => #Date(r))
| Bool => Bool.range->E.A2.fmap(r => #Bool(r))
| String({options}) => String.range(options, i)->E.A2.fmap(r => #String(r))
}
let random = (arg: arg) =>
switch arg {
| Float({min, max}) => #Float(Float.random(min, max))
| Date({min, max}) => #Date(Date.random(min, max))
| Bool => #Bool(Bool.random())
| String({options}) => #String(String.random(options))
}
let possibleValueNumber = (arg: arg) =>
switch arg {
| Float(_) => infinity
| Date(_) => infinity
| Bool => 2.0
| String({options}) => E.A.length(options)->E.Int.toFloat
}
let toString = (arg: arg) => {
switch arg {
| Float({min, max}) =>
`Float({min: ${E.Float.with2DigitsPrecision(min)}, max: ${E.Float.with2DigitsPrecision(
max,
)}})`
| Date({min, max}) =>
`Date({min: ${DateTime.Date.toString(min)}, max: ${DateTime.Date.toString(max)}})`
}
}
}
let meshFromCount = (args: array<arg>, total) => {
let length = E.A.length(args)
let averageCount =
Js.Math.pow_float(
~base=E.Int.toFloat(total),
~exp=1.0 /. E.Int.toFloat(length),
)->Js.Math.floor_int
args->E.A2.fmap(Arg.range(_, averageCount))->E.A.cartesianProductMany
}
let randomFromCount = (args: array<arg>, total) => {
let randomItem = () => args |> E.A.fmap(Arg.random)
Belt.Array.makeBy(total, _ => randomItem())
}
module ContinuousFloatArg = { module ContinuousFloatArg = {
let make = (min: float, max: float): arg => { let make = (min: float, max: float): arg => {
Float({min: min, max: max}) Float({min: min, max: max})
@ -19,19 +110,6 @@ module ContinuousTimeArg = {
} }
} }
module Arg = {
let toString = (arg: arg) => {
switch arg {
| Float({min, max}) =>
`Float({min: ${E.Float.with2DigitsPrecision(min)}, max: ${E.Float.with2DigitsPrecision(
max,
)}})`
| Date({min, max}) =>
`Date({min: ${DateTime.Date.toString(min)}, max: ${DateTime.Date.toString(max)}})`
}
}
}
let make = (fn: 'a, args: array<arg>): declaration<'a> => { let make = (fn: 'a, args: array<arg>): declaration<'a> => {
{fn: fn, args: args} {fn: fn, args: args}
} }

View File

@ -35,6 +35,7 @@ module FloatFloatMap = {
module Int = { module Int = {
let max = (i1: int, i2: int) => i1 > i2 ? i1 : i2 let max = (i1: int, i2: int) => i1 > i2 ? i1 : i2
let random = (~min, ~max) => Js.Math.random_int(min, max) let random = (~min, ~max) => Js.Math.random_int(min, max)
let toFloat = Belt.Int.toFloat
} }
/* Utils */ /* Utils */
module U = { module U = {
@ -362,13 +363,6 @@ module J = {
} }
} }
module JsDate = {
let fromString = Js.Date.fromString
let now = Js.Date.now
let make = Js.Date.make
let valueOf = Js.Date.valueOf
}
/* List */ /* List */
module L = { module L = {
module Util = { module Util = {
@ -634,6 +628,15 @@ module A = {
let all = (p: 'a => bool, xs: array<'a>): bool => length(filter(p, xs)) == length(xs) let all = (p: 'a => bool, xs: array<'a>): bool => length(filter(p, xs)) == length(xs)
let any = (p: 'a => bool, xs: array<'a>): bool => length(filter(p, xs)) > 0 let any = (p: 'a => bool, xs: array<'a>): bool => length(filter(p, xs)) > 0
let cartesianProductMany = (combinations: array<array<'a>>) => {
let appendCombination = (l: array<array<'a>>, l': array<'a>): array<array<'a>> =>
l |> fmap(lEl => l' |> fmap(l'El => concat(lEl, [l'El]))) |> concatMany
let laterCombinations = Belt.Array.sliceToEnd(combinations, 1)
let startArray = combinations->unsafe_get(0) |> fmap(r => [r])
let results = reduce(laterCombinations, startArray, appendCombination)
results
}
module O = { module O = {
let concatSomes = (optionals: array<option<'a>>): array<'a> => let concatSomes = (optionals: array<option<'a>>): array<'a> =>
optionals optionals
@ -882,3 +885,12 @@ module Dict = {
let concat = (a, b) => A.concat(toArray(a), toArray(b))->fromArray let concat = (a, b) => A.concat(toArray(a), toArray(b))->fromArray
let concatMany = ts => ts->A2.fmap(toArray)->A.concatMany->fromArray let concatMany = ts => ts->A2.fmap(toArray)->A.concatMany->fromArray
} }
module JsDate = {
let fromString = Js.Date.fromString
let now = Js.Date.now
let make = Js.Date.make
let valueOf = Js.Date.valueOf
let fromFloat = Js.Date.fromFloat
let range = (min, max, n) => A.Floats.range(valueOf(min), valueOf(max), n) |> A.fmap(fromFloat)
}