Is it possible to typealias enumeration with changing cases names?

Suppose that you have type Either.

enum Either<Left, Right> {
  case left(Left)
  case right(Right)
  func flatMapLeft() {}
  func flatMapRight() {}
}

I would like to create another type for my domain DomainEither.

enum DomainEither {
  case range(Range<Int>)
  case whole(Bool)
  func flatMapLeft() {}
  func flatMapRight() {}
}

But it is exactly the same Either type except names of cases. I pretty sure that I can't solve it by type aliasing.
But...

typealias DomainEither = Either<Range<Int>, Bool> where Self.left = range, Self.right = whole

// or 

typealias DomainEither = Either<Range<Int>, Bool> where Self.range = .left, Self.whole = .right

No, you can't change the case names of enums.

You can fake it pretty well though:

// Name the type and cases
typealias DomainEither = Either<Range<Int>, Bool>

extension DomainEither {
  static func range(_ x: Range<Int>) -> Self { .left(x) }
  static func whole(_ x: Bool) -> Self { .right(x) }
}

// Enable pattern-matching for raw cases (ignoring associated values)
enum DomainEitherCases { case range, whole }

extension DomainEither {
  static func ~= (lhs: DomainEitherCases, rhs: Self) -> Bool {
    switch (lhs, rhs) {
    case (.range, .left): return true
    case (.whole, .right): return true
    default: return false
    }
  }
}

The main shortcoming is that you still need a default case in a switch that ignores associated values:

let value: DomainEither = .range(0..<5)

switch value {
case .range: print("It's a range!")
case .whole: print("It's a whole!")
default: break
}
Terms of Service

Privacy Policy

Cookie Policy