I'm using Java. I built a small library for internal use. The idea is from F" railway oriented programming : developing a pipeline by composing functions
1. The basic block
@FunctionalInterface
public interface FonctionMetier<R, S> {
Result<ListeErreursMetier, S> invoke(R request);
default <U> FonctionMetier<R, U> andThen(FonctionMetier<S, U> after) {
return req -> this.invoke(req).flatMap(r -> after.invoke(r);
}
{
2. Composing
I can compose a small pipeline using this pattern. But when building more complex pipelines I encounter an issue to still have access to the original input without "breaking" the pipeline by invoking the function and re-start another sub-pipeline
Let's say I have these functions :
FonctionMetier<String, Integer> step1 = input -> Result.success(input.length());
FonctionMetier<Integer, Boolean> step2 = length -> Result.success(length > 5);
FonctionMetier<Boolean, String> step3 = isLong ->
Result.success(isLong ? "Long" : "Short");
And I would like to build a pipeline but in the body of the third function still have access to the input of the first function.
Solution 1 : I can have a snowball effect where each step produce an Object that is the input of the next step and defined by all the data required along the pipeline.
Solution 2 : I was think about wrapping the FonctionMetier inside a Reader that need to provide the execution Context. I can't find the tricks to make this possible :/ I don't know if it's possible and I don't know the way to do it or if it's a dead end. I would like to keep the responsabilities separate
The same way I was thinking about adding a contramap operator later to learn it but first things first : the pipeline :D