Reputation: 419
I am stuck with the following problem:
Question 1 - Generic currying Create a protocol named
Worker
containing a function calledperform
, which takes in a function and returns a function;perform
must have a default implementation. The function passed as a parameter should be namedwork
, and takes as an argument an instance of the type conforming to the protocol and returns a generic type T. The output function is () -> 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
}
}
The result of this should be something like this:
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
I am thinking that I have to return the execution of the work function passed as the parameter to my protocol function perform.
Am I thinking right? If I am, how could I do that?
I have already read about currying and generics, but I still can't figure this out.
EDIT 1:
I fixed the part about the default implementation, but I still can't figure it out how to return that closure.
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 {}
}
}
I went back to my textbook and they give me the following example about currying a function:
func curry<A, B, C>(_ f: @escaping (A, B) -> C) -> (A) -> (B) -> C {
return { x in { y in f(x, y) } }
}
So in my mind the return of my function should be:
Like this:
return {() in {x in work(x)}}
The compiler gives me the following error:
Cannot convert return expression of type '() -> (A) -> T' to return type '() -> T'
I can't understand why that happens because the inner closure
{x in work(x)}
in my mind should return an value of type T, since it is the execution of the function work, but instead it returns an (A) -> T.
What am I missing?
Upvotes: 0
Views: 263
Reputation: 1
and the perform method should be called like this:
person.perform(work: { p in "\(p.name) is working"})
Upvotes: 0
Reputation: 385960
The function passed as a parameter should be named
work
, and takes as an argument an instance of the type conforming to the protocol
Swift makes “the type conforming to the protocol” available as Self
. So work
's argument should be Self
, not A
. You don't need the A
type at all.
protocol Worker {
func perform<T>(work: @escaping (Self) -> T) -> () -> T
}
Given that signature, how can we write a default implementation?
T
.T
by calling work
.Self
to work
.Self
available is self
.So this is the only reasonable default implementation:
extension Worker {
func perform<T>(work: @escaping (Self) -> T) -> () -> T {
return { work(self) }
}
}
Upvotes: 1