16 — Advanced
Functions
Functions in rulii are like Actions but they return a value. They support 0 to 10 parameters (via NoArgFunction through DecFunction), and parameter names are matched to bindings automatically, just like conditions and actions.
Creating Functions
import static org.rulii.model.function.Functions.function;
// No parameters
Function<String> greeting = function(() -> "Hello World!");
String result = greeting.apply(Bindings.builder().standard());
// result == "Hello World!"
// With parameters (matched by name to bindings)
Function<String> fullName = function(
(String firstName, String lastName) -> firstName + " " + lastName);
String name = fullName.apply(firstName -> "Alice", lastName -> "Smith");
// name == "Alice Smith"
Parameter Arity
rulii provides typed functional interfaces for 0 through 10 parameters:
NoArgFunction<R>
Zero parameters, returns R
UnaryFunction<A, R>
One parameter, returns R
BiFunction<A, B, R>
Two parameters, returns R
TriFunction ... DecFunction
Three through ten parameters
Use as RuleSet Result Extractor
RuleSet<String> ruleSet = RuleSet.builder()
.with("MyRules")
.rule(/* ... */)
.resultExtractor(function((String name) -> "Result for " + name))
.build();
Function Composition
Functions support composition via compose() and andThen():
compose(f, bindingName)
Apply f first, then this function
andThen(f, bindingName)
Apply this function first, then f
Function<Integer> addOne = function((Integer x) -> x + 1);
Function<Integer> multiplyByTwo = function((Integer value) -> value * 2);
// compose: apply addOne first, then multiplyByTwo
Function<Integer> composed = multiplyByTwo.compose(addOne, "value");
// (5 + 1) * 2 = 12
// andThen: apply multiplyByTwo first, then addOne
Function<Integer> chained = multiplyByTwo.andThen(addOne, "value");
// (5 * 2) + 1 = 11