How do you combine filter conditions

后端 未结 4 1483
悲哀的现实
悲哀的现实 2021-02-02 09:42

The filter class of functions takes a condition (a -> Bool) and applies it when filtering.

What is the best way to use a filter on when you have multiple conditions?

4条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-02-02 10:11

    If you have a list of filtering functions of type a -> Bool and want to combine them into one concise filtering function of the same type, we can write functions to do just. Which of the two functions below that you use will depend on the filter behavior you need.

    anyfilt :: [(a -> Bool)] -> (a -> Bool)
    anyfilt fns = \el -> any (\fn -> fn el) fns
    
    allfilt :: [(a -> Bool)] -> (a -> Bool)
    allfilt fns = \el -> all (\fn -> fn el) fns
    

    anyfilt will return true if any of the filter functions return true and false if all of the filter functions return false. allfilt will return true if all of the filter functions return true and false if any of the filter functions return false. Note that you cannot η-reduce either function as the references to fns on the RHS are within anonymous functions.

    Use it like this:

    filterLines :: [String] -> [String]
    filterLines = let
      isComment = isPrefixOf "# "
      isBlank = (==) ""
      badLine = anyfilt([isComment, isBlank])
      in filter (not . badLine)
    
    main = mapM_ putStrLn $ filterLines ["# comment", "", "true line"]
    --> "true line"
    

提交回复
热议问题