I’m changing some Haskell code from using lists to sets. I understand everything required, I think, but I’m not sure how to pattern match on sets. Lists have this nice literal syntax that seems hard to emulate with the Set constructor. For example, I might have some code like this:
foo [] = []
foo x = other_thing
How can I write this code so it uses Sets instead of lists?
Well, you can’t.
Setis an abstract data type[0] that deliberately hides its internal representation, primarily to maintain invariants of the data structure that can’t be statically-enforced by the type system (specifically, the standard libraryData.Set.Setis a binary search tree).Losing the ability to pattern match on an abstract data type is an unpleasant bit of collateral damage, but oh well. Your options are roughly:
null, as in trinithis’s answer.Setto a list. Most of the time this is silly but if you want to iterate through the set anyway, it works well enough.ViewPatternsextension, which provides syntactic sugar for using accessor functions where a pattern match would normally go.Set, treat it like a set, and work with it as a whole for mapping, filtering, etc. Not always possible, but can lead to cleaner code with fewer explicit conditionals/iterations.View patterns would let you write something that looks like this:
…where
setViewis a function you write. Not really much of a gain here, but can be nice for more complex pseudo-patternsFor avoiding explicit checks, besides well-known set operations such as
unionandintersection, consider making use of thefilter,partition,map, andfoldfunctions inData.Set.[0]: See this paper (warning: PDF) for the definition of the term as I’m using it.