关于swift中的通用currying

时间:2018-06-03 16:49:55

标签: swift generics functional-programming

我遇到了以下问题:

  

问题1 - 通用currying   创建一个名为Worker的协议,其默认实现包含一个名为perform的函数,它接收一个函数并返回一个函数。   作为参数传递的函数应该命名为work,并将符合协议的类型的实例作为参数,并返回泛型类型T.输出函数是a() - > Ť

struct Person {
    var name: String
    var age: Int
}

protocol Worker {
    func perform<A,T>(work: @escaping (A) -> (T)) -> () -> T
}

extension  Person: Worker {
    func perform<A, T>(work: @escaping (A) -> (T)) -> () -> T {
        return //execution of the function work
    }
}

结果应该是这样的:

let person = Person(name: "Bob", age: 3)
let work = person.perform(work: {return "\(person.name) is working"})
print(type(of: work)) // () -> String
print(work()) // Bob is working

我想我必须将作为参数传递的工作函数的执行返回给我的协议函数执行。

我在想什么?如果我是,我怎么能这样做?

我已经读过关于currying和generics的内容,但我仍然无法弄清楚这一点。

编辑1:

我修复了关于默认实现的部分,但我仍然无法弄清楚如何返回该闭包。

struct Person: Worker {
    var name: String
    var age: Int
}

protocol Worker {
    func perform<A,T>(work: (A) -> (T)) -> () -> T
}

extension  Worker {
    func perform<A,T>(work: @escaping (A) -> T) -> () -> T {
        return {}
    }
}

我回到了我的教科书,他们给了我以下关于cur a函数的例子:

func curry<A, B, C>(_ f: @escaping (A, B) -> C) -> (A) -> (B) -> C {
    return { x in { y in f(x, y) } }
}

所以在我看来,我的函数的返回应该是:     1.没有参数的闭包()     2.内部有一个闭包,它接收一个传递给工作的参数。

像这样:

return {() in {x in work(x)}}

编译器给出了以下错误:

Cannot convert return expression of type '() -> (A) -> T' to return type '() -> T'

我无法理解为什么会发生这种情况,因为内部封闭

{x in work(x)}
在我看来,

应该返回类型为T的值,因为它是函数work的执行,而是返回一个(A) - &gt;吨。

我错过了什么?

1 个答案:

答案 0 :(得分:1)

作为参数传递的函数应命名为work,并将符合协议类型的实例作为参数

Swift将“符合协议的类型”用作Self。因此,work的参数应该是Self,而不是A。您完全不需要A类型。

protocol Worker {
    func perform<T>(work: @escaping (Self) -> T) -> () -> T
}

鉴于该签名,我们如何编写默认实现?

  • 我们必须返回一个返回T的函数。
  • 我们只能通过致电T来创建work
  • 我们必须将Self传递给work
  • 唯一可用的Selfself

因此,这是唯一合理的默认实现:

extension Worker {
    func perform<T>(work: @escaping (Self) -> T) -> () -> T {
        return { work(self) }
    }
}