type environment = GenericDist.env @genType.opaque type rec value = | IEvArray(arrayValue) | IEvBool(bool) | IEvDate(Js.Date.t) | IEvDeclaration(lambdaDeclaration) | IEvDistribution(DistributionTypes.genericDist) | IEvLambda(lambdaValue) | IEvNumber(float) | IEvRecord(map) | IEvString(string) | IEvTimeDuration(float) | IEvType(map) | IEvTypeIdentifier(string) | IEvVoid @genType.opaque and arrayValue = array @genType.opaque and map = Belt.Map.String.t and lambdaBody = (array, environment, reducerFn) => value @genType.opaque and lambdaValue = { parameters: array, body: lambdaBody, } @genType.opaque and lambdaDeclaration = Declaration.declaration and expression = | EBlock(array) // programs are similar to blocks, but don't create an inner scope. there can be only one program at the top level of the expression. | EProgram(array) | EArray(array) | ERecord(array<(expression, expression)>) | ESymbol(string) | ETernary(expression, expression, expression) | EAssign(string, expression) | ECall(expression, array) | ELambda(array, expression) | EValue(value) and namespace = Belt.Map.String.t and bindings = { namespace: namespace, parent: option, } and context = { bindings: bindings, environment: environment, } and reducerFn = (expression, context) => (value, context)