【问题标题】:Filtering a list of elements by a list of filters通过过滤器列表过滤元素列表
【发布时间】:2023-03-23 00:47:02
【问题描述】:

我在考虑如何实现,以便如果我有一个元素列表 [1, 2, ... n] 和一个过滤器列表(例如 [(>3), (<4), ...]),它将返回通过每个过滤器的元素列表。

尝试了一段时间,到目前为止我得到的是:

filt :: (a -> Bool) -> [a] -> [a]
filt f xs = filter f xs

这个函数应该获取一个过滤器和一个元素列表,并返回通过一个过滤器的元素列表。

然后,

filters :: [a] -> ([a] -> Bool) -> [a]
filters xs ps = (\p -> filt p xs) ps

这不仅给了我错误,而且我也不知道我是否做得正确。 (我试图让过滤器列表的 每个 过滤器成为 filt 函数的参数,以及元素列表。

Haskell 新手,非常感谢你们想给我的任何提示和技巧!

【问题讨论】:

  • 最近的现有技术(带有指向更多现有技术的指针):SO_q64452181

标签: list haskell filtering


【解决方案1】:

一个接一个地链接过滤器,

filters :: [a] -> [a -> Bool] -> [a]
filters xs ps  =  foldr (\p r -> filter p r) xs ps

或者,更短,

filters :: [a] -> [a -> Bool] -> [a]
filters  =  foldr filter

或者我们可以使用foldl' (flip filter),它以从左到右的顺序通过过滤器推送列表。

【讨论】:

    【解决方案2】:

    以及过滤器列表,例如[(>3), (<4), ...]

    签名不正确。这是函数a -> Bool的列表,所以你应该使用:

    filters :: [a] -&gt; <b>[a -&gt; Bool]</b> -&gt; [a]

    但这还不够。你需要把它变成一个过滤器,检查是否满足 all 谓词。我们可以使用all :: Foldable f =&gt; (b -&gt; Bool) -&gt; f b -&gt; Bool。这里all函数的b是函数a -&gt; Bool,因此函数(b -&gt; Bool)的类型是(a -&gt; Bool) -&gt; Bool。我们通过调用该元素上的每个函数来做到这一点:

    filters :: [a] -> [a -> Bool] -> [a]
    filters xs fs = filter (\x -> all ($ x) fs) xs

    我们可以将签名进一步概括为:

    filters :: Foldable f => [a] -> f (a -> Bool) -> [a]
    filters xs fs = filter (\x -> all ($ x) fs) xs

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-28
      相关资源
      最近更新 更多