Consider a protocol JSON which represents any valid JSON object. We might define it like so:
protocol JSON { }
extension String: JSON { }
extension Int: JSON { }
... // and so on
extension Array: JSON where Element: JSON { }
extension Dictionary: JSON where Key == String, Value: JSON { }
The above implies that a dictionary of type [String: JSON] itself should be a JSON. Yet, I am unable to use it like below without the following warnings:
// Case 1: Error: Cannot convert value of type 'Int'
// to expected dictionary value type 'String'
let foo: JSON = ["name": "Bob", "age": 25]
// Case 2: Error: Value of protocol type 'JSON'
// cannot conform to 'JSON'; only struct/enum/class
// types can conform to protocols
func foo(_ json: JSON)
let json: [String: JSON] = ["name": "Bob", "age": 25]
foo(json) // error
I have a hunch this has to do with the some P/any P stuff. Can someone tell me why what I'm trying to do is not yet possible?
Edit: this post seems extremely related. I am reading through it.
Value == JSON won't allow me to call JSON.staticMethod(). I'm not actually sure what the difference is between T == P and T: P. Can you elaborate on that for me?
Value == JSON is a same-type constraint, which means Value has to be exactly JSON and Value: JSON is a conformance constraint, which means Value has to be a concrete type that conforms to JSON (there are exceptions to it, like Error which self-conforms). In your dictionary example, Value is inferred to be String so other values need to be String as well. If you change it to Value == JSON, it compiles because you can have different types of values boxed/erased into JSON. It' effectively makes it a heterogenous dictionary, kind of like [String: Any].
I see. Is that similar to the difference between some P and any P?
Why does using == remove my ability to call static methods on P?
Edit: Never mind, I just needed to change dict.mapValues(Value.staticMethod()) to dict.mapValues(staticMethod()) for some reason?
Edit 2: Okay so the above just ended up calling the method I was already in, never mind. I now understand when and why I would use == over :, thank you!