【问题标题】:About generic currying in swift关于 swift 中的通用柯里化
【发布时间】:2020-06-11 09:16:53
【问题描述】:

我遇到了以下问题:

问题 1 - 通用柯里化 创建一个名为Worker 的协议,其中包含一个名为perform 的函数,该函数接受一个函数并返回一个函数; perform 必须有一个默认实现。 作为参数传递的函数应该命名为work,并将符合协议的类型的实例作为参数,并返回一个泛型类型T。输出函数为() -> T

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

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

我想对了吗?如果我是,我怎么能这样做?

我已经阅读了关于柯里化和泛型的文章,但我仍然无法弄清楚。

编辑 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 {}
    }
}

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

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 类型的值,因为它是函数工作的执行,而是返回一个 (A) -> T。

我错过了什么?

【问题讨论】:

  • 首先,我将建议您回到教科书寻找作业的答案。问题的关键是“默认实现”您还需要考虑如何返回闭包。
  • @DavidBerry 谢谢,我去看看!
  • @DavidBerry 我用我的发现编辑了我的问题,但我无法弄清楚关于返回闭包的部分。我在问题编辑中解释了我的想法。

标签: swift generics functional-programming currying


【解决方案1】:

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

Swift 将“符合协议的类型”作为Self 提供。所以work 的参数应该是Self,而不是A。你根本不需要A 类型。

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

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

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

所以这是唯一合理的默认实现:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    • 2011-05-26
    • 2016-01-01
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多