[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