ラムダを楽しみながら実験しようとしています。ラムダの構成を可能にするファンクタを作成しました。しかし、合成の手段は線形変換のみを許し、分岐を許さない。他のラムダのラムダを構成するときの分岐
私は、将来的に効果的に不変の状態のデータ構造を持つことを知っています。状態から値を抽出する変換を作成したいと思います。変換を実行するために状態を必要とするか、または必要としない一連のステップを実行する。
この目的のために、私は2つのクラスを作成します。 java.util.function.Function
のように機能するが、andThen
メソッドでBiFunctionをとり、状態パラメータをラムダからラムダに渡すことができる機能的インタフェースです。
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));
}
}
ファンクタは、2つのマッピング関数(状態を利用するもの、としないもの)、及び(再び、と状態なし)変換を確定2つの終端方法を有する、非常に簡単です。
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));
}
}
簡単に(不自然な)例:
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);
誰もが、私は最終消費者の実行時に条件分岐を可能にするProcedureContainer
にbranch
メソッドを実装する方法の任意のアイデアを持っています。私はmap
とterminateBranch
メソッドを持つ新しいBranchProcedureContainer
を作成することによって試みられてきた
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);
:私は、この例の作業になるだろう何かを考えています。この問題は、ブランチだけが実行されるように2つのブランチをマージする方法がわかりません。
新しいクラスの作成や既存のクラスへのメソッドの追加に制限はありません。
このようなご心配はありませんでした。私も本当にこれに興味がありました。少なくとも私は投票できるのです。 – Eugene