
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