我正在尝试使用elem函数将列表的每个元素与另一个列表进行比较。到目前为止我已经
了compin:: (Eq a) => [a] -> [a] -> Bool
compin (x:xs) ys = elem x ys
这似乎只将函数应用于第一个列表的第一个元素。如何将第一个列表的每个元素与第二个列表的整个元素进行比较?
答案 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
但是,使用map
和foldr
:
-- 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
已经定义了all
和Prelude
函数。这将检查每个x
是否在ys
中。如果您想检查x
中是否有ys
,请将&&
替换为||, replace
和with
或, 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
简单易行。