How can I simulate Haskell's “Either a b” in Java

后端 未结 14 2199
梦毁少年i
梦毁少年i 2020-12-07 22:40

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)         


        
相关标签:
14条回答
  • 2020-12-07 23:32

    The suggestions already provided, although feasible, are not complete as they rely on some null references and effectively make "Either" masquerade as a tuple of values. A disjoint sum is obviously one type or the other.

    I'd suggest having a look at the implementation of FunctionalJava's Either as an example.

    0 讨论(0)
  • 2020-12-07 23:32

    The closest I can think of is a wrapper around both values that lets you check which value is set and retrieve it:

    class Either<TLeft, TRight> {
        boolean isLeft;
    
        TLeft left;
        TRight right;
    
        Either(boolean isLeft, TLeft left1, TRight right) {
            isLeft = isLeft;
            left = left;
            this.right = right;
        }
    
        public boolean isLeft() {
            return isLeft;
        }
    
        public TLeft getLeft() {
            if (isLeft()) {
                return left;
            } else {
                throw new RuntimeException();
            }
        }
    
        public TRight getRight() {
            if (!isLeft()) {
                return right;
            } else {
                throw new RuntimeException();
            }
        }
    
        public static <L, R> Either<L, R> newLeft(L left, Class<R> rightType) {
            return new Either<L, R>(true, left, null);
        }
    
        public static <L, R> Either<L, R> newRight(Class<L> leftType, R right) {
            return new Either<L, R>(false, null, right);
        }
    }
    
    class Main {
        public static void main(String[] args) {
            Either<String,Integer> foo;
            foo = getString();
            foo = getInteger();
        }
    
        private static Either<String, Integer> getInteger() {
            return Either.newRight(String.class, 123);
        }
    
        private static Either<String, Integer> getString() {
            return Either.newLeft("abc", Integer.class);
        }   
    }
    
    0 讨论(0)
提交回复
热议问题