2014-05-20 55 views
5

只要盯着Haskell。我想定义一些元素来轻松创建它们之间的态射。模式匹配变量的值

a = "foo" 
b = "bar" 

g a = a --Problem is here 
g b = a --Problem is here 

编辑的问题是,Haskell的治疗的“a”“克”作为变量,但我真正想要的“a”如上定义的值。从概念上讲,希望这个

g (valueOf a) = a --Problem is here 
g (valueOf b) = a --Problem is here 

valueOf是一个神奇的功能,这将使我

g "foo" = a 
g "bar" = a 
+0

g是无标识,因为:g b = a –

回答

7

使用

a = "foo" 
b = "bar" 

g x | x==a = a 
    | x==b = a 

g "foo" = a 
g "bar" = a 

当使用变量作为

g a = ... 

可变a你模式匹配是一个局部变量,绑定到函数的自变量。即使全球已定义a,上面的代码也不会使用全局a的值执行比较。

这种语义允许本地推理你的代码。只要看一眼上面的定义可以看出,f 2 34

f 2 x = 4 
f c d = 0 

:考虑下面的代码作为例子。

x = 5 

f 2 x = 4 
f c d = 0 

如果匹配语义相比,第二个参数5,现在我们将不得不f 2 3等于0:如果以后你添加一个定义x如下这一点没有改变。这将使得关于函数定义的推理更加困难,所以大多数(如果不是全部的话)函数式语言(如Haskell)使用“局部”变量进行模式匹配,忽略了这些变量的可能全局定义。


一个更冒险的选择是使用view patterns

{-# LANGUAGE ViewPatterns #-} 
a = "foo" 
b = "bar" 
g ((==a) -> True) = ... 
g ((==b) -> True) = ... 

我不是这种方法的粉丝虽然,因为我觉得标准模式与警卫更清晰。

+0

谢谢!我明白了这一点。但仍然认为应该有一个操作员告诉解释器使用外部范围中的定义。 –

+0

卫士如'x | x == a = ... | x == b = ...'不需要太多打字。否则,你可能想试验[查看模式](http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#view-patterns),但它们似乎矫枉过正任务恕我直言。 – chi

3

如果这是一个完整的误解,你想完成什么 ,但不会像这样?

Data Obj = A | B 

g A = A 
g B = A 

f A = "foo" 
f B = "bar" 

你想要一组预定义的对象吗?