containers icon indicating copy to clipboard operation
containers copied to clipboard

Pattern synonyms for simple cases

Open typesanitizer opened this issue 7 years ago • 8 comments

I think it would nice to add patterns for special cases for some containers so you can have neater case statements instead of using ifs with partial functions or similar workarounds (e.g. using findMin).

For sets, it would look something like

{-# LANGUAGE PatternSynonyms #-}

pattern Empty :: Set a
pattern Empty = Tip

pattern Singleton :: a -> Set a
pattern Singleton x = Bin 1 x Tip Tip

Similarly for Map. I'm not sure how you could implement this for IntSet but I think having it for at least Set and Map would be handy. I suppose this can be extended to most other containers (apart from Sequence which already has synonyms).

I'm happy to submit a PR if this feature request is approved :).

typesanitizer avatar Apr 17 '18 22:04 typesanitizer

Feel free to raise the question on the libraries list, but I'm generally not in favor. I don't see any way for this to help avoid partial functions. Here's the basic problem:

f :: Set A -> B
f Empty = ...
f (Singleton x) = ...
f {- uh.... what goes here??? -}

I believe we already have total versions of all the partial functions. So you can write things like

f s
  | Just the_min <- lookupMin s = ...
  | otherwise = ... {- the set was empty -}

g s = case minView s of
  Nothing -> ... {- the set was empty)
  Just (the_min, the_rest) -> ...

It's true that we could add pattern synonyms for "viewing" the set from the left and the right, much like :<| and :|> in Data.Sequence, but whereas these are fundamental for sequences, the left and right views for sets just aren't terribly exciting in general.

If you can find compelling and reasonably common use-cases for pattern synonyms for Set, I'll be happy to add them.

treeowl avatar Apr 17 '18 23:04 treeowl

It's true that we could add pattern synonyms for "viewing" the set from the left and the right, much like :<| and :|> in Data.Sequence, but whereas these are fundamental for sequences, the left and right views for sets just aren't terribly exciting in general.

This isn't what I'm suggesting. Of course, if this is something of interest, then that can be a separate feature request. As you rightly point out, the sequential-ness of the match doesn't make much sense for sets.

If you can find compelling and reasonably common use-cases for pattern synonyms for Set, I'll be happy to add them.

The reason I ran into this just now was in working with lattices -- it would be handy to have a Singleton pattern there as what I'm trying to check is whether a variable can take one value at a point in a data-flow analysis or more than one. I maintain the invariant that the IntSet is non-empty, so having the Empty pattern would be helpful too for throwing an error. I suppose this would apply more generally to any situation where you are using a Set to represent possible values and would like to do something different for the cases in which you have a many possibilities/a unique possibility/no possibilities.

Earlier, I was modelling equivalence classes as Map k (Set v) where I missed the Singleton for Map and Set.

While the lookupMin solution certainly works for distinguishing between empty and non-empty, in my opinion, it doesn't reflect Set's semantics appropriately.

Maybe these don't count as common use cases, so give me some time to think if I can come up with something better :). I will post it on the mailing list for feedback if I hit on something more common.

typesanitizer avatar Apr 18 '18 04:04 typesanitizer

I think before we get into pattern synonyms we should look into functions to do what you want. Indeed, because containers aims to be portable, we would never export a pattern synonym to do something unless we also export a function to do so. I suggest you get to work thinking about how to name the function that checks whether a Set, Map, IntSet, or IntMap is a singleton, and if so returns the key (and value).

treeowl avatar Apr 18 '18 05:04 treeowl

By the way, for whatever it's worth, I'm actually playing with something right now that needs a function to check whether a Map or IntMap is a singleton, and return the only entry if so. In particular, I'm trying to add leaf compression to generic-tries, and a singleton check shows up in deletion and various withering operations.

treeowl avatar Apr 18 '18 05:04 treeowl

After thinking about it a bit more, I think it that while having this feature would be a bit nice, it can be emulated using other means if a user wants to do so. So I'm closing the issue.

typesanitizer avatar Jul 22 '18 14:07 typesanitizer

I've found myself in several situations where pattern synonyms for minView and maxView would mildly improve the readability of my code. Of course, these could only be used for pattern matching and not for construction.

andrewthad avatar Oct 11 '18 14:10 andrewthad

I'm not really opposed to Empty, MinView, and MaxView patterns if there's a real application. Perhaps write a libraries list proposal?

treeowl avatar Oct 11 '18 14:10 treeowl

Hi, I'm a fairly new to Haskell (learning for 4 months) and today I intuitively reached for the (Empty) pattern for Sets, before finding out it didn't exist - would like to see this feature!

image ^this is where I would use it.

tupoiu avatar Jan 26 '24 22:01 tupoiu