如何根据一个谓词比较两个列表的元素并根据另一个谓词进行选择?

时间:2016-10-30 14:59:33

标签: list haskell tuples

我想要实现的是将两个元组列表与((==) `on` fst)进行比较,并从满足此谓词的对中进行比较,选择满足(min `on` snd)的那些

2 个答案:

答案 0 :(得分:2)

我会假设......

  

我想要实现的是将两个元组列表与((==) `on` fst)

进行比较

...意味着将一个列表中的每个对与另一个列表中的对应对进行比较,就像通常的(==)列表一样。

这是一个主要是无点(并且可能略显暴躁)的解决方案,它与原始建议保持一致:

-- Suggestions of sensible names for this are welcome.
yourSelector :: (Eq a, Ord b) => [(a, b)] -> [(a, b)] -> [(a, b)]
yourSelector ps = fmap (minBy' snd)
    . filter (uncurry ((==) `on` fst)) . zip ps
    where
    minBy' f (x, y) = case (compare `on` f) x y of
        LT -> x
        _ -> y
GHCi> yourSelector [(1,2),(3,5),(4,7)] [(1,3),(2,2),(4,9)]
[(1,2),(4,7)]

对于其他写作方式minBy',参见Maximizing according to a function

答案 1 :(得分:1)

要解决一般情况,您可以定义过滤器的修改版本,该模式匹配包含两个谓词的元组,并检查两者是否都满足。

filter' :: ((a->Bool),(a->Bool)) -> [(a,a)] -> [(a,a)]
filter' (pred1,pred2) = foldr f []
 where f = (\x acc -> if pred1 $ fst x then
                                        if pred2 $ snd x then x : acc
                                        else acc
                      else acc
           )

哪个会使用第一个谓词[(1,2),(2,2),(3,3),(3,4)]和第二个谓词odd来评估列表even

>> filter' (odd,even) [(1,2),(2,2),(3,3),(3,4)]
[(1,2),(3,4)]