Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Case on a set ignores equality/inequality

Pattern-matching is based on Eq instance, right? I see that Data.Set.Set implements Eq and

>S.fromList [] == S.fromList [1,2]
False
>S.fromList [1,2] == S.fromList [2,1]
True

which is right. Then why does

case S.fromList [1,2] of mempty -> True

return true? (actually it always evaluates to true). I mean such matching is wrong and we should use S.null as a predicate, but anyway: how does it work and comes to True?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Pattern-matching is based on Eq instance, right?

Wrong. In general, pattern matching doesn’t have anything to do with ==. Pattern matching is structural deconstruction. This requires having constructors available. Set is internally defined as

data Set a    = Bin {-# UNPACK #-} !Size !a !(Set a) !(Set a)
              | Tip

so you could write

import Data.Set.Internal (Set(..))

case S.fromList [1,2] of Tip -> True

Notice that the LHS of the pattern is uppercase. This means Tip can’t be a variable, so the thing you’ve experiences where it shadows the existing name mempty can’t happen.

But you’re not supposed to do that. Data.Set does not export the constructors; the implementation is considered too complicated / unstable to be sensible to access for users. Instead you can just do

    if S.null (S.fromList [1,2]) then True
                                 else FLEBLEBLEARG

Arguably, at least for the empty case it would make sense to have the constructor available. You can actually define a usable version of it yourself with -XPatternSynonyms and -XViewPatterns.


The exception are number literals. To match on such a literal, you need to have instances of both Num and Eq, and the pattern match works by first converting the literal to the suitable type and then performing an equality check. Likewise for string literals when -XOverloadedStrings is enabled.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading