How about something like F#'s active patterns, which are a way of defining custom mutually-exclusive conditions for pattern matching purposes? You could think of them as being "computed cases", a list of mutually exclusive cases whose value is determined by an associated block of code:
struct ErrorCode {
// 0 if success, <0 if failure
var value: Int
// A computed case that lets you pattern match an ErrorCode
case ok, error(code: Int) {
assert(value <= 0)
if value == 0 { return ok }
return error(code: value)
}
}
func handleError(code: ErrorCode) throws {
switch code {
case .ok: return
case .error(let code): throw ErrorCodeError(code)
}
}