
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