0

I need some help converting some Java code to Haskell. I have managed to make a dumbed-down version. The dumbed-down version is as follows:

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

So, for the above, if I do the following example:

Prelude> add (mult 3 2) (sub 2 1)

It will return:

Prelude> 7

I know this works, however I am supposed to convert the following Java code into Haskell, and I know that the code above is not the same as the Java code:

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)))));
    }
}

I am just really lost, even the Java code is confusing me a bit. I really need some help. Any help is greatly appreciated!

Cirdec
  • 24,019
  • 2
  • 50
  • 100
camrymps
  • 327
  • 3
  • 11

1 Answers1

5

The elaborate visitor pattern in the Java code is simulating a sum type with a product and quantification. In Java the quantification takes the form of a generic type. I've written a simpler example (in C#) of using generics to simulate sum types.

In Haskell we don't need to resort to such an elaborate representation and can use a sum type directly

data Expression
     = IntNumber Integer
     | Add      Expression Expression
     | Subtract Expression Expression
     | Multiply Expression Expression
     | Divide   Expression Expression

The Evaluate Visitor <Integer> can be written in Haskell as a simple function with the type 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
Community
  • 1
  • 1
Cirdec
  • 24,019
  • 2
  • 50
  • 100