一种有趣的看待这件事情的方式是,不把
filter
作为原始概念。有一个名为
Filterable
的Haskell类型类
被恰当地描述为:
类似于Functor
,但它包含Maybe
效应。
严格来说,类Filterable
代表从Kleisli Maybe到Hask的函子。
"从Kleisli Maybe
到Hask的函子"的态射映射由该类的mapMaybe
方法捕获,这确实是同名Data.Maybe
函数的推广:
mapMaybe :: Filterable f => (a -> Maybe b) -> f a -> f b
类别律就是适当的函子律(注意,在Kleisli Maybe中,
Just
和
(<=<)
分别是恒等和复合函数):
mapMaybe Just = id
mapMaybe (g <=< f) = mapMaybe g . mapMaybe f
这个类也可以用catMaybes
来表示...
catMaybes :: Filterable f => f (Maybe a) -> f a
...这与mapMaybe
是可以互相定义的(类似于sequenceA
和traverse
之间的关系)...
catMaybes = mapMaybe id
mapMaybe g = catMaybes . fmap g
...并且相当于Compose f Maybe
和f
之间的自然变换,它们都是Hask函子的一部分。
那么这一切与你的问题有什么关系呢?首先,函子是范畴之间的态射,自然变换是函子之间的态射。因此,在这里可以以比“在Hask中的态射”更有趣的方式谈论态射。你不一定会想要这样做,但无论如何,这是一个现有的观点。
其次,filter
也是Filterable
的一种方法,其默认定义为:
filter :: Filterable f => (a -> Bool) -> f a -> f a
filter p = mapMaybe $ \a -> if p a then Just a else Nothing
或者,使用另一个可爱的组合符号拼写:
filter p = mapMaybe (ensure p)
这间接地使得filter
在这个特定的范畴概念中有了位置。
List
数据结构,并将其概括为Foldable
。然而,我不明白为什么不能将filter
应用于模拟随机抽样的单子上,以仅生成满足某些谓词的样本。这与可折叠数据结构基本没有关系,但它可以很好地适应用于生成复杂随机对象的单子框架中。我不确定Foldable
是从filter
中提取的唯一可能的“本质”。 - Andrey Tyukinsupplies
,可以获取一个列表。在我看来,所有的响应式编程都是另一种情况,你在单子中生成事件列表,然后像处理纯数据一样处理它。这是否让您重新考虑“这与可折叠数据结构基本没有关系”的说法? - Ignat InsarovSupply
看起来有点像一个无限元素流,这又是一种可数无限数据结构,与List
相似。但我也可以过滤掉所有不像Foldable
数据结构的东西。例如,可以明显地通过某个条件cond
来定义集合并对其进行过滤:class Set[X](cond: X => Boolean) { def contains(x: X) = cond(x) ; def filter(p: X => Boolean) = new Set[X](x => cond(x) && p(x)) }
。我不知道这样的内涵Set[X]
如何成为Foldable
。 - Andrey Tyukin过滤
立方体中未包含在球体中的所有元素,而无需调用任何类型的fold
。 - Andrey Tyukin