Java 8 中的 Monadic 函数组合与链接

use*_*195 0 java monads method-chaining function-composition

不知何故,我应该能够指定这样的链,同时值通过每个函数进行管道传输。

a::create -> a::processing -> a::updating -> a:uploading
Run Code Online (Sandbox Code Playgroud)

在以下文章的上下文中,我想将这些方法链接起来,其中一个方法将结果传递给下一个方法,同时修改它。

https://dzone.com/articles/higher-order-functions

https://dzone.com/articles/function-programming-java-8

我的演示将尝试展示我想要的最终结果。它将是通过管道传递给每个方法(如 monad)的单个参数/参数,并且应该更容易在链中指定任意数量的方法。

我一直在用其他语言做这件事,所以试图了解如何在 java 中做这件事。

所有方法都将接收相同类型的参数,并且仅接收一个参数。

等级值

public class Value {
    public String progress = "";
}
Run Code Online (Sandbox Code Playgroud)

类文章

public class Article {

    public void create(Value value) {
        value.progress += "creating ";
    }

    public void processing(Value value) {
        value.progress += "processing ";
    }

    public void updating(Value value) {
        value.progress += "updating ";
    }

    public void uploading(Value value) {
        value.progress += "uploading ";
    }

}
Run Code Online (Sandbox Code Playgroud)

主班

public class Main {

    public static void main(String[] args) {
        Value v = new Value();
        Article a = new Article();

        a.create(v);
        a.processing(v);
        a.updating(v);
        a.uploading(v);
    }
}
Run Code Online (Sandbox Code Playgroud)

建议链接

Ste*_*ner 5

鉴于在函数式编程中不可变状态更可取,我进行了调整Value- 这具有使进度函数更清晰的额外好处。

public class Value {
    public final String progress;

    public Value() {
        this("");
    }

    public Value(final String progress) {
        this.progress = progress;
    }
}
Run Code Online (Sandbox Code Playgroud)

代替方法,Article然后有函数。可以使用 链接这些函数andThen

import java.util.function.Function;

public class Article {

    private final Function<Value, Value> create = v -> new Value(v.progress + "creating ");
    private final Function<Value, Value> processing = v -> new Value(v.progress + "processing ");
    private final Function<Value, Value> updating = v -> new Value(v.progress + "updating ");
    private final Function<Value, Value> uploading = v -> new Value(v.progress + "uploading ");

    public static void main(String[] args) {
        final Article a = new Article();
        final Value v = a.create.andThen(a.processing).andThen(a.updating).andThen(a.uploading).apply(new Value());

        System.out.println(v.progress);
    }
}
Run Code Online (Sandbox Code Playgroud)

System.out.println那么结果就是creating processing updating uploading.

更新

根据您对在方法中创建函数的偏好,您只需更改您的Article实现即可获得类似的内容。请注意,我正在使用您的原始(可变)实现Value

public class Article {

    public Function<Value, Value> create() {
        return v -> {
            v.progress += "creating ";
            return v;
        };
    }

    public Function<Value, Value> processing() {
        return v -> {
            v.progress += "processing ";
            return v;
        };
    }

    public Function<Value, Value> updating() {
        return v -> {
            v.progress += "updating ";
            return v;
        };
    }

    public Function<Value, Value> uploading() {
        return v -> {
            v.progress += "uploading ";
            return v;
        };
    }

    public static void main(String[] args) {
        final Article a = new Article();
        final Value v = a.create()
                         .andThen(a.processing())
                         .andThen(a.updating())
                         .andThen(a.uploading())
                         .apply(new Value());

        System.out.println(v.progress);
    }
}
Run Code Online (Sandbox Code Playgroud)

更新2

已请求静态方法引用,所以就开始吧。我要添加一个附带条件,如果有人向我提供此代码,我会想要一个设计选择的充分理由。

public class Article {

    public static Value create(Value v) {
        v.progress += "creating ";
        return v;
    }

    public static Value processing(Value v) {
        v.progress += "processing ";
        return v;
    }

    public static Value updating(Value v) {
        v.progress += "updating ";
        return v;
    }

    public static Value uploading(Value v) {
        v.progress += "uploading ";
        return v;
    }


    public static void main(String[] args) {
        Optional<Value> maybeValue = Stream.of(new Value())
                                           .map(Article::create)
                                           .map(Article::processing)
                                           .map(Article::updating)
                                           .map(Article::uploading)
                                           .findFirst();

        maybeValue.ifPresent(v -> System.out.println(v.progress));
    }
}
Run Code Online (Sandbox Code Playgroud)