define function returning result

This commit is contained in:
Umur Ozkul 2022-07-11 17:45:26 +02:00
parent d25e052b61
commit 532a878911
3 changed files with 46 additions and 1 deletions

View File

@ -22,6 +22,13 @@ module FooImplementation = {
let makeFoo = (a: string, b: string, _environment): string => `I am ${a}-foo and I am ${b}-foo` let makeFoo = (a: string, b: string, _environment): string => `I am ${a}-foo and I am ${b}-foo`
let makeBar = (a: float, b: float, _environment): string => let makeBar = (a: float, b: float, _environment): string =>
`I am ${a->Js.Float.toString}-bar and I am ${b->Js.Float.toString}-bar` `I am ${a->Js.Float.toString}-bar and I am ${b->Js.Float.toString}-bar`
// You can also define functions that has their internal errors
let makeReturningError = (_a: float, _b: float, _environment): result<float, ErrorValue.t> =>
if false {
0.->Ok
} else {
ErrorValue.RETodo("test error")->Error
}
} }
// There is a potential for type modules to define lift functions // There is a potential for type modules to define lift functions
@ -38,6 +45,17 @@ module FooFFI = {
| [IEvNumber(a), IEvNumber(b)] => FooImplementation.makeBar(a, b, environment)->IEvString->Some | [IEvNumber(a), IEvNumber(b)] => FooImplementation.makeBar(a, b, environment)->IEvString->Some
| _ => None | _ => None
} }
let makeReturningError: ExpressionT.optionFfiFnReturningResult = (
args: array<InternalExpressionValue.t>,
environment,
) =>
switch args {
| [IEvNumber(a), IEvNumber(b)] =>
FooImplementation.makeReturningError(a, b, environment)
->Belt.Result.map(v => v->InternalExpressionValue.IEvNumber)
->Some
| _ => None
}
} }
let fooModule: Module.t = let fooModule: Module.t =
@ -47,6 +65,7 @@ let fooModule: Module.t =
->Module.defineBool("fooBool", FooImplementation.fooBool) ->Module.defineBool("fooBool", FooImplementation.fooBool)
->Module.defineFunction("makeFoo", FooFFI.makeFoo) ->Module.defineFunction("makeFoo", FooFFI.makeFoo)
->Module.defineFunction("makeBar", FooFFI.makeBar) ->Module.defineFunction("makeBar", FooFFI.makeBar)
->Module.defineFunctionReturningResult("makeReturningError", FooFFI.makeReturningError)
let makeBindings = (prevBindings: Bindings.t): Bindings.t => let makeBindings = (prevBindings: Bindings.t): Bindings.t =>
prevBindings->Module.defineModule("Foo", fooModule) prevBindings->Module.defineModule("Foo", fooModule)

View File

@ -72,6 +72,10 @@ type ffiFn = (
) => result<internalExpressionValue, Reducer_ErrorValue.errorValue> ) => result<internalExpressionValue, Reducer_ErrorValue.errorValue>
type optionFfiFn = (array<internalExpressionValue>, environment) => option<internalExpressionValue> type optionFfiFn = (array<internalExpressionValue>, environment) => option<internalExpressionValue>
type optionFfiFnReturningResult = (
array<internalExpressionValue>,
environment,
) => option<result<internalExpressionValue, Reducer_ErrorValue.errorValue>>
type expressionOrFFI = type expressionOrFFI =
| NotFFI(expression) | NotFFI(expression)

View File

@ -126,6 +126,17 @@ let functionNotFoundErrorFFIFn = (functionName: string): ExpressionT.ffiFn => {
} }
} }
let convertOptionToFfiFnReturningResult = (
myFunctionName: string,
myFunction: ExpressionT.optionFfiFnReturningResult,
): ExpressionT.ffiFn => {
(args: array<InternalExpressionValue.t>, environment) => {
myFunction(args, environment)->Belt.Option.getWithDefault(
functionNotFoundErrorFFIFn(myFunctionName)(args, environment),
)
}
}
let convertOptionToFfiFn = ( let convertOptionToFfiFn = (
myFunctionName: string, myFunctionName: string,
myFunction: ExpressionT.optionFfiFn, myFunction: ExpressionT.optionFfiFn,
@ -159,4 +170,15 @@ let defineFunction = (nameSpace: t, identifier: string, value: ExpressionT.optio
nameSpace->define(identifier, convertOptionToFfiFn(identifier, value)->eLambdaFFIValue) nameSpace->define(identifier, convertOptionToFfiFn(identifier, value)->eLambdaFFIValue)
} }
let emptyStdLib: t = emptyModule->defineBool("stdlib", true) let defineFunctionReturningResult = (
nameSpace: t,
identifier: string,
value: ExpressionT.optionFfiFnReturningResult,
): t => {
nameSpace->define(
identifier,
convertOptionToFfiFnReturningResult(identifier, value)->eLambdaFFIValue,
)
}
let emptyStdLib: t = emptyModule->defineBool("_standardLibrary", true)