Reputation: 1937
I am struggling to conceptualise in my head how to create a generic interface or class which functions like so.
functionOne {
return "123"
}
.chainedFunction { string -> Int in
return Int(string) + 456
}
.anotherChain {
[NSNumber($0), String($0)]
}
.lastInTheChain {
print("value 1: \($0[0])")
print("value 2: \($0[1])")
}
so for this to work it is essentially an array of functions that pipe its return value into the next function's parameter list.
assuming each function closure was named after the function it came from i.e
functionOne(_ functionOne:(T) -> T) {}
chainedFunction(_ chainedFunction:(T) -> T) {}
then you would then call them like so to make sure you pass the correct values through.
lastInTheChain(anotherChain(chainedFunction(functionOne())))
The part i struggly mostly with is the Generics part and whether type inference will work or not (this is a secondary concern, would just be nice if it worked)
Im also attempting to use protocols, and generic protocols in swift require the use of thunks here and there which is only compounding my confusion.
So anyone out there a tad more knowledgeable if you would not mind chipping in how i could do this or whether it is doable in the first place i would be most appreciative.
Upvotes: 0
Views: 249
Reputation: 63167
functionOne
needs to return something that has a chainedFunction
instance method, which itself needs to return something that has an anotherChain
instance method, and so on. For this, you need to create a type. I'll call it wrapper because I don't know your use case, but you should name it something more meaningful.
import Foundation
struct Wrapper<T> {
let value: T
// This replaces `function1`
init(_ value: T) { self.value = value }
func chainedFunction<R>(_ transform: (T) -> R) -> Wrapper<R> {
return Wrapper<R>(transform(self.value))
}
func anotherChain<R>(_ transform: (T) -> R) -> Wrapper<R> {
return Wrapper<R>(transform(self.value))
}
func lastInTheChain<R>(_ transform: (T) -> R) -> R {
return transform(self.value)
}
}
Wrapper("123")
.chainedFunction { string -> Int in
return Int(string)! + 456
}
.anotherChain {
[NSNumber(value: $0), String($0)]
}
.lastInTheChain {
print("value 1: \($0[0])")
print("value 2: \($0[1])")
}
Terminology: this Wrapper
type is called a functor
, because it defines a map
method (here called chainedFunction
and anotherChain
, which are equivalent functions in the example). Using map
, a closure which can be used to transform T
to R
(transform) can be used to transform a Wrapper<T>
into a Wrapper<R>
.
Upvotes: 3