function Promise.retry(r,B,...)assert(isCallable(r),"\080\097\114\097\109\101\116\101\114 \035\049 \116\111 \080\114\111\109\105\115\101\046\114\101\116\114\121 \109\117\115\116 \098\101 \097 \102\117\110\099\116\105\111\110")assert(type(B)=="\110\117\109\098\101\114","\080\097\114\097\109\101\116\101\114 \035\050 \116\111 \080\114\111\109\105\115\101\046\114\101\116\114\121 \109\117\115\116 \098\101 \097 \110\117\109\098\101\114")local p,y={...},select("\035",...)return(Promise.resolve(r(...))):catch(function(...)if B>0 then return Promise.retry(r,B-1,unpack(p,1,y))else return Promise.reject(...)end end)end
--[=[
	Repeatedly calls a Promise-returning function up to `times` number of times, until the returned Promise resolves.

	If the amount of retries is exceeded, the function will return the latest rejected Promise.

	```lua
	local function canFail(a, b, c)
		return Promise.new(function(resolve, reject)
			-- do something that can fail

			local failed, thing = doSomethingThatCanFail(a, b, c)

			if failed then
				reject("it failed")
			else
				resolve(thing)
			end
		end)
	end

	local MAX_RETRIES = 10
	local value = Promise.retry(canFail, MAX_RETRIES, "foo", "bar", "baz") -- args to send to canFail
	```

	@since 3.0.0
	@param callback (...: P) -> Promise<T>
	@param times number
	@param ...? P
]=]
function Promise.retry(callback, times, ...)
	assert(isCallable(callback), "Parameter #1 to Promise.retry must be a function")
	assert(type(times) == "number", "Parameter #2 to Promise.retry must be a number")

	local args, length = { ... }, select("#", ...)

	return Promise.resolve(callback(...)):catch(function(...)
		if times > 0 then
			return Promise.retry(callback, times - 1, unpack(args, 1, length))
		else
			return Promise.reject(...)
		end
	end)
end
