listhaskell

Take elements of a list up to and including the first value that satisfies some predicate in Haskell


Given a predicate p, takeWhile p xs gives you the longest prefix of elements satisfying p. How can I get the shortest prefix containing an element that satisfies p?


Solution

  • break, which splits a list on the first match, seems like a good starting point:

    cutAfter :: (a -> Bool) -> [a] -> Maybe [a]
    cutAfter p xs = case break p xs of
        (start, mid : _) -> Just (start ++ [mid])
        _ -> Nothing
    

    It also seems like a plausible choice to want a list that doesn’t contain a matching element to be taken in its entirety:

    cutAfter :: (a -> Bool) -> [a] -> [a]
    cutAfter p xs =
        let (start, end) = break p xs
        in start ++ take 1 end
    

    This option is nice because it’s more efficient and lazy – no need to find the match before using the list.