// AAA: this is a general case that take a Collection
func foo<C: Collection>(_ a: C) -> C {
print("foo AAA")
return a
}
// bbb: special case for collection of Character's element to return String
func foo<C: Collection>(_ a: C) -> String where C.Element == Character {
print("foo bbb")
return String(a)
}
foo([1, 2, 3]) // calls AAA
foo(["X", "Y", "Z"]) // calls bbb
foo("abc") // calls bbb
// 👆👆👆 is there anyway to force the above two to call AAA instead?
Edit: the reason to want to call the general one when the input is Collection of Character is to get the result in a Collection of Character instead of [String] in case when you need to.
This still call bbb. It make sense as some Collection is still a Collection where Element == Character, which match the constraint of bbb. So I guess adding a func forceGeneral(...) is the only way.
or convert the String to [Character] and use @hborla 's method:
foo("abc".map { $0 }) as [Character]
to avoid any unnecessary conversion, it's best to just provide a func forceGeneral(...)
Edit: oh, sorry, you are right, it's calling "AAA", it's just return the passing in value, so its result is"abc"!