2010-09-16 47 views
15

常量我非常喜欢写这样的事:哈斯克尔模式匹配 - 如何使用可变

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

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

调用myFunc myValue2回报True - 不是我的打算。我知道为什么会发生这种情况,但是有没有办法在Haskell中表达这一点,而不诉诸C风格#define声明?

+0

谢谢每个人,非常快速的回应! – Kevin 2010-09-16 18:20:58

回答

22

那么,Haskell并没有统一这样的名字。这些新的'myValue1'和'2'标识符是您绑定的新变量。

最Haskelly的方法是使用强类型和模式匹配:

data Values 
    = D1 
    | D2 

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

给你一个静态保证只有“1”或“2”可以传递给myFunc的,适当的符号匹配,你甚至保留通过派生Enum转换为整数。

+0

谢谢,这似乎是最接近我想要做的 - 我没有想过派生Enum,这将只是票。 – Kevin 2010-09-16 18:20:11

6

如果您不希望创建另一种数据类型,通常的解决办法是使用侍卫:

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

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

你管后放什么可以是任何布尔条件;如果这是真的,则会运行相应的函数体。

12

正如Don解释的那样,您无法与变量值匹配。

但是你可以在这种情况下使用防护:如果这个想法仅仅是定义一些常量时使用的模式

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

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

,您还可以使用语言扩展PatternSynonyms

{-# LANGUAGE PatternSynonyms #-} 

pattern MyValue1 = 1 
pattern MyValue2 = 2 

myFunc :: Int -> Bool 
myFunc MyValue1 = True 
myFunc MyValue2 = False