Haskell - 检查列表是否包含元素至少 N 次

Haskell - Checking if a list contains an element atleast N times

我正在编写一个函数来检查列表是否包含某个元素至少 N 次

atLeastNtimes :: Eq a => Int -> a -> [a] -> Bool
atLeastNtimes n a l = n <= (sum [1 | x <- l, (x == a)])

有限列表工作正常,但我正在努力使它适用于无限列表,例如:

atLeastNtimes 100 'a' (repeat 'a') 

以下是一些可能的替代方法:

  • 递归定义您的函数,无需检查完整列表,只检查所需的前缀。

  • 首先 filter 编辑列表,以便仅保留要计算的元素。然后,使用 drop (n-1) xs 删除 n-1 个元素(如果有),并检查结果列表是否不为空(使用 null)。请注意 dropping 比列表中更多的元素不是错误,它会导致一个空列表。

我们可以把问题分成两部分。第一个只是检查列表是否足够长。

-- | Check whether the length of a list
-- is at least a certain value.
lengthAtLeast :: Int -> [a] -> Bool
lengthAtLeast n0 xs0 = foldr go stop xs0 n0
  where
    stop n = n <= 0

    go _ _ n | n <= 0 = True
    go _ r n = r (n - 1)

第二个是过滤,filter 为您完成。所以

atLeastNtimes :: Eq a => Int -> a -> [a] -> Bool
atLeastNtimes n a = lengthAtLeast n . filter (a ==)