Haskell 使用@-patterns获取模式值是否多余?

Haskell 使用@-patterns获取模式值是否多余?,haskell,pattern-matching,Haskell,Pattern Matching,我正在经历,在其中我遇到了一些看似多余的代码;他们使用-模式,然后返回值本身,让我解释一下 以下是相关代码: data LispVal = Atom String | List [LispVal] | DottedList [LispVal] LispVal | Number Integer | String String | Bool Bool eval :: L

我正在经历,在其中我遇到了一些看似多余的代码;他们使用-模式,然后返回值本身,让我解释一下

以下是相关代码:

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
并将原始代码中的所有@模式都放在底格中


我这样想是不是搞错了?他们这样做是否真的有好处?或者另一种方式更简洁?

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

eval val@(Atom _) = val
无论这是否是复制粘贴错误,它都强调了风格上的重要差异:

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

第二种风格断言:
eval
只需查看
列表
值,其他所有值都可以单独处理。特别是,以后对数据类型的添加也应该可以正常工作,这样您就不想为这个函数而烦恼了

在操作上,它们是等价的