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

Ele*_*fee 4 haskell pattern-matching

我将在48小时内为自己编写一个方案,在其中我遇到了一些看似冗余的代码; 他们使用@ -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
Run Code Online (Sandbox Code Playgroud)

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

eval :: LispVal -> LispVal
eval (List [Atom "quote", val]) = val
eval val = val
Run Code Online (Sandbox Code Playgroud)

并在原始代码中为所有@ -patterns设置底层案例帐户.

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

Joa*_*ner 11

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

eval val@(Atom _) = val
Run Code Online (Sandbox Code Playgroud)

无论这是否是一个''''''''''''',,,,,,,,,,,,

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

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

在操作上,它们是等价的.