我怎样才能模拟Haskell的“任一个b”在Java中 [英] How can I simulate Haskell's "Either a b" in Java

查看:88
本文介绍了我怎样才能模拟Haskell的“任一个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.

因此对于或者ab ,它会是这样的:

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的“任一个b”在Java中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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