函数式语言中的GADT是否等同于传统的OOP + 泛型,或者存在这样一种情况,即 GADT 很容易强制执行正确性约束,但使用 Java 或 C# 很难或不可能实现?
例如,这个“类型良好的解释器”Haskell 程序:
data Expr a where
N :: Int -> Expr Int
Suc :: Expr Int -> Expr Int
IsZero :: Expr Int -> Expr Bool
Or :: Expr Bool -> Expr Bool -> Expr Bool
eval :: Expr a -> a
eval (N n) = n
eval (Suc e) = 1 + eval e
eval (IsZero e) = 0 == eval e
eval (Or a b) = eval a || eval b
可以使用泛型和每个子类的适当实现在 Java 中等效地编写,但要冗长得多:
interface Expr<T> {
public <T> T eval();
}
class N extends Expr<Integer> {
private Integer n;
public N(Integer m) {
n = m;
}
@Override public Integer eval() {
return n;
}
}
class Suc extends Expr<Integer> {
private Expr<Integer> prev;
public Suc(Expr<Integer> aprev) {
prev = aprev;
}
@Override public Integer eval() {
return 1 + prev.eval()
}
}
/** And so on ... */