我需要一些帮助将一些Java代码转换为Haskell。我设法做了一个愚蠢的版本。这个愚蠢的版本如下:
add :: Integer -> Integer -> Integer
add a b = a + b
sub :: Integer -> Integer -> Integer
sub a b = a - b
mult :: Integer -> Integer -> Integer
mult a b = a * b
divi :: Integer -> Integer -> Integer
divi a b = a `div` b
因此,对于上述情况,如果我执行以下示例:
Prelude> add (mult 3 2) (sub 2 1)
它将返回:
Prelude> 7
我知道这有效,但我应该将以下Java代码转换为Haskell,并且我知道上面的代码与Java代码不同:
public class Calculator {
static interface Expression { < T > T accept(Visitor < T > v);
}
static class IntNumber implements Expression {
int value;
IntNumber(int value) {
this.value = value;
}@Override
public < T > T accept(Visitor < T > v) {
return v.visit(this);
}
}
static class Multiply implements Expression {
Expression a, b;
Multiply(Expression a, Expression b) {
this.a = a;
this.b = b;
}@Override
public < T > T accept(Visitor < T > v) {
return v.visit(this);
}
}
static class Divide implements Expression {
Expression numerator, denominator;
Divide(Expression numerator, Expression denominator) {
this.numerator = numerator;
this.denominator = denominator;
}@Override
public < T > T accept(Visitor < T > v) {
return v.visit(this);
}
}
static class Add implements Expression {
Expression a, b;
Add(Expression a, Expression b) {
this.a = a;
this.b = b;
}@Override
public < T > T accept(Visitor < T > v) {
return v.visit(this);
}
}
static class Subtract implements Expression {
Expression a, b;
Subtract(Expression a, Expression b) {
this.a = a;
this.b = b;
}@Override
public < T > T accept(Visitor < T > v) {
return v.visit(this);
}
}
static interface Visitor < T > {
public T visit(IntNumber integer);
public T visit(Add add);
public T visit(Subtract subtract);
public T visit(Multiply multiply);
public T visit(Divide divide);
}
static class Evaluate implements Visitor < Integer > {@Override
//this method will be called and return “3”
public Integer visit(IntNumber integer) {
return integer.value;
}@Override
public Integer visit(Add add) {
return add.a.accept(this) + add.b.accept(this);
}@Override
public Integer visit(Subtract subtract) {
return subtract.a.accept(this) - subtract.b.accept(this);
}@Override
public Integer visit(Multiply multiply) {
// “this” means an instance (eval) of Evaluate class
return multiply.a.accept(this) * multiply.b.accept(this);
}@Override
public Integer visit(Divide divide) {
return divide.numerator.accept(this) / divide.denominator.accept(this);
}
}
/**
* @param args
*/
public static void main(String[] args) {
Evaluate eval = new Evaluate();
System.out.println(eval.visit(
new Multiply(
new IntNumber(3),
new Subtract(new IntNumber(10), new IntNumber(5)))));
}
}
我真的迷失了,即使Java代码让我感到困惑。我真的需要一些帮助。任何帮助是极大的赞赏!
答案 0 :(得分:5)
Java代码中精心设计的visitor pattern模拟带有产品的sum type和quantification。在Java中,量化采用通用类型的形式。我写了一个更简单的例子(在C#中)using generics to simulate sum types。
在Haskell中,我们不需要求助于这样精细的表示,并且可以直接使用和类型
data Expression
= IntNumber Integer
| Add Expression Expression
| Subtract Expression Expression
| Multiply Expression Expression
| Divide Expression Expression
Evaluate
Visitor <Integer>
可以在Haskell中编写为类型为Expression -> Integer
的简单函数。
evaluate :: Expression -> Integer
evaluate (IntNumber x) = x
evaluate (Add a b) = evaluate a + evaluate b
evaluate (Subtract a b) = evaluate a - evaluate b
evaluate (Multiply a b) = evaluate a * evaluate b
evaluate (Divide a b) = evaluate a `div` evaluate b