I'm trying create a "conversion" Protocol, to which a Dictionary can conform to if its values implement said protocol.
import Foundation
protocol Fooable {
var foo:String { get }
}
extension Double:Fooable {
var foo:String { get { return "number" } }
}
extension Int:Fooable {
var foo:String { get { return "count" } }
}
extension String:Fooable {
var foo:String { get { return "name" } }
}
extension Dictionary:Fooable where Key == String, Value:Fooable {
var foo:String {
get {
var result = "["
self.keys.sorted().forEach { key in
result += key
result += ": "
result += self[key]!.foo
}
result += "]"
return result
}
}
}
["a": 6.28, "b": 42, "c": "boo"].foo
The problem is that the last line is deemed ambiguous:
error: type of expression is ambiguous without more context
["a": 6.28, "b": 42, "c": "boo"].foo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
Is what I'm trying to do even doable? What do I have to change or add to make it work?
UPDATE
Type Erasure seems to be one "solution". So basically, I would need to make something like:
struct AnyFoo<Fooable> { }
At this point, I can now wrap/erase everything in my dictionary literal:
["a": AnyFoo(6.28), "b": AnyFoo(42), "c": AnyFoo("boo")].foo
along with refining the extension of Dictionary to be for Dictionary's where Value is AnyFoo. Is this really any better than just constricting the Dictionary's extension to cases where Value is String instead and just doing:
["a": 6.28.foo, "b": 42.foo, "c": "boo".foo].foo
For a simple "convert" case, I'm not sure what I would gain from using TypeErasure to defer the conversion through a wrapper, vs just converting before dictionary creation. Less actual typing (as in character input) to do the latter. So I haven't really gained any thing.
Unless I'm missing something, for my case, I'll probably just go with downcasts (e.g. as? Fooable
) for container elements, and do something like log errors or something.