This module contains an API and some tools to implement native functions. Native functions are functions that are not expressed in terms Morphir expressions either because they cannot be or they are more efficient natively. Native in this context means evaluating within Elm which in turn translates to JavaScript which either executes in the browser or on the backend using Node.
Native functions are mainly used in the interpreter for evaluating SDK functions. Think of simple things like adding two
numbers: the IR captures the fact that you want to add them in a reference Morphir.SDK.Basics.add
and the interpreter
finds the native function that actually adds the two numbers (which would be impossible to express in Morphir since it's
a primitive operation).
Eval -> List Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
Type that represents a native function. It's a function that takes two arguments:
One important thing to understand is that the API allows lazy evaluation. Instead of evaluating arguments before they
are passed to the native function they are passed without evaluation. This allows the native function itself to decide
what order to evaluate arguments in. Think of the boolean and
and or
operators, they can often skip evaluation of
the second argument depending on the value of the first argument.
Also, when a lambda is passed as an argument it might need to be evaluated multiple times with different inputs. For
example the predicate in a filter
will need to be evaluated on each item in the list.
Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
Type that captures a function used for evaluation. This will usually backed by the interpreter.
Various utilities to help with implementing native functions.
unaryLazy : (Eval -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue) -> Function
Create a native function that takes exactly one argument. Let the implementor decide when to evaluate the argument.
nativeFunction : Native.Function
nativeFunction =
unaryLazy
(\eval arg ->
eval arg
|> Result.map
(\evaluatedArg ->
-- do something
)
)
unaryStrict : (Eval -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue) -> Function
Create a native function that takes exactly one argument. Evaluate the argument before passing it to the supplied function.
nativeFunction : Native.Function
nativeFunction =
unaryLazy
(\eval evaluatedArg ->
-- do something with evaluatedArg
)
binaryLazy : (Eval -> Morphir.IR.Value.RawValue -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue) -> Function
Create a native function that takes exactly two arguments. Let the implementor decide when to evaluate the arguments.
nativeFunction : Native.Function
nativeFunction =
binaryLazy
(\eval arg1 arg2 ->
eval arg1
|> Result.andThen
(\evaluatedArg1 ->
eval arg2
|> Result.andThen
(\evaluatedArg2 ->
-- do something with evaluatedArg1 and evaluatedArg2
)
)
)
binaryStrict : (Morphir.IR.Value.RawValue -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue) -> Function
Create a native function that takes exactly two arguments. Evaluate both arguments before passing then to the supplied function.
nativeFunction : Native.Function
nativeFunction =
binaryStrict
(\eval evaluatedArg1 evaluatedArg2 ->
-- do something with evaluatedArg1 and evaluatedArg2
)
boolLiteral : Morphir.IR.Literal.Literal -> Result Morphir.Value.Error.Error Basics.Bool
charLiteral : Morphir.IR.Literal.Literal -> Result Morphir.Value.Error.Error Char
eval0 : r -> Encode r -> Function
eval1 : (a -> r) -> Decoder a -> Encode r -> Eval -> List Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
eval2 : (a -> b -> r) -> Decoder a -> Decoder b -> Encode r -> Eval -> List Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
eval3 : (a -> b -> c -> r) -> Decoder a -> Decoder b -> Decoder c -> Encode r -> Eval -> List Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
floatLiteral : Morphir.IR.Literal.Literal -> Result Morphir.Value.Error.Error Basics.Float
intLiteral : Morphir.IR.Literal.Literal -> Result Morphir.Value.Error.Error Basics.Int
oneOf : List Function -> Function
stringLiteral : Morphir.IR.Literal.Literal -> Result Morphir.Value.Error.Error String
decimalLiteral : Morphir.IR.Literal.Literal -> Result Morphir.Value.Error.Error Morphir.SDK.Decimal.Decimal
decodeFun1 : Encode a -> Decoder r -> Eval -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error (a -> Result Morphir.Value.Error.Error r)
decodeList : Decoder a -> Eval -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error (List a)
decodeLiteral : (Morphir.IR.Literal.Literal -> Result Morphir.Value.Error.Error a) -> Eval -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error a
decodeMaybe : Decoder a -> Eval -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error (Maybe a)
decodeLocalDate : Eval -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error Morphir.SDK.LocalDate.LocalDate
decodeRaw : Eval -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
decodeTuple2 : ( Decoder a, Decoder b ) -> Eval -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error ( a, b )
encodeList : Encode a -> List a -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
encodeLiteral : (a -> Morphir.IR.Literal.Literal) -> a -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
encodeMaybe : Encode a -> Maybe a -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
encodeLocalDate : Morphir.SDK.LocalDate.LocalDate -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
encodeMaybeResult : Maybe (Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue) -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
encodeRaw : Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
encodeResultList : List (Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue) -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
encodeTuple2 : ( Encode a, Encode b ) -> ( a, b ) -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
decodeDict : Decoder k -> Decoder v -> Eval -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error (Morphir.SDK.Dict.Dict k v)
decodeFun2 : Encode a -> Encode b -> Decoder r -> Eval -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error (a -> b -> Result Morphir.Value.Error.Error r)
encodeDict : Encode k -> Encode v -> Morphir.SDK.Dict.Dict k v -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue
trinaryLazy : (Eval -> Morphir.IR.Value.RawValue -> Morphir.IR.Value.RawValue -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue) -> Function
trinaryStrict : (Morphir.IR.Value.RawValue -> Morphir.IR.Value.RawValue -> Morphir.IR.Value.RawValue -> Result Morphir.Value.Error.Error Morphir.IR.Value.RawValue) -> Function