Haskell 检查是否只有元素满足给定条件

Haskell Check if only element satisfies a given condition

我正在做一个作业,检查是否只有一个元素满足给定条件,我想过传递 map 来获取布尔值列表,然后计算它是否具有值 1,如果它我 return 是吗,如果不是,那么我 return 是假的。

single :: (a -> Bool) -> [a] -> Bool
single p [] = False
single p a = map p a
let c = single p a
single count True c = if k == 1
    then True 
    else False

我算的是:

count :: (Num a, Eq b) => b -> [b] -> a
count _ [] = 0
count x list = sum $ map (const 1) $ filter (== x) list

您的解决方案包含一些错误。例如 single 的第二个参数是一个列表,所以 single count True c 没有意义。您可以使用:

single :: (a -> Bool) -> [a] -> Bool
single p a = count True (map p a) == 1

但效率不高。 filter p a会产生一个和filter (== True) (map p a)一样长的列表,不需要先映射再过滤。此外,通过计算满足条件的项数,您将枚举 整个列表 ,即使您已经找到两个匹配的项,因此您知道它不能再包含恰好有一项匹配。

您可以使用 filter 并在列表上仅包含一项进行模式匹配,并让此 return True 用于其他两种情况(空列表和包含两个或更多项目的列表),我们 return False,因此:

single :: (a -> Bool) -> [a] -> Bool
single p a = case filter p a of
    [_] -> True
    _ -> False

如果它能找到两个满足给定条件的项目,这将防止枚举整个列表。