【发布时间】:2018-11-30 17:14:21
【问题描述】:
Philip Wadler 的论文“函数式编程的 Monads”有一个用 Haskell 编写的执行除法的函数 eval 的示例。
这里改编自 Graham Hutton 的“Haskell 编程”:
data Expr = Val Int | Div Expr Expr
eval :: Expr -> Int
eval (Val n) = n
eval (Div x y) = eval x `div` eval y
我的 Java 等价物是:
abstract class IntegerExpression {
abstract Integer evaluate();
}
class Value extends IntegerExpression {
Integer value;
public Value(Integer x) {
value = x;
}
public Integer evaluate() {
return value;
}
}
class DivisionExpression extends IntegerExpression {
IntegerExpression x, y;
public DivisionExpression(IntegerExpression a, IntegerExpression b) {
x = a;
y = b;
}
public Integer evaluate() {
return x.evaluate() / y.evaluate();
}
}
public class DivisionExample {
public static void main(String[] args) {
IntegerExpression two = new Value(2);
IntegerExpression twenty = new DivisionExpression (new Value(100), new Value(5));
IntegerExpression ten = new DivisionExpression(twenty, new Value(2));
IntegerExpression five = new DivisionExpression(new Value(10), two);
IntegerExpression expr = new DivisionExpression(ten, five);
System.out.println(expr.evaluate());
}
}
这看起来不错,但是如何开发此代码以便我可以在 Java 中演示 Try monad(以捕获除零)?
【问题讨论】:
-
为什么不在 Java 代码中使用异常?此外,Haskell 代码实际上并不处理除以零。如果你直接翻译,我不明白你为什么要处理。
-
如果你想发挥作用:java中有一个
Optional类 -
@DánielSomogyi 感谢您的评论让我更好地理解了这里的问题
-
我会使用 Java 接口而不是抽象类。还要知道,理论上,任何代数数据类型(如 Haskell 的
datas)都可以使用“访问者模式”/“指示性编码”/“Church 编码”在 Java 中忠实地表示。像上面那样使用继承很接近,但不一样,因为类是开放的(可以添加新的子类)。此外,必须在所有子类上传播模式匹配有点不方便(访问者模式避免了这种情况)。主要缺点是访问者模式不像上述方法那么简单。
标签: java haskell java-8 functional-programming monads