Pattern match(es) are overlapped ... but I do not see that they do

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

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

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

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

On 08/31/2013 11:07 PM, Edward Z. Yang wrote:
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.
In a perfect world, these constants would be defined as part of an enumeration type, correct? For example, data WxId = WxIdCancel | WxIdNo | WxIdYes ... deriving (Enum) in which case the original attempt would have succeeded since it would be matching on a constructor. However, unless there are constants defined for 0,1,... this approach won't work automatically -- the derived Enum instance starts at zero and increments by one. The library would have to define a custom Enum instance and it would add a good bit of code.

Hey, I ended up using guards. If I end up needing this at multiple locations, I will introduce an ADT. This was very helpful! Regards, Nathan On 09/01/2013 05:39 AM, Michael Orlitzky wrote:
On 08/31/2013 11:07 PM, Edward Z. Yang wrote:
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.
In a perfect world, these constants would be defined as part of an enumeration type, correct? For example,
data WxId = WxIdCancel | WxIdNo | WxIdYes ... deriving (Enum)
in which case the original attempt would have succeeded since it would be matching on a constructor.
However, unless there are constants defined for 0,1,... this approach won't work automatically -- the derived Enum instance starts at zero and increments by one. The library would have to define a custom Enum instance and it would add a good bit of code.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Sat, Aug 31, 2013 at 11:39:22PM -0400, Michael Orlitzky wrote:
On 08/31/2013 11:07 PM, Edward Z. Yang wrote:
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.
In a perfect world, these constants would be defined as part of an enumeration type, correct? For example,
data WxId = WxIdCancel | WxIdNo | WxIdYes ... deriving (Enum)
in which case the original attempt would have succeeded since it would be matching on a constructor.
However, unless there are constants defined for 0,1,... this approach won't work automatically -- the derived Enum instance starts at zero and increments by one. The library would have to define a custom Enum instance and it would add a good bit of code.
In this case I wouldn't recommend making a custom Enum instance (because the Enum class makes all sorts of assumptions that would be hard to satisfy); I would just make a pair of functions wxIdToCode :: WxId -> Int wxCodeToId :: Int -> Maybe WxId -Brent

On 09/01/2013 04:32 PM, Brent Yorgey wrote:
In a perfect world, these constants would be defined as part of an enumeration type, correct? For example,
data WxId = WxIdCancel | WxIdNo | WxIdYes ... deriving (Enum)
in which case the original attempt would have succeeded since it would be matching on a constructor.
However, unless there are constants defined for 0,1,... this approach won't work automatically -- the derived Enum instance starts at zero and increments by one. The library would have to define a custom Enum instance and it would add a good bit of code.
In this case I wouldn't recommend making a custom Enum instance (because the Enum class makes all sorts of assumptions that would be hard to satisfy); I would just make a pair of functions
wxIdToCode :: WxId -> Int wxCodeToId :: Int -> Maybe WxId
Oh, I wasn't suggesting that the OP do this. I was wondering aloud whether or not there was a reason why wxHaskell doesn't define these constants as a separate data type rather than a series of Ints (maybe there's a good reason).
participants (4)
-
Brent Yorgey
-
Edward Z. Yang
-
Michael Orlitzky
-
Nathan Hüsken