1

In Haskell, we can define types with multiple, mutually exclusive value constructors, such as the Maybe type, which is defined as follows:

data Maybe a = Nothing | Just a

where 'a' is any existing type. It'd be nice if we could do something similar in Java. For instance, if we wanted to define an extended real number in Haskell, we could do something like

data ExtendedReal = Infinity | Real Double

In Java, the only way I can think of creating a class with similar functionality is by putting a boolean flag in the class that overrides the double. For instance, we could do

public class ExtendedReal {

    private double real;
    private boolean isInfinity;

    public ExtendedReal() {
        isInfinity = true;
    }

    public ExtendedReal(double real) {
        this.real = real;
    }
    ...
    ...
}

and then check for the flag in all of your methods.

Is there a more canonical way of achieving this?

3
  • What is your endgame here? Commented Jun 19, 2016 at 12:59
  • Double already represents infinity, and better than this (it differentiates positive and negative infinity); you can check for it with Double.isInfinite. Commented Jun 19, 2016 at 13:00
  • @AndyTurner Yes, but this is intended as a more general question than implementing doubles. Commented Jun 19, 2016 at 13:02

3 Answers 3

4

Not sure if this really answers your question, because I'm not familiar with Haskell, and I'm not sure I really understand the question, but "special cases" like this can be designed as a base class with subclasses, and polymorphism:

public abstract class Real {
    public abstract Real plus(double value);

    public static Real infinity() {
        return new Infinity();
    }

    public static Real regular(double value) {
        return new RegularReal(value);
    }

    private static class Infinity extends Real {
        @Override
        public void plus(double value) {
            return this;
        }
    }

    private static class RegularReal extends Real {
        private final double value;

        private RegularReal(double value) {
            this.value = value;
        }

        @Override 
        public Real plus(double value) {
            return new RegularReal(this.value + value);
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

The only big thing missing here is a catamorphism to make up for the absence of pattern matching, which in Java you'd call "the visitor pattern".
0

One possible way to achieve this for immutable classes is to define public static final instances of the class that represent special values. With this approach no new types are introduced.

Comments

0

AFAIK Java 8's Optional is somewhat similar to Haskell's Maybe. Since Java's Optional is implemented using if/else, I guess this is the way to do it in Java. Of course, it is possible to replace that with polymorphism, but the principle remains. For example, Optional's map function is implemented this way:

public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Optional.ofNullable(mapper.apply(value));
    }
}

public boolean isPresent() {
    return value != null;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.