使用 Java 登录函数式编程

Nar*_*hai 5 java monads functional-programming java-8

我是函数式编程的新手,我正在尝试使用 Java 中的 Lambda 功能来尝试执行 FP。我知道 Java 不是学习 Functional 的好选择,但在我的办公室里,我只能使用 Java,并且很想在那里应用其中的一些原则。

我在 Java 中创建了一个 Optional monad 类型的东西,它看起来像这样:

public abstract class Optional<T> implements Monad<T> {
    //unit function
    public static <T> Optional<T> of(T value) {
        return value != null ? new Present<T>(value) : Absent.<T>instance();
    }

    @Override
    public <V> Monad<V> flatMap(Function<T, Monad<V>> function) {
        return isPresent() ? function.apply(get()) : Absent.<V>instance();
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用它来避免null代码中的嵌套检查,我使用它的典型用例是当我需要类似firstNonNull.

用:

String value = Optional.<String>of(null)
                .or(Optional.<String>of(null)) //call it some reference
                .or(Optional.of("Hello"))      //other reference
                .flatMap(s -> {
                    return Optional.of(s.toLowerCase());
                })
                .get();
Run Code Online (Sandbox Code Playgroud)

这是一种魅力。现在的问题是如何将日志记录与此结合起来?如果我需要知道使用了这些参考中的哪一个怎么办?如果这些引用附加了一些语义,并且我需要记录未找到此引用并尝试其他选项,则这很有用。

日志:

some reference is not present and some other business case specific log
Run Code Online (Sandbox Code Playgroud)

这可以用Java实现吗?我试图从网上阅读一些可能的解决方案,并找到Writer了 Haskell 的 monad,但我很困惑,无法理解。

编辑

链接到要点

Pet*_*rey 0

我会使用可变参数方法,它会更容易跟踪并且编写起来更短。

public static <T> Optional<T> of(T... value) {
    for(int i=0;i<values.length;i++) {
        if (value[i] != null) {
            // log that value[i] was chosen
            return new Present<T>(value[i]);
        }
    }
    // log all was null
    return Absent.<T>instance();
}
Run Code Online (Sandbox Code Playgroud)

在你的例子中

String value = Optional.of(null, null, "Hello").get();
Run Code Online (Sandbox Code Playgroud)