stu*_*ith 13 haskell coding-style
假设我的Vector数据类型定义如下:
data Vector = Vector { x :: Double
, y :: Double
, z :: Double
}
Run Code Online (Sandbox Code Playgroud)
使用成员访问来定义函数是否更常见:
vecAddA v w
= Vector (x v + x w)
(y v + y w)
(z v + z w)
Run Code Online (Sandbox Code Playgroud)
或者使用模式匹配:
vecAddB (Vector vx vy vz) (Vector wx wy wz)
= Vector (vx + wx)
(vy + wy)
(vz + wz)
Run Code Online (Sandbox Code Playgroud)
(如果我的任何术语不正确,请道歉).
val*_*man 12
我通常会使用模式匹配,特别是因为你使用了所有构造函数的参数,并且它们不是很多.此外,在此示例中,这不是问题,但请考虑以下事项:
data Foo = A {a :: Int} | B {b :: String}
fun x = a x + 1
Run Code Online (Sandbox Code Playgroud)
如果你使用模式匹配来做Foo类型的工作,你就是安全的; 无法访问不存在的成员.另一方面,如果使用访问器函数,则调用fun (B "hi!")此处等某些操作将导致运行时错误.
编辑:虽然它当然很可能忘记在一些构造函数上匹配,但模式匹配使得它非常明确,所发生的事情取决于使用的构造函数(您还可以告诉编译器检测并警告您不完整的模式)而使用一个函数提示更多,任何构造函数去,IMO.
如果你只想获得一个或几个构造函数(可能很多)参数并且你知道使用它们是安全的(没有在错误的构造函数上使用访问器的风险,例如在示例中),最好保存访问器.)
另一个次要的"真实世界"论点:一般来说,拥有如此短的记录条目名称并不是一个好主意,因为短名称喜欢x并y经常最终用于局部变量.
所以这里的"公平"比较是:
vecAddA v w
= Vector (vecX v + vecX w) (vecY v + vecY w) (vecZ v + vecZ w)
vecAddB (Vector vx vy vz) (Vector wx wy wz)
= Vector (vx + wx) (vy + wy) (vz + wz)
Run Code Online (Sandbox Code Playgroud)
我认为模式匹配在这种类型的大多数情况下都胜出.一些值得注意的例外: