data Ray = Ray Vector Vector
或者
type Ray = (Vector, Vector)
在惯用的haskell中哪个是首选?为什么我应该使用一个而不是另一个?
我不在乎性能。
它似乎与功能没什么区别,例如:
trace :: Ray -> …
trace (Ray x d) = …
-- OR
trace (x, d) = …
首选版本,data
因为它更清楚地表明了程序员的意图——通过创建一个新类型,你向所有人指出这不仅仅是一个元组,而是一个有意义的语义实体,a Ray
.
这样就可以进一步依赖类型系统,自定义实例Ray
和元组中不可能的优化。
您还可以考虑第三种选择,它是两者的结合:newtype
newtype Ray = Ray (Vector, Vector)
在我看来,代数数据类型用于有多种选择的情况,或者需要类型是递归的、包含自身的情况。但对于这样的事情来说,这可能是矫枉过正。
Don Stewart 指出,将类型与元组同义词与直接使用元组类型相同;类型同义词没有自己的身份。因此类型检查器将无法区分您的类型和元组,因此它无法检查您是否使用了所需的类型。此外,它将具有与元组完全相同的实例。
Anewtype
允许您使用与元组相同的基础类型;但它是类型检查器的单独类型,具有单独的实例。
我发现非常方便的第四个选择是记录:
data Ray = Ray { from, to :: Vector }
它们基本上具有“普通”ADT 的所有特性,但还带有一些额外的语法糖。特别是它们使获取值的部分修改副本变得更容易。确实,在某些情况下记录太有限了,但是您可以使用诸如fclabels之类的“改进版本”走得更远。