func useA(_ input: Value<A>) {} is actually not generic over the protocol, but expect the specific type Value<any A>, where any A is the box that contains something that implements A.
The solution is generally to go all-in on generics, and often using some is enough.
I am not entirely sure what you are after, but something like this compiles just fine:
// functions with generic arguments
func useA(_ input: Value<some A>) {}
func useB(_ input: Value<some B>) {}
func useAB(_ input: Value<some A & B>) {}
struct AB: A, B {}
func doSomething() {
// AB is a concrete type, not an existential
let value = Value<AB>()
useA(value)
useB(value)
useAB(value)
}
I'm trying to model GraphQL in a Swift result builder. Consider the following query:
query {
repository(owner: "swiftlang", name: "swift") {
id
name
}
viewer {
id
}
}
To make this work in Swift, I was going to have a type that's constrained to its parent:
struct Field<Parent> { /.../ }
Then create values that are constrained, so only valid queries can be constructed:
// Constraint for all fields of "User" query
protocol User {}
// Constraint for all fields of "Repository" query
protocol Repository {}
// Can be used in both Repository and User builders
let id: Field<Repository & User>
// Can be only be used in the Repository builder
let name: Field<Repository>
But since the generic can't be covariant, this might be the wrong abstraction. The some A & B looks intriguing, though.