Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: (a -> Result x b) -> List a -> Result (List x) (List b) #178

Open
adamyakes opened this issue Jan 13, 2024 · 1 comment
Open

Comments

@adamyakes
Copy link

adamyakes commented Jan 13, 2024

I've found myself writing this function a couple times. It's a map that collects all failures. If every call to f returns Ok, the result is Ok (List b), but if one or more fail, the result is Err (List x). The implementation is straightforward, but I'm not sold on a name

collectResults : (a -> Result x b) -> List a -> Result (List x) (List b)
collectResults f =
    let
        folder a res =
            case (f a, res) of
                (Ok b, Ok bs) ->
                    Ok (b :: bs) -- Collect more Ok's
                (Ok _, Err xs) ->
                    Err xs -- Ok's are ignored once we hit an error
                (Err x, Ok _) ->
                    Err [x] -- One Err causes the whole thing to Err
                (Err x, Err xs) ->
                    Err (x :: xs) -- Collect more Err's
    in
    List.foldr folder (Ok [])

The function is useful when checking a bunch of input, and only passing the whole thing if all is good, but collecting (multiple) errors to show if any are bad.

@adamyakes
Copy link
Author

If people are interested, I'd be glad to add this in a PR with tests and docs!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant