Recursive block in Swift
I am trying to convert this block of code from Objective-C (taken from https://gist.github.com/mikeash/1254684 ) to Swift. I have used it successfully to iterate over a block of code based on the results of API calls. Is there a better way to do this in Swift?
dispatch_block_t recursiveBlockVehicle(void (^block)(dispatch_block_t recurse)) {
return ^{
block(recursiveBlockVehicle(block));
};
}
Any help is appreciated.
source to share
Here is a direct translation of your obj-c version:
func recursiveBlockVehicle(block: (()->Void)->Void) -> ()->Void {
return { block(recursiveBlockVehicle(block)) }
}
// test usage
var i = 5
let block = recursiveBlockVehicle { recurse in
if i > 0 {
print("\(i--) ")
recurse()
}
else {
println("blastoff!")
}
}
block() // prints 5 4 3 2 1 blastoff!
(Ive aligned dispatch_block_t
as it is not needed in the Swift version, but you can use it instead ()->Void
if you like)
For the 1 parameter version, you can use generics, not obj-c id
, so it can create one parameter recursive blocks like:
func recursiveBlockVehicle<T>(block: (T, T->Void)->Void) -> T->Void {
return { param in block(param, recursiveBlockVehicle(block)) }
}
let block1: Int->Void = recursiveBlockVehicle { i, recurse in
if i > 0 {
print("\(i) ")
recurse(i-1)
}
else {
println("blastoff!")
}
}
block1(5) // prints 5 4 3 2 1 blastoff!
(and Swift overloading means you don't have to give them different names)
... and if you want your recursive function to return a value:
func recursiveBlockVehicle<T,U>(block: (T, T->U)->U) -> T->U {
return { (param: T)->U in block(param, recursiveBlockVehicle(block)) }
}
let factorial: Int->Int = recursiveBlockVehicle { i, factorial in
return i > 1 ? i*factorial(i-1) : 1
}
factorial(4) // returns 24
Please note that this is the last one thing that you need - because T
, and U
can be Void
, it also serves for the purpose of the non-return of the zero option, although you need to write your circuit to take two arguments (the first of which you can ignore, because itll be invalid ), i.e:
let block: ()->() = recursiveBlockVehicle { _, recurse in
If you like this stuff, you should check out the 2014 WWDC Advanced Swift video , which is an example of an imaginary recursive caller function.
source to share