如何使用elem比较列表中的每个元素?

时间:2014-12-11 20:44:30

标签: haskell pattern-matching

我正在尝试使用elem函数将列表的每个元素与另一个列表进行比较。到目前为止我已经

compin:: (Eq a) => [a] -> [a] -> Bool
compin (x:xs) ys = elem x ys 

这似乎只将函数应用于第一个列表的第一个元素。如何将第一个列表的每个元素与第二个列表的整个元素进行比较?

4 个答案:

答案 0 :(得分:3)

这一切都取决于你想做什么。可能的答案是:

compin (x:xs) ys = elem x ys && compin xs ys   -- ensure every xs is in ys

compin (x:xs) ys = elem x ys || compin xs ys   -- check if at least on xs is in ys

两者都有不同的基本情况 - 当xs为空列表时,你必须决定发生了什么:

compin [] ys = ???

答案 1 :(得分:0)

你会想要使用某种形式的递归。要使用显式递归来执行此操作,您可以执行

compin [] ys = True
compin (x:xs) ys = elem x ys && compin xs ys

但是,使用mapfoldr

可以更简单地完成
--                               v What we do with each element of x
compin xs ys = foldr (&&) True $ map (`elem` ys) xs
--                    ^    ^ Base case for xs == []
--                    | The operation we perform between each iteration

但这也是一种常见的模式:

compin xs ys = and $ map (`elem` ys) xs
-- and xs = foldr (&&) True xs

但这可以再次减少:

compin xs ys = all (`elem` ys) xs
-- all p xs = and $ map p xs

and已经定义了allPrelude函数。这将检查每个x是否在ys中。如果您想检查x中是否有ys,请将&&替换为||, replacewith, and replace所有with } any`。

答案 2 :(得分:0)

您还可以使用Data.List

中的set操作
> a = [1..5]
> b = [2,3]
> b \\ a
[]

空列表表示b中包含a。假设列表元素是唯一的。

答案 3 :(得分:0)

怎么样?

compin xs ys = all (flip elem ys) xs

简单易行。