Проверьте, является ли переменная блоком / функцией / вызываемой в Swift

Есть ли в Swift простой и определенный способ проверить, является ли что-то вызываемым блоком / функцией? На некоторых языках это тривиальная вещь, но, возможно, я смотрю на это с неправильной точки зрения в Swift? Учтите следующее.

func foo(){ print("foo") }
var bar: () -> () = { print("bar") }
var baz: () -> (Bool) = { print("baz"); return true }

print(foo) // (Function)
print(bar) // (Function)
print(baz) // (Function)

print(foo is () -> ()) // true
print(bar is () -> ()) // true
print(baz is () -> ()) // false
print(baz is () -> (Bool)) // true

Swift знает, что все они являются функциями, хотя такого типа данных не существует. Я могу проверить, используя надежную подпись, но может возникнуть ситуация, когда мне наплевать на подпись* и просто хочу вызвать его. Например:

func call(callable: () -> ()) {
    callable()
}

call(foo) // foo
call(bar) // bar
call(baz) // error: cannot convert value of type '() -> (Bool)' to expected argument type '() -> ()'

Я могу переписать это так, что будет работать дляVoid а такжеBool возвращать типы, но делать это для каждого типа - это безумие, тем более что мне все равно, но компилятор делает…

func call(callable: Any) {
    if let block: () -> () = callable as? () -> () {
        block()
    } else if let block: () -> (Bool) = callable as? () -> (Bool) {
        block()
    }
}

call(foo) // foo
call(bar) // bar
call(baz) // truely baz

* Согласитесь, наплевать на подпись - это грех. Ради аргумента давайте просто не будем заботиться о типе возвращаемого значения.

Ответы на вопрос(1)

Ваш ответ на вопрос