What is the Java equivalent of this Haskell function?

  • A+
Category:Languages

Philip Wadler's paper "Monads for functional programming" has an example of a function eval which performs division written in Haskell.

Here it is as adapted in "Programming in Haskell" by Graham Hutton:

data Expr = Val Int | Div Expr Expr  eval :: Expr -> Int eval (Val n) = n eval (Div x y) = eval x `div` eval y 

My Java equivalent of this is:

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

This seems fine but how do I develop this code so that I can demonstrate a Try monad (to catch division by zero) in Java?

 


Edit: a workaround to failures in this kind of cases is the use of the Maybe Monad, and his cousin in Java is the Optional class, where Option.of would be return and flatMap would be bind. On the other hand in Java and others O.O. languages there is a common pattern to use in this kind of cases called composite, basically your data type Expr will be an interface or abstract class, and the type constructors will be the leaves: So, with all of that in mind, a simple example working would be:

import java.util.Optional;  public interface Expr {      public Optional<Integer> eval();  } 

Then the leaves implementing Expr:

import java.util.Optional;  public class Val implements Expr{      Optional<Integer> value;      public Val(int value) {         this.value = Optional.of(value);     }      @Override     public Optional<Integer> eval() {         return value;     } } 

Then the recursive case:

import java.util.Optional;  public class Div implements Expr {      Expr expr1;     Expr expr2;      public Div(Expr expr1, Expr expr2) {         this.expr1 = expr1;         this.expr2 = expr2;     }      @Override     public Optional<Integer> eval() {         return expr1.eval().flatMap(v1 ->                 expr2.eval().flatMap(v2 ->                     (v2 == 0) ? Optional.empty() : Optional.of(v1 / v2)                 )                );     }      public static void main(String[] args) {         Expr iv1 = new Val(6);         Expr iv2 = new Val(3);         Expr iv3 = new Val(2);         Expr iv4 = new Val(0);         Expr div1 = new Div(iv1, iv2);         Expr div2 = new Div(div1, iv3);         Expr div3 = new Div(div2, iv4);          System.out.println(div2.eval());         System.out.println(div3.eval());      } } 

The main function output will be:

Optional[1] Optional.empty 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: