tags:

views:

108

answers:

3

I would ideally like to write something like this:

myValue1 = 1 :: Int
myValue2 = 2 :: Int

myFunc :: Int -> Bool
myFunc myValue1 = True
myFunc myValue2 = False

Calling 'myFunc myValue2' returns True - not what I intend. I know why this happens, but is there a way to express this in Haskell without resorting to C-style '#define' statements?

Thanks in advance.

+10  A: 

Well, Haskell doesn't unify names like this. Those new 'myValue1' and '2' identifiers are new variables you're binding.

The most Haskelly way is to use strong types and pattern matching:

data Values
   = D1
   | D2

myFunc :: Values -> Bool
myFunc D1 = True
myFunc D2 = False

Giving you a static guarantee only "1" or "2" can be passed to myFunc, proper symbolic matching and you even retain conversion to integers by deriving Enum.

Don Stewart
Thanks, this seems to be the closest to what I want to do - I hadn't thought of deriving Enum, which will be just the ticket.
Kevin
+3  A: 

If you don't want to create another data type, the usual solution is to use guards:

myValue1 = 1 :: Int
myValue2 = 2 :: Int

myFunc :: Int -> Bool
myFunc val | val == myValue1 = True
           | val == myValue2 = False

What you put after the pipe can be any boolean condition; if it's true, the corresponding function body will be run.

Antal S-Z
+3  A: 

You cannot match against variable values as Don explained.

But you can use guards in this case:

myValue1 = 1 :: Int
myValue2 = 2 :: Int

myFunc :: Int -> Bool
myFunc x
  | x == myValue1 = True
  | x == myValue2 = False
jetxee