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?
 
    