Haskell multifilter

I want to filter the list by predicates from another list. For example:

multifilter :: (a -> a -> Bool) -> [a] -> [a] -> [a]
multifilter _ _ [] = []
multifilter _ [] _ = []
multifilter f (x:xs) ys = (filter (f x) ys) ++ (multifilter f xs ys)

Using for example:

prelude> multifilter (==) [1,2,3] [5,3,2]
[2,3]

Is there a standard way to do this?

+4
source share
5 answers

Note. This answer implements the specification expressed by words and an example in the question, and not the other specified in the implementation multifilter. For the latest opportunity, see gallais' .

Sibi's answer shows how you should do this. In any case, it is instructive to consider how you could write your function using filter. To begin with, we can establish two facts:

  • multifilter filter pred pred. " ", , , .
  • multifilter f xs ys , , xs, " " - ys. , [3,2], [2,3] ( ) .

, :

multifilter :: (a -> a -> Bool) -> [a] -> [a] -> [a]
multifilter f xs ys = filter pred xs
    where
    pred = undefined -- TODO

, , pred. x, pred True, y of ys, f x y . , any:

pred x = any (\y -> f x y) ys

-- Or, with less line noise:
pred x = any (f x) ys

, multifilter ...

multifilter :: (a -> a -> Bool) -> [a] -> [a] -> [a]
multifilter f xs ys = filter pred xs
    where
    pred x = any (f x) ys

-- Or, more compactly:
multifilter :: (a -> a -> Bool) -> [a] -> [a] -> [a]
multifilter f xs ys = filter (\x -> any (f x) ys) xs

... intersectBy, , intersectBy.

+5

intersectBy:

ฮป> :t intersectBy
intersectBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
ฮป> intersectBy (==) [1,2,3] [5,3,2]
[2,3]

hoogle .

+11

:

multifilter rel xs ys = [ x | x <- xs, y <- ys, x `rel` y ]

, :

multifilter p xs ys = [ x | x <- xs, let f = p x, y <- ys, f y ]

,

relate rel xs ys = filter (uncurry rel) $ liftM2 (,) xs ys

( map fst)

+4

, , , , : xs, ys. , multifilter:

multifilter :: (a -> b -> Bool) -> [a] -> [b] -> [b]

, , :

multifilter p xs ys = fmap snd
                    $ filter (uncurry p)
                    $ concatMap (\ x -> fmap (x,) ys) xs

If you don't mind storing the values โ€‹โ€‹in the order in which they are in ys, then you can have an even simpler definition:

multifilter' :: (a -> b -> Bool) -> [a] -> [b] -> [b]
multifilter' p xs = filter (flip any xs . flip p)
+2
source

Just use Hoogle to find out through the signature. (a -> a -> Bool) -> [a] -> [a] -> [a]

https://www.haskell.org/hoogle/?hoogle=%28a+-%3E+a+-%3E+Bool%29+-%3E+%5Ba%5D+-%3E+%5Ba%5D+-%3E+%5Ba% 5D

gives intersectBy:

intersectBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
+1
source

Source: https://habr.com/ru/post/1606199/


All Articles