使用@ -patterns来获取模式值是多余的?

时间:2015-07-02 12:32:04

标签: haskell pattern-matching

我经历了Write Yourself a Scheme in 48 Hours,在其中我遇到了一些看似冗余的代码;他们使用@ -patterns然后返回值本身,让我解释一下。

以下是相关代码:

data LispVal = Atom String
             | List [LispVal]
             | DottedList [LispVal] LispVal
             | Number Integer
             | String String
             | Bool Bool

eval :: LispVal -> LispVal -- code in question starts here
eval val@(String _) = val
eval val@(Number _) = val
eval val@(Bool _)   = val
eval (List [Atom "quote", val]) = val

在我看来,整个eval函数可以很容易地重写为

eval :: LispVal -> LispVal
eval (List [Atom "quote", val]) = val
eval val = val

并在原始代码中使用所有@ -patterns的底部案例帐户。

我是否错误地想到了这一点,并且按照他们的方式做到这一点是否有实际好处?或者另一种方式更简洁?

1 个答案:

答案 0 :(得分:11)

一个区别是对于使用Atom构造的值,原始代码未定义,即没有行

eval val@(Atom _) = val

无论这是否是一个'复制'错误,它突出了风格的重要区别:

第一种风格鼓励你单独思考每个值,明确断言“这是正确的方程式”。如果稍后在LispVal类型中添加更多构造函数,则会出现运行时错误(或编译器警告-fwarn-incomplete-patterns,这是一种很好的做法)。

第二种风格断言:eval只需要查看List值,而其他所有值都可以单独处理。特别是,稍后添加到数据类型也应该可以正常工作,并且您不希望对此函数感到困扰。

在操作上,它们是等效的。