Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
228 views
in Technique[技术] by (71.8m points)

haskell - Is there an appropriate optic for set membership?

I’m using Data.Sets in deeply-nested heterogeneous data structures, and thought it would be helpful to create a Prism for set membership. Hence:

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

However, this fails the first prism law, preview l (review l b) ≡ Just b, in the case where review l inserts a member that is already present in b, viz., if l is the membership lens for a, and b is {a}, then review l b is also {a}, and preview l (review l b) is just the null set, rather than just {a} as the first prism law requires.

Is there a better optic for capturing set membership? I like being able to check membership and conditionally decompose the set into the matching and non-matching parts simultaneously. Additionally, having an optic to do this is appealing because, since it captures all the use-cases I have for working with Sets in other parts of my code, it enables me to remove my import Data.Set statements from the rest of my package, which often indicates successful abstraction to me.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There is Contains type class with a member:

contains :: Contains m => Index m -> Lens' m Bool

which when specialised to Set is

contains :: Ord a => a -> Lens' (Set a) Bool

It is probably a good exercise to think why it is a lens (and not a prism, as in your attempt).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...