lolgear
(Dmitry Lobanov)
1
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
nuclearace
(Erik Little)
2
No, you can't change the case names of enums.
Nevin
3
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
}