Yes, but:
// Are these two the same type or not?
// .--'-. .-'--.
func identity<T, U>(_ f: @escaping (T)->U) -> (T)->U {
return f
}
func add(_ a: Int, _ b: Int) -> Int { return a + b }
print(type(of: add)) // Prints (Int, Int) -> Int
print(type(of: identity(add))) // Prints ((Int, Int)) -> Int
print(type(of: add) == type(of: identity(add))) // false
let f: (Int, Int) -> Int = add
var g = identity(f)
// g = add // ERROR: Cannot assign value of type
// '(Int, Int) -> Int' to type '((Int, Int)) -> Int'
// Workaround:
g = { f($0.0, $0.1) }
// Have to call it with double parens like this:
let r = g((1, 2))
print(r) // Prints 3
It will work (same type, no double parentheses etc) if we use add1
instead of add
though:
func add1(_ a: Int) -> Int { return a + 1 }
It looks like (T)->U
and (T)->U
in the definition of identity
are the same type. But they are evidently not always the same.
So how do we write the identity function in Swift?
func identity<T>(_ f: T) -> T {
return f
}
?
I know this is the identity function, but I mean one that takes only function types, and returns the same function type, no matter the number of parameters of that function type.
Maybe overload it for each number of parameters you want to support? No, that will result in Ambiguous use of 'identity'
.