2015-04-07 24 views
0

我需要一些幫助將一些Java代碼轉換爲Haskell。我設法制作了一個虛擬版本。該簡單化下來的版本如下:Java to 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

你在找什麼樣的幫助?你想要有人教你java嗎? – zerkms

回答

5

Java代碼中精心製作的visitor pattern正在模擬帶有產品的sum typequantification。在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 

EvaluateVisitor <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