I have a generic function foo()
which takes an argument p
whose type conforms to Proto
. Proto
and some types conforming to it are defined in another module and can't be changed.
foo()
should dynamically check the type of p
and handle some types in a specific way. Some of the types it should handle are generic themselves but the type parameters again conform to Proto
and thus the nested values could be handled by foo()
again:
protocol Proto {}
struct A: Proto { let value: Int }
struct B<P: Proto>: Proto { let value: P }
func foo<P: Proto>(_ p: P) -> Int {
if let a = p as? A {
return a.value
} else if let b = p as? B<???> {
// If we could cast this to `B<T>` with an unknown T, we could pass it to foo<T>().
return 2 * foo(b.value)
} else {
// Handle unknown types in a generic way.
fatalError()
}
}
print(foo(A(value: 1)))
print(foo(B(value: A(value: 2))))
print(foo(B(value: B(value: A(value: 3)))))
How can I handle values to type B<T>
for an arbitrary T
and call foo()
on the nested value?