import haxe.ds.Either;

class Test {
    static function main() {
        trace("Passing an Array<Int>: " + add([10, 20, 30]));
        trace("Passing an Int: " + add(3));
        
        // This will throw a compile time error
        //trace("Passing an Array<String>: " + add(["a", "b", "c"]));
    }
    
    static function add(o:OneOf<Array<Int>, Int>):Array<Int> {
        var a:Array<Int>;
        switch(o) {
            case Left(x): a = x;
          case Right(x): a = [for(i in 0...x) i];
        }
        
        a.push(100);
        a.push(300);
        
        return a;
    }
}

abstract OneOf<A, B>(Either<A, B>) from Either<A, B> to Either<A, B> {
  @:from inline static function fromA<A, B>(a:A):OneOf<A, B> {
    return Left(a);
  }
  @:from inline static function fromB<A, B>(b:B):OneOf<A, B> {
    return Right(b);  
  } 
    
  @:to inline function toA():Null<A> return switch(this) {
    case Left(a): a; 
    default: null;
  }
  @:to inline function toB():Null<B> return switch(this) {
    case Right(b): b;
    default: null;
  }
}