Внутренние фигурные скобки -> in { ... }
быстро сообщает, что эта внутренняя часть является замыканием, тогда как на самом деле она содержит только значение (C
тип оценки f(a,b)
). Если вы удалите эти внутренние фигурные скобки, ваш пример будет работать.
Например, попробуйте
func stdCurry<A,B,C>(f : (A,B) -> C) -> (A) -> (B -> C) {
return { (a:A) -> (B -> C) in {
(b:B) -> C in
return f(a,b) // <-- this is not a closure (just returns a value of type C`
}
}
}
Обратите внимание, что я добавил общие типы, функции подписи выше (возможно, вы действуете является частью класса, и вы получите ваши типы A
, B
и C
оттуда) ,
Чтобы сделать выше более ясной ошибки, рассмотрим это немного более простой пример (принимая закрытие и возвращение его):
/* This is ok */
func myClosure<A,B>(f: (A) -> B) -> (A) -> B {
return {
x in f(x)
}
}
/* Error: return type here is not (A) -> B, but contains
an anonymous closure() -> B */
func myClosure<A,B>(f: (A) -> B) -> (A) -> B {
return {
x in { f (x) }
}
}
/* Ok */
func myClosure<A,B>(f: (A) -> B) -> (A) -> (() -> B) {
return {
x in { f(x) }
}
}
Также отметим, что поскольку Swift знает (выводит) --- из ваша подпись функции --- типы, а также то, что тип/закрытие ожидать взамен на каждый статус in ...
, вы можете опустить тип закрытия ((a:A) -> (B -> C)
), а также ключевое слово return
и сделать ваше выражение более компактным следующим образом:
func stdCurry<A, B, C>(f: (A, B) -> C) -> A -> (B -> C) {
return { a in { b in f(a, b) } }
}
По вашему желанию в комментариях ниже: Вы можете использовать «нескольких операторов» в хвосте, например, используя подход третьего «простого примера» выше, например:
func stdCurry<A,B,C>(f : (A,B) -> C) -> (A) -> (B) ->() -> C {
return { (a:A) -> (B ->() -> C) in {
(b:B) ->() -> C in
return {
// ...
f(a,b)
}
}
}
}
Обратите внимание, что, как функция подпись растет несколько «грязной», это выгодно опустить эти детали в реальном закрытии вашей функции, а именно:
func stdCurry<A,B,C>(f : (A,B) -> C) -> (A) -> (B) ->() -> C {
return { a in {
b in
return {
// ...
f(a,b)
}
}
}
}
это потому, что вы пытаетесь ввести еще один блок этих посторонних скобками цветка после «(Ь: в -> с в» на самом деле вы хотите в этом случае только 2 крышки вложенной, если ввести эти цветистые фигурные скобки , вы закончите с 3 закрытием, а не 2. – Shripada