How about this?

func withPredicateErrors<Element, Return>(
    _ predicate: @escaping (Element) throws -> Bool,
    do body: ((Element) -> Bool) -> Return
    ) rethrows
    -> Return
{
    var caught: Error?
    var element: Element?
    
    let value = body { elem in
        element = elem
        do {
            return try predicate(elem)
        }
        catch {
            caught = error
            return true     // Terminate search
        }
    }
    
    if let _ = caught,
        let element = element {
        try _ = predicate(element)
    }

    return value
}

-Kenny


> On Dec 30, 2017, at 8:15 PM, Brent Royal-Gordon via swift-users 
> <swift-users@swift.org> wrote:
> 
> I need to do something like this:
> 
>       func withPredicateErrors<Element, Return>(_ predicate: (Element) throws 
> -> Bool, do body: ((Element) -> Bool) -> Return) rethrows -> Return {
>         var caught: Error?
>         let value = body { elem in 
>           do {
>             return try predicate(elem)
>           }
>           catch {
>             caught = error
>             return true     // Terminate search
>           }
>         }
>         
>         if let caught = caught {
>           throw caught
>         }
>         else {
>           return value
>         }
>       }
> 
> The problem is, the Swift compiler doesn't allow the explicit `throw` 
> statement; even though it can only throw errors originally thrown by 
> `predicate`, the compiler is not smart enough to prove that to itself. I 
> cannot make `body` a `throws` function.
> 
> Is there any way to do this? Either to override the compiler's safety check, 
> or to rewrite this function to avoid it?
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to