First, consider why your first example is illegal:
let intHandler: (Int) -> Void = { i in print(i) } var anyHandler: (Any) -> Void = intHandler // error: Cannot convert value of type '(Int) -> Void' to specified type '(Any) -> Void'
An (Any) -> Void is a function that can work with any input; a (Int) -> Void is a function that can only handle input Int . Therefore, it follows that we cannot consider the Int -taking function as a function that can deal with anything because it cannot. What if we call anyHandler with String ?
What about the other way? It is legal:
let anyHandler: (Any) -> Void = { i in print(i) } var intHandler: (Int) -> Void = anyHandler
Why? Since we can consider a function that deals with anything as a function that can deal with Int , because if it can handle anything, by definition it must deal with Int .
So, we have established that we can consider (Any) -> Void as (Int) -> Void . Take a look at your second example:
let intResolver: ((Int) -> Void) -> Void = { f in f(5) } var anyResolver: ((Any) -> Void) -> Void = intResolver
Why can we consider ((Int) -> Void) -> Void as ((Any) -> Void) -> Void ? In other words, why when calling anyResolver can we redirect the argument (Any) -> Void to the parameter (Int) -> Void ? Well, as we have already figured out, we can consider (Any) -> Void as (Int) -> Void , so it is legal.
The same logic applies to your example using ((String) -> Void) -> Void :
let stringResolver: ((String) -> Void) -> Void = { f in f("wth") } var anyResolver: ((Any) -> Void) -> Void = stringResolver
When calling anyResolver we can pass it (Any) -> Void , which is then passed to stringResolver , which accepts (String) -> Void . And a function that can deal with anything is also a function that deals with strings, so it is legal.
Playback using return types:
let intResolver: ((Int) -> Void) -> String = { f in f(5) return "I want to return some string here." } var anyResolver: ((Any) -> Void) -> Any = intResolver
Because intResolver says it returns String , and anyResolver says it returns Any ; Well, the string is Any , so it is legal.