ios - Swift: Returning a recursive function (currying) -
i wanting return function in turn call itself. possible through returning closure calling itself?
my problem i'm unsure of correct syntax use here, i'm not sure if possible due having cyclic reference (and swift being heavy on compiler type checking)
i currying functions models , presenters not need know datagateway further decoupling code
some background information problem, api expects page number passed itself, not want store state. want function pass model can call next function when needs to.
i know curried function definition looks this:
function (completion: ([example.product], uint) -> void) -> example.task?
look __function_defined_here__
in code samples
original - example code
func fetch(datagateway: datagateway, category: string)(page: uint)(completion: [product] -> void) -> task? { return datagateway.productmap(category, page: page) { products in completion(products.map { $0.build }) } }
idea 1 - return tuple
func fetch(datagateway: datagateway, category: string)(page: uint)(completion: [product] -> void) -> (task?, __function_defined_here__) { return (datagateway.productmap(category, page: page) { products in completion(products.map { $0.build }) }, fetch(datagateway, category: category)(page: page + 1)) }
idea 2 - pass in completion
func fetch(datagateway: datagateway, category: string)(page: uint)(completion: ([product], __function_defined_here__) -> void) -> task? { return datagateway.productmap(category, page: page) { products in completion(products.map { $0.build }, fetch(datagateway, category: category)(page: page + 1)) } }
i ended solving following, create class reference store next function in. pass reference object in completion of asynchronous operation.
extension product { class next { typealias functiontype = (([product], next) -> void) -> task? let fetch: functiontype init(_ fetch: functiontype) { self.fetch = fetch } } func fetch(datagateway: datagateway, incategory category: string)(page: uint)(completion: ([product], next) -> void) -> task? { return datagateway.products(incategory: category, page: page)() { products in completion(products.map { $0.build }, next(fetch(datagateway, incategory: category)(page: page + 1))) } } } let initial = product.fetch(datagateway, incategory: "1")(page: 0)
pass function in data model
data() { [weak self] products, next in self?.data = products self?.setneedsupdate() self?.next = next }
scrolling down bottom of table view triggers above again, using next
function instead of data
Comments
Post a Comment