elm-community / list-extra

Convenience functions for working with List.
http://package.elm-lang.org/packages/elm-community/list-extra/latest
MIT License
135 stars 58 forks source link

proposal: Add findMap #131

Closed showell closed 4 years ago

showell commented 4 years ago

The idea is that you have a function to apply to your elements, and you want the first value that satisfies the predicate, and you want to short-circuit as soon as you find a match. The problem with the current API (unless I'm missing something) is that you can only get the index or the element, so you end up having to recalculate your function. Hopefully the code below clarifies a typical use case.

findMap : (a -> b) -> (b -> Bool) -> List a -> Maybe ( a, b )
findMap f pred lst =
    case lst of
        [] ->
            Nothing

        h :: rest ->
            let
                v =
                    f h
            in
            if pred v then
                Just ( h, v )

            else
                findMap f pred rest

getPage : String -> Maybe (List String)
getPage frag =
    findMap
        (\p -> p frag)
        isJust
        [ parser "a", parser "b", parser "c" ]
        |> Maybe.andThen Tuple.second

parser : String -> (String -> Maybe (List String))
parser keyword =
    \s ->
        if s == (keyword ++ "," ++ keyword) then
            Just [ keyword, keyword ]

        else
            Nothing
pzp1997 commented 4 years ago

This seems closely related to #82 and #95, although the type is slightly different. Maybe we can pick up the discussion in #82 to keep things in one place.

As for the example that you included in your issue, I think using Parser.oneOf might lead to a more idiomatic solution (which I now see you mentioned in elm-community/maybe-extra#47).

showell commented 4 years ago

Yeah, this was inspired by Parser.oneOf, for sure. (The reason I don't directly use Parser.oneOf is that sometimes I have non-Parser parsers for routes.)

I'll close this in favoar of #82. Thanks, @pzp1997! (P.S. See you in Philly tonight!)