Skip to content

Instantly share code, notes, and snippets.

@EricRabil
Created August 29, 2021 04:11
Show Gist options
  • Save EricRabil/4b3671aac4cf99c22be83c8b91b46b79 to your computer and use it in GitHub Desktop.
Save EricRabil/4b3671aac4cf99c22be83c8b91b46b79 to your computer and use it in GitHub Desktop.
my head hurts
/**
Accepts three functions, where the sole argument of the first two functions is a closure which each accept some ephemeral value and return some value.
The third function accepts two parameters, the first parameter being the parameter of function A, and the second belonging to B. It's combinant value is returned.
- Parameter sourceA: The first function to zip
- Parameter sourceB: The second function to zip
- Parameter combiner: The third function to receive the argument of both A and B
- Returns: The return value
*/
@discardableResult
func withZip<FirstAccessorParameter, SecondAccessorParameter, ReturnValue>(
_ firstAccessor: @escaping ((FirstAccessorParameter) throws -> ReturnValue) throws -> ReturnValue?,
_ secondAccessor: @escaping ((SecondAccessorParameter) throws -> ReturnValue) throws -> ReturnValue,
_ combine: (FirstAccessorParameter, SecondAccessorParameter) throws -> ReturnValue
) throws -> ReturnValue {
// first accessor does not return nil
guard let result = try firstAccessor ({ firstParameter in
// second accessor does
try secondAccessor { secondParameter in
try combine(firstParameter, secondParameter)
}
}) else {
throw CombinantError.firstFailure
}
return result
}
@discardableResult
func withZip<FirstAccessorParameter, SecondAccessorParameter, ReturnValue>(
_ firstAccessor: @escaping ((FirstAccessorParameter) throws -> ReturnValue) throws -> ReturnValue,
_ secondAccessor: @escaping ((SecondAccessorParameter) throws -> ReturnValue) throws -> ReturnValue?,
_ combine: (FirstAccessorParameter, SecondAccessorParameter) throws -> ReturnValue
) throws -> ReturnValue {
// first accessor does not return nil
try firstAccessor { firstParameter in
// second accessor does
guard let secondResult = try secondAccessor ({ secondParameter in
try combine(firstParameter, secondParameter)
}) else {
throw CombinantError.secondFailure
}
return secondResult
}
}
@discardableResult
func withZip<FirstAccessorParameter, SecondAccessorParameter, ReturnValue>(
_ firstAccessor: @escaping ((FirstAccessorParameter) throws -> ReturnValue) throws -> ReturnValue,
_ secondAccessor: @escaping ((SecondAccessorParameter) throws -> ReturnValue) throws -> ReturnValue,
_ combine: (FirstAccessorParameter, SecondAccessorParameter) throws -> ReturnValue
) rethrows -> ReturnValue {
// first accessor does not return nil
try firstAccessor { firstParameter in
// second accessor does
try secondAccessor { secondParameter in
try combine(firstParameter, secondParameter)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment