【发布时间】:2021-04-11 18:56:15
【问题描述】:
我在深度嵌套的异构数据结构中使用Data.Sets,并认为为集合成员创建Prism 会很有帮助。因此:
membership :: (Ord a) => a -> Prism' (Set a) (Set a)
membership a = prism (Set.insert a) g
where g as = if Set.member a as
then Right $ Set.delete a as
else Left as
但是,如果review l 插入一个已经存在于b 中的成员,即,如果l 是a 的成员镜头,则这不符合第一棱镜定律preview l (review l b) ≡ Just b ,而b 是{a},那么review l b 也是{a},而preview l (review l b) 只是空集,而不是第一棱镜定律要求的{a}。
有没有更好的方法来捕捉集合成员?我喜欢能够检查成员资格并有条件地将集合同时分解为匹配和不匹配的部分。此外,有一个光学来做到这一点很有吸引力,因为它捕获了我在代码的其他部分中使用Sets 的所有用例,它使我能够从其余部分中删除我的import Data.Set 语句我的包,这通常表明对我的抽象成功。
【问题讨论】:
-
at/alterF适合你吗?就光学词汇而言,这是对Set的“最佳”描述。 -
特别是请求的分解
a -> Set a -> (Bool, Set a)就是alterF (, False),也应该是flip at (, False)或者\x -> at x %%~ (, False)。 -
谢谢,我忘记了 Sets 可以被视为类似 Map 的容器,因此可以与 At 一起使用。 (虽然,我不确定当 Set 不是 Traversable,甚至是 Functor 时,如何绕过法律
ix k ≡ at k . traverse。)
标签: haskell set haskell-lens lenses