我如何模拟 Haskell 的“Either a b"?在 Java 中 [英] How can I simulate Haskell's "Either a b" in Java

查看:26
本文介绍了我如何模拟 Haskell 的“Either a b"?在 Java 中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何编写一个类型安全的 Java 方法来返回类 a 的某些内容或类 b 的某些内容?例如:

How can I write a typesafe Java method that returns either something of class a or something of class b? For example:

public ... either(boolean b) {
  if (b) {
    return new Integer(1);
  } else {
    return new String("hi");
  }
}

最干净的方法是什么?

(我唯一想到的是使用异常,这显然很糟糕,因为它滥用了通用语言功能的错误处理机制......

( The only thing that comes to my mind is using exceptions which is obviously bad, as it is abusing a error-handling mechanism for a general language feature ...

public String either(boolean b) throws IntException {
  if (b) {
    return new String("test");
  } else {
    throw new IntException(new Integer(1));
  }
}

)

推荐答案

我模拟代数数据类型的一般公式是:

My general formula for simulating algebraic data types is:

  • 该类型是一个抽象基类,构造函数是它的子类
  • 每个构造函数的数据都在每个子类中定义.(这允许具有不同数据数量的构造函数正常工作.它还消除了维护不变量的需要,例如只有一个变量是非空的或类似的东西).
  • 子类的构造函数用于为每个构造函数构造值.
  • 要解构它,可以使用instanceof来检查构造函数,然后向下转换为适当的类型以获取数据.
  • The type is an abstract base class, and the constructors are subclasses of that
  • The data for each constructor are defined in each subclass. (This allows constructors with different numbers of data to work correctly. It also removes the need to maintain invariants like only one variable is non-null or stuff like that).
  • The constructors of the subclasses serve to construct the value for each constructor.
  • To deconstruct it, one uses instanceof to check the constructor, and downcast to the appropriate type to get the data.

所以对于a b,它会是这样的:

So for Either a b, it would be something like this:

abstract class Either<A, B> { }
class Left<A, B> extends Either<A, B> {
    public A left_value;
    public Left(A a) { left_value = a; }
}
class Right<A, B> extends Either<A, B> {
    public B right_value;
    public Right(B b) { right_value = b; }
}

// to construct it
Either<A, B> foo = new Left<A, B>(some_A_value);
Either<A, B> bar = new Right<A, B>(some_B_value);

// to deconstruct it
if (foo instanceof Left) {
    Left<A, B> foo_left = (Left<A, B>)foo;
    // do stuff with foo_left.a
} else if (foo instanceof Right) {
    Right<A, B> foo_right = (Right<A, B>)foo;
    // do stuff with foo_right.b
}

这篇关于我如何模拟 Haskell 的“Either a b"?在 Java 中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆