Standard library needs Either/Result

Originator:GriotSpeak
Number:rdar://21375916 Date Originated:14-Jun-2015 03:08 PM
Status:Open Resolved:
Product:Developer Tools Product Version:Xcode-beta (7A120f)
Classification:Enhancement Reproducible:Always
 
Summary:
Either and Result should be included in the standard library in order to aid better error handling for Swift-only APIs. The error handling syntax added in Swift 2.0 is effective for many general cases but does seem to leave a few scenarios without an optimal solution. Most of these involve wanting to return a value representing the success or failure of an operation which can be used to decide consequent operations. 

While developers can create their own Either/Result types to address this issue, the fact that–without all agreeing on a single source for this type–we would need to convert from one module’s Either to another make this a non starter.

Steps to Reproduce:
See standard lib

Expected Results:


enum Either<L, R> {
    case Left(L)
    case Right(R)

    init(left: L) {
        self = .Left(left)
    }
    init(right: R) {
        self = .Right(right)
    }

    var left:L? {
        if case let .Left(value) = self {
            return value
        } else {
            return nil
        }
    }

    var right:R? {
        if case let .Right(value) = self {
            return value
        } else {
            return nil
        }
    }
}

enum Result<T> {
    case Error(ErrorType)
    case Success(T)

    init(error: ErrorType) {
        self = .Error(error)
    }
    init(right: T) {
        self = .Success(right)
    }

    var error:ErrorType? {
        if case let .Error(value) = self {
            return value
        } else {
            return nil
        }
    }

    var Success:T? {
        if case let .Success(value) = self {
            return value
        } else {
            return nil
        }
    }

    typealias ThrowingClosure = () throws -> T

    init (closure: ThrowingClosure) {
        do {
            let theValue:T = try closure()
            self = .Success(theValue)
        } catch {
            self = .Error(error)
        }
    }
}

enum MyError : ErrorType {
    case One
}

func theOp(input: Int) throws -> Int {
    if input % 3 == 0 {
        return input
    } else {
        throw MyError.One
    }
}

let something = Result<Int> {
    do {
        return try theOp(2)
    }
}

switch something {
case let .Success(value):
    print("success: \(value)")
case let .Error(value):
    print("err: \(value)")
}

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!