Skip to content

Instantly share code, notes, and snippets.

@LemonSpike
Last active March 3, 2021 20:58
Show Gist options
  • Save LemonSpike/7dbe87c73dcb521eeac8a8efbda43752 to your computer and use it in GitHub Desktop.
Save LemonSpike/7dbe87c73dcb521eeac8a8efbda43752 to your computer and use it in GitHub Desktop.
Confusing NumericEitherEnum
import Foundation
enum NumericEitherEnum<Left, Right> {
case left(Left)
case right(Right)
var left: Left? {
switch self {
case .left(let left) where left is NumericEitherEnum:
return (left as? NumericEitherEnum)?.left
case .left(let left):
return left
case .right(_):
return self.as(Left.self)
}
}
var right: Right? {
switch self {
case .left(_):
return self.as(Right.self)
case .right(let right) where right is NumericEitherEnum:
return (right as? NumericEitherEnum)?.right
case .right(let right):
return right
}
}
}
extension NumericEitherEnum {
public func `as`(_ type: Left.Type) -> Left? {
guard case let .left(left) = self else { return nil }
return left
}
public func `as`(_ type: Right.Type) -> Right? {
guard case let .right(right) = self else { return nil }
return right
}
public func `as`<L,R>(_ type: L.Type) -> L? where Left == NumericEitherEnum<L,R> {
guard case let .left(left) = self else { return nil }
return left.as(type)
}
public func `as`<L,R>(_ type: R.Type) -> R? where Left == NumericEitherEnum<L,R> {
guard case let .left(left) = self else { return nil }
return left.as(type)
}
public func `as`<L,R>(_ type: L.Type) -> L? where Right == NumericEitherEnum<L,R> {
guard case let .right(right) = self else { return nil }
return right.as(type)
}
public func `as`<L,R>(_ type: R.Type) -> R? where Right == NumericEitherEnum<L,R> {
guard case let .right(right) = self else { return nil }
return right.as(type)
}
}
print(NumericEitherEnum<Int, Float>.left(3).left ?? "failed :(")
print(NumericEitherEnum<Int, Float>.left(3).right ?? "failed :(")
print(NumericEitherEnum<Int, NumericEitherEnum<Int, Float>>.right(.right(3)).right ?? "failed :(")
print(NumericEitherEnum<NumericEitherEnum<Int, Float>, NumericEitherEnum<Int, Float>>.left(.left(3)).left ?? "failed :(")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment