1

我有[a]那个可以转换为[b]. 每个a都是不同的,但每个都b可能不是。我想过滤我[a]的条件,即过滤[a]后转换为[b].

有人可以帮助我实现这一目标吗?

编辑

作为帮助,我将提供一个示例。

as = [1..10]
conv = even
bs = map even as
-- bs = [False,True,False,True,False,True,False,True,False,True]
-- filter <cond> as -- [1,2]
4

2 回答 2

9

假设这是从 转换为f的函数。然后,您可以分三个步骤进行:ab

  1. 您将列表中的每个元素与其下的图像配对fmap (id &&& f)
  2. 您删除第二个元素已经出现在现在获得的列表中的每一对nubBy (on (==) snd)
  3. 您删除每对的第二个组件:map fst.

因此:

import Control.Arrow ((&&&))
import Data.Function (on)
import Data.List (nubBy)

filterOn :: Eq b => (a -> b) -> [a] -> [a]
filterOn f = map fst . nubBy ((==) `on` snd) . map (id &&& f)

例如:

> filterOn even [1 .. 10]
[1,2]
于 2012-08-13T10:23:23.753 回答
1

cond :: a -> Bool仅使用函数filter(即使用(filter cond) [1..10]yielding )是不可能做到这一点的[1,2]

问题是只filter查看数组中的每个元素一次,并且您没有关于先前元素的信息。

于 2012-08-13T10:52:38.527 回答