提问人:toowren 提问时间:9/20/2023 更新时间:9/27/2023 访问量:38
在 Monad 中将 java.util.Function 转换为非 Lambda 表达式 1 示例取自 维基百科
Converting java.util.Function to non-Lambda expression one in Monad example taken from Wikipedia
问:
有一个非常简单的 Monad 示例,用 Java 编写,取自维基百科文章。
import java.util.function.Function;
interface Monad<T> {
<U> Monad<U> bind(Function<T, Monad<U>> f);
}
class Maybe<T> implements Monad<T> {
private final T val;
public Maybe(T val) {
this.val = val;
}
public T getVal() {
return val;
}
@Override
public <U> Monad<U> bind(Function<T, Monad<U>> f) {
if (val == null)
return new Maybe<U>(null);
return f.apply(val);
}
}
public class MonadApp {
public static void main(String[] args) {
Maybe<Integer> x = new Maybe<>(5);
Monad<Integer> y = x
.bind(v -> new Maybe<>(v + 1))
.bind(v -> new Maybe<>(v * 2));
System.out.println( ((Maybe<Integer>)y).getVal() );
}
}
出于学术目的,我正在尝试在没有 lambda 表达式的情况下重写旧的 Java 1.7 版本。
我的代码如下所示
import java.util.function.Function;
class MonadFunction implements Function<T, Monad<U>>{
Monad<U> apply(T val) { return Monad<U>(val + 1); }
}
interface Monad<T> {
<U> Monad<U> bind(Function<T, Monad<U>> f);
}
class Maybe<T> implements Monad<T> {
private final T val;
public Maybe(T val) {
this.val = val;
}
public T getVal() {
return val;
}
@Override
public <U> Monad<U> bind(Function<T, Monad<U>> f) {
if (val == null)
return new Maybe<U>(null);
return f.apply(val);
}
}
public class MonadApp {
public static void main(String[] args) {
Maybe<Integer> x = new Maybe<>(5);
Monad<Integer> y = x.bind(new MonadFunction())
System.out.println( ((Maybe<Integer>)y).getVal() );
}
}
我用
class MonadFunction implements Function<T, Monad<U>>{
Monad<U> apply(T val) { return Monad<U>(val + 1); }
}
但是,脱机和联机编译器都会返回错误和/MonadApp.java:3: error: cannot find symbol class MonadFunction implements Function<T, Monad<U>>{
symbol: class U /MonadApp.java:5: error: cannot find symbol Monad<U> apply(T val) { return Monad<U>(val + 1); }
问题是我做错了什么?
答:
0赞
Tim Moore
9/22/2023
#1
如果您只需要在不使用 lambda 的情况下在 Java 8 中完成这项工作,您还可以创建一个实现以下内容的类:Function
class Adder implements Function<Integer, Monad<Integer>> {
private final int num;
Adder(int num) {
this.num = num;
}
@Override
public Monad<Integer> apply(Integer integer) {
return new Maybe<>(integer + num);
}
}
public class MonadApp {
public static void main(String[] args) {
Maybe<Integer> x = new Maybe<>(5);
Monad<Integer> y = x
.bind(new Adder(1))
.bind(new Adder(2));
System.out.println( ((Maybe<Integer>)y).getVal() );
}
}
在这种情况下,和 的定义保持不变。Monad
Maybe
如果它确实需要与 Java 7 一起使用,则不可用,但您可以轻松地自己定义一个相同的接口:java.util.function.Function
interface Function<T, U> {
U apply(T value);
}
如果您使用此接口而不是 ,这将适用于 Java 7 和 Java 8,甚至适用于 lambda。java.util.function.Function
0赞
jon hanson
9/26/2023
#2
由于以下几个原因,您的方法存在缺陷:
- 您可以在 Java 中实现 monadic 类型,但您无法有效地表达您的类型是 的事实,因为 bind 方法的返回类型需要是 M(M 是实际的 monad 类型),而不是 .由于缺少更高种类的类型,这不可能在 Java 中表达。您也无法捕获 monad 类型需要具有静态方法(有时称为 或 )的事实。
Monad
Monad<U>
pure
return
unit
- 您的类型不是有效的 Java,因为未声明泛型类型参数 T 和 U(类声明应以 )。即使您解决了这个问题,您仍然会遇到上述问题。
MonadFunction
class MonadFunction<T, U>
但是,一旦您抛弃了类型,您就可以很容易地表达您的类,而无需求助于 Lambda 函数:Maybe
Monad
class Maybe<T> {
private final T val;
public Maybe(T val) {
this.val = val;
}
public T getVal() {
return val;
}
public <U> Maybe<U> bind(Function<T, Maybe<U>> f) {
if (val == null)
return new Maybe<U>(null);
else
return f.apply(val);
}
}
public class MonadApp {
public static void main(String[] args) {
Maybe<Integer> x = new Maybe<>(5);
Maybe<String> y = x.bind(new Function<Integer, Maybe<String>>() {
@Override
public Maybe<String> apply(Integer i) {
return i == 0 ? new Maybe<>(null) : new Maybe<>(i.toString());
}
});
System.out.println(y.getVal());
}
}
评论
Function
return Monad<U>(val + 1);
return new Monad<U>(val + 1);
T
MonadFunction
Function
class FunctionWithoutLambda implements Function<String, Integer> { FunctionWithoutLambda() { } Integer apply(String string_) { return string_.length(); } }
MonadFunction
T