我正在尝试将一个简单的 Haskell 数据类型和一个函数转换为 OO。 但是我很困惑..
具有以下用于算术计算的Haskell类型:
data Expr = Lit Int |
Add Expr Expr |
deriving Show
--Turn the expr to a nice string
showExpr :: Expr -> String
showExpr (Lit n) = show n
showExpr (Add e1 e2) = "(" ++ showExpr e1 ++ "+" ++ showExpr e2 ++ ")"
现在我正在尝试转换..
public interface Expr {
String showExpr(String n);
}
// Base case
public class Lit implements Expr {
String n;
public Lit(String n) {
this.n = n;
}
@Override
public String ShowExpr() {
return n;
}
}
public class Add implements Expr {
Expr a;
Expr b;
public Add(Expr aExpr, Expr bExpr) {
this.a = aExpr;
this.b = bExpr;
}
public String ShowExpr() {
return "(" + a.ShowExpr() + "+" + b.ShowExpr() + ")";
}
public static void main(String[] args) {
Lit firstLit = new Lit("2");
Lit secLit = new Lit("3");
Add add = new Add(firstLit,secLit);
System.out.println(add.ShowExpr());
}
}
这将导致“(2+3)”,这是正确答案。
但是..我不确定..这是在 OO 中思考和建模的正确方法吗?
Haskell 数据类型不是很好的表示吗?
最佳答案
让我们尽可能地复制代码。
Haskell 数据结构的一些属性如下:
- 它有类型
Expr
和两个构造函数Lit
和Add
- 您不能从“外部”添加或删除构造函数
因此,如果我们希望这些属性在 Java 版本中保持为真,您应该这样做:
public abstract class Expr {
// So that you can't add more subclasses outside this block
private Expr() {}
// Simulate pattern matching:
// (This CAN be done with instanceof, but that's ugly and not OO)
public boolean isLit() {
return false;
}
public boolean isAdd() {
return false;
}
public Lit asLit() {
throw new UnsupportedOperationException("This is not a Lit");
}
public Add asAdd() {
throw new UnsupportedOperationException("This is not an Add");
}
public static class Lit extends Expr {
public final int n;
public Lit(int n) {
this.n = n;
}
@Override
public boolean isLit() {
return true;
}
@Override
public Lit asLit() {
return this;
}
}
public static class Add extends Expr {
public final Expr a, b;
public Lit(Expr a, Expr b) {
this.a = a;
this.b = b;
}
@Override
public boolean isAdd() {
return true;
}
@Override
public Add asAdd() {
return this;
}
}
}
现在,转换showExpr
:
public static String showExpr(final Expr expr) {
if(expr.isLit()) {
return Integer.toString(expr.asLit().n);
} else if(expr.isAdd()) {
return "(" + expr.asAdd().a + "+" + expr.asAdd().b + ")";
}
}
您可以将showExpr
作为Expr
类中的静态方法。我不会使它成为一个实例方法,因为这与 Haskell 版本相去甚远。
关于java - Haskell 数据类型到 Java(OO),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9504641/