Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 如何根据一个谓词比较两个列表的元素,并根据另一个谓词进行选择?_List_Haskell_Tuples - Fatal编程技术网

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

List 如何根据一个谓词比较两个列表的元素,并根据另一个谓词进行选择?,list,haskell,tuples,List,Haskell,Tuples,我试图实现的是比较两个元组列表与(==)on`fst,并从满足此谓词的元组对中,选择满足(min`on`snd)的元组来解决一般情况,您可以定义过滤器的修改版本,该模式匹配包含两个谓词的元组,并检查两者是否都满足 filter' :: ((a->Bool),(a->Bool)) -> [(a,a)] -> [(a,a)] filter' (pred1,pred2) = foldr f [] where f = (\x acc -> if pred1 $ fst x

我试图实现的是比较两个元组列表与
(==)on`fst
,并从满足此谓词的元组对中,选择满足
(min`on`snd)

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

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)]
进行评估,如下所示:

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

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

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)]
进行评估,如下所示:

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

我试图实现的是将两个元组列表与`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
对于编写
minBy'
,cf..

的替代方法,我假设

我试图实现的是将两个元组列表与`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

有关编写
minBy'
的其他方法,请参见。您正在寻找
groupBy
minimumBy
。请查看。您正在寻找
groupBy
minimumBy
。使用
foldl
重建列表,方法是在
(++)
中添加单个元素,而不是使用
foldr
(:)
。此外,没有必要重新实施整个计划。您可以使用类似于
filter'pq=filter(uncurry(&&&).bimap pq)之类的工具重新使用
filter
,这很好。将我的实现更改为使用
foldr
,但您所包含的内容更简洁/更好。您正在使用的
bimap
函数是什么?它位于
数据中。Bifunctor
,可用于将两个不同的函数映射到
的每个组件(a,b)
成对或每种情况下的
或a b
。使用
foldl
重新生成一个列表,方法是在
(++)
中添加单个元素,而不是使用
foldr
(:)
。此外,没有必要重新实施整个计划。您可以使用类似于
filter'pq=filter(uncurry(&&&).bimap pq)之类的工具重新使用
filter
,这很好。将我的实现更改为使用
foldr
,但您所包含的内容更为简洁。您使用的
bimap
函数是什么?它位于
数据中。Bifunctor
,可用于将两个不同的函数映射到
(a,b)
对的每个组件或
的每个案例。