Java中的Haskell样式值构造函数

时间:2016-06-19 12:56:46

标签: java haskell

在Haskell中,我们可以使用多个互斥的值构造函数定义类型,例如Maybe类型,它定义如下:

data Maybe a = Nothing | Just a

其中' a'是任何现有的类型。如果我们可以在Java中做类似的事情,那就太好了。例如,如果我们想在Haskell中定义扩展实数,我们可以做类似

的操作
data ExtendedReal = Infinity | Real Double

在Java中,我能想到创建具有类似功能的类的唯一方法是在类中放置一个覆盖double的布尔标志。例如,我们可以做到

public class ExtendedReal {

    private double real;
    private boolean isInfinity;

    public ExtendedReal() {
        isInfinity = true;
    }

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

然后检查所有方法中的标志。

是否有更规范的方法来实现这一目标?

3 个答案:

答案 0 :(得分:4)

不确定这是否真的能回答你的问题,因为我不熟悉Haskell,我不确定我是否真的理解这个问题,但是像这样的“特殊情况”可以被设计为带有子类的基类,和多态:

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

答案 1 :(得分:0)

为不可变类实现此目的的一种可能方法是定义表示特殊值的类的公共静态最终实例。采用这种方法不会引入新的类型。

答案 2 :(得分:0)

AFAIK Java 8的Optionalsomewhat similar to Haskell's Maybe。由于Java的Optional是使用if / else实现的,我想这是在Java中实现它的方法。当然,有可能用多态来代替它,但原则仍然存在。例如,Optional的map函数以这种方式实现:

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