Ich versuche, mit Lambda zum Spaß zu experimentieren. Ich habe einen Funktor erstellt, der die Zusammensetzung eines Lambda ermöglicht. Aber die Mittel zur Komposition erlauben nur eine lineare Transformation und erlauben keine Verzweigung.Verzweigen beim Komponieren von Lambdas von anderen Lambdas
Die Idee ist, dass ich weiß, dass ich in Zukunft eine effektiv unveränderliche Zustandsdatenstruktur haben werde. Ich möchte eine Transformation erstellen, die einen Wert aus dem Zustand extrahiert. und führt eine Reihe von Schritten durch, die den Zustand erfordern können oder nicht, um die Transformation durchzuführen.
Zu diesem Zweck erstelle ich zwei Klassen. Die funktionale Schnittstelle funktioniert wie java.util.function.Function
, nimmt aber eine BiFunction in der andThen
-Methode, die es ermöglicht, den Zustandsparameter von Lambda an Lambda zu übergeben.
import java.util.Objects;
import java.util.function.BiFunction;
@FunctionalInterface
public interface Procedure<S, T> {
T procede(S stateStructure);
default <R> Procedure<S, R> andThen(BiFunction<S, T, R> after) {
Objects.requireNonNull(after);
return (param) -> after.apply(param, procede(param));
}
}
Die Funktors ist recht einfach, zwei Abbildungsfunktionen aufweist (eine, die den Zustand verwendet, und eines, das nicht der Fall ist), und zwei Verfahren zur Einstellung, die die Transformationen (auch hier mit und ohne Zustand), abzuschließen.
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
public class ProcedureContainer<S, T> {
protected final Procedure<S, T> procedure;
protected ProcedureContainer(final Procedure<S, T> procedure) {
this.procedure = procedure;
}
public static <S, R> ProcedureContainer<S, R> initializeContainer(
final Function<S, R> initialDataRetriever) {
return new ProcedureContainer<>(initialDataRetriever::apply);
}
public <R> ProcedureContainer<S, R> map(final BiFunction<S, T, R> mapper) {
return new ProcedureContainer<>(procedure.andThen(mapper));
}
public <R> ProcedureContainer<S, R> map(final Function<T, R> mapper) {
BiFunction<S, T, R> subMapper =
(ignored, stagedData) -> mapper.apply(stagedData);
return new ProcedureContainer<>(procedure.andThen(subMapper));
}
public Consumer<S> terminate(final BiConsumer<S, T> consumer) {
return (param) -> consumer.accept(param, procedure.procede(param));
}
public Consumer<S> terminate(final Consumer<T> consumer) {
return (param) -> consumer.accept(procedure.procede(param));
}
}
Ein kurzes (erfundenes) Beispiel:
StateStruct state = new StateStruct();
state.setJson("{\"data\":\"meow, meow, I'm a cow\"}");
state.setRequestedField("data");
Consumer<StateStruct> consumer = ProcedureContainer
.initializeContainer(SateStruct::getJson)
.map(JSONObject::new)
.map((state, jsonObj) -> jsonObject.getString(state.getRequsetedField()))
.terminate(System.out::singLoudly);
consumer.accept(state);
Hat jemand irgendwelche Ideen, wie ich eine branch
Methode auf den ProcedureContainer
implementieren könnte, die einer bedingte Verzweigung in der Ausführung der Endverbraucher ermöglichen würden, . Ich denke, etwas, das dieses Beispiel Arbeit machen würde:
StateStruct state = new StateStruct();
state.setJson("{\"data\":\"meow, meow, I'm a cow\"}");
state.setRequestedField("data");
state.setDefaultMessage("There is no data... only sheep");
Consumer<StateStruct> consumer = ProcedureContainer
.initializeContainer(SateStruct::getJson)
.map(JSONObject::new)
.branch((state, jsonObj) -> !jsonObject.getString(state.getRequsetedField()))
.terminateBranch((state, json) -> System.out.lament(state.getDefaultMessage()))
.map((state, jsonObj) -> jsonObject.getString(state.getRequsetedField()))
.terminate(System.out::singLoudly);
consumer.accept(state);
ich versucht habe, indem ein neues BranchProcedureContainer
zu schaffen, die eine map
und terminateBranch
Methode hat. Dieses Problem ist, dass ich nicht weiß, wie die zwei Zweige so zusammengeführt werden, dass nur der Zweig ausgeführt wird.
Es gibt keine Einschränkungen beim Erstellen neuer Klassen oder Hinzufügen von Methoden zu vorhandenen Klassen.
so eine Schande, dass Sie hier keine Aufmerksamkeit bekommen haben. Das hat mich auch sehr interessiert. Am wenigsten kann ich wählen. – Eugene