If we want to find an implementable solution I think we strive for parity with anonymous product types, instead of creating an anonymous sum type with implicit casting (i.e. func h(_: Int | Float); h(1.0) / /choose Float
) and other "fancy" features.
I think this post from John outlines some key considerations:
All in all, I think that a more grounded approach, such as the following could work in current Swift:
Syntax:
// === Declaration-----------------------------------
typealias Content = Int | String
typealias Action = receive: Image | send: Request
// === Access ---------------------------------------
@ViewBuilder
func viewForContent(_ content: Content) -> some View {
switch content {
case .0(let number):
Text("Number: \(number)")
case .1(let numberDescription):
Text(numberDescription)
}
}
func handleTap(for action: Action) {
switch action {
case .receive(let image):
...
case .send(let request):
...
}
}
// === Initialization --------------------------------
viewForContent(.1("The number six"))
viewForContent("The number six") ❌
// Error: Cannot convert 'String' to 'Int | String'
handleTap(for: .send(myRequest))
handleTap(for: .1(myRequest)) ✅
// Okay, matches tuple behavior
// === Unsupported ------------------------------------
let content: Content = ...
let number = content as? Int ❌
content.description ❌
// Note: Although both types conform to 'CustomStringConvertible'
// access to 'description' is invalid.
extension Content { ❌
// Error: Anonymous sum types are not extensible
func printHello() {
print("Hello world!")
}
}