[Haskell-beginners] Pattern match(es) are overlapped ... but I do not see that they do

Edward Z. Yang ezyang at MIT.EDU
Sun Sep 1 05:07:59 CEST 2013


Well, the trouble is at the source language level there
is no way to tell if some_var is /actually/ a constant, or
some complicated expression.  So you could do guards:

    case res of
      _ | res == wxID_CANCEL -> True
        | res == wxID_NO -> False
        | ...

The suggestion to use an ADT is, you write a helper fucntion
which does this case-split first, and then you do regular pattern
matching on the result.  If you need to do this multiple times,
it saves you a bunch of typing; it also gives you one place
to write the error code when the integer is not one of these
three values.

Another mechanism is to define a map (e.g. Data.Map or Data.IntMap)
mapping integers to the appropriate values, and then do a table lookup.

Edward

Excerpts from Nathan Hüsken's message of Sat Aug 31 16:50:03 -0700 2013:
> Hey,
> 
> Thanks for the reply. Ah, yes of course. I see the problem.
> 
> How exactly would you do the encoding into an ADT?
> What I also could do is used nested ifs ...
> 
> Is there no easy, compact way to switch over a set of ints in haskell, 
> that are defined in variables?
> 
> Best Regards,
> Nathan
> 
> On 09/01/2013 01:12 AM, Edward Z. Yang wrote:
> > Hello Nathan,
> >
> > The problem is that because these "numbers" are actually
> > variable names, Haskell is not pattern matching against the
> > number; it is actually binding the result type to the variable.
> > You might as well have written:
> >
> >>       case res of
> >>         x -> return False
> >>         x -> return True
> >>         x -> do
> > which of course is overlapping.
> >
> > There are a few ways to rewrite your program, but my recommendation
> > would be to define an abstract data type which encodes the three
> > choices, and pattern match against that.
> >
> > Edward
> >
> > Excerpts from Nathan Hüsken's message of Sat Aug 31 15:46:01 -0700 2013:
> >> Hey,
> >>
> >> I have the following code (which uses wxHaskell):
> >>
> >> import Graphics.UI.WX
> >> import Graphics.UI.WX.Controls
> >> import Graphics.UI.WXCore
> >> import Graphics.UI.WXCore.Events
> >>
> >> (...)
> >>
> >> dealWithUnsavedChanges :: Var ProgramState -> TextCtrl a -> IO Bool
> >> dealWithUnsavedChanges state tc = do
> >>     ProgramState unsavedChanges _ <- varGet state
> >>     if not unsavedChanges then return True else do
> >>       res <- messageDialog tc "Unsaved changes ..." "You have unsaved
> >> changes, do you want to save them?" (wxYES_NO .+. wxCANCEL .+.
> >> wxICON_EXCLAMATION)
> >>       case res of
> >>         wxID_CANCEL -> return False
> >>         wxID_NO     -> return True
> >>         wxID_YES    -> do
> >>           onSave state tc
> >>           -- check if saving worked
> >>           ProgramState newUnsavedChanges _ <- varGet state
> >>           return (not newUnsavedChanges)
> >>
> >> When I compile it, I get:
> >>
> >> Main.hs:130:5: Warning:
> >>       Pattern match(es) are overlapped
> >>       In a case alternative:
> >>           wxID_NO -> ...
> >>           wxID_YES -> ...
> >>
> >> which is strange. I checked, wxID_NO is defined as 5104 and wxID_YES as
> >> 5103. So they are not overlapping. On the other hand, when I replace the
> >> wxID_NO/YES/CANCEL with the actual values, the warning vanishes.
> >>
> >> Any Idea what this could be?
> >>
> >> Thanks!
> >> Nathan
> >>




More information about the Beginners mailing list