Haskell:代数数据与元组

mk1*_*k12 14 haskell types tuples

data Ray = Ray Vector Vector
Run Code Online (Sandbox Code Playgroud)

要么

type Ray = (Vector, Vector)
Run Code Online (Sandbox Code Playgroud)

哪个是惯用的哈希尔?我为什么要使用一个而不是另一个?
我不关心表现.

它似乎与功能没什么区别,例如:

trace :: Ray -> …

trace (Ray x d) = …
-- OR
trace (x, d) = …
Run Code Online (Sandbox Code Playgroud)

Don*_*art 10

data版本是首选,因为它更清楚地表明程序员的意图 - 通过创建一个新类型,你指出所有这不仅仅是一个元组,而是一个有意义的语义实体,a Ray.

这样就可以进一步依赖类型系统,使用自定义实例Ray,并且在元组中不可能进行优化.

  • 不,出于性能原因,在Color中使用打包矢量类型更有意义,就像在颜色包中一样 - 这样有意义的类型可以进行优化和专业化.http://hackage.haskell.org/packages/archive/colour/2.3.3/doc/html/src/Data-Colour-Internal.html#Colour (2认同)
  • 元组对于其他模块不可见的临时和中间数据类型很有用,或者对于逻辑上相关但仅是模块中的“支持角色”的事物的集合很有用。 (2认同)
  • @Mk12 请记住,对于 3 维整数坐标空间中的位置,“type Color = (Int, Int, Int)”与“type Position = (Int, Int, Int)”无法区分。但您可能不希望对位置进行操作的函数也对颜色进行操作。 (2认同)

new*_*cct 6

您可能还会考虑第三种选择,它们是两者的组合: newtype

newtype Ray = Ray (Vector, Vector)
Run Code Online (Sandbox Code Playgroud)

在我看来,代数数据类型用于有多种替代方案的情况,或者在需要包含自身类型的递归类型的情况下.但对于这样的事情来说可能有些过分.

Don Stewart指出,为元组创建类型同义词与直接使用该元组类型相同; 类型同义词没有自己的身份.因此类型检查器无法区分您的类型和元组,因此无法检查您是否正在使用所需的类型.此外,它将具有与元组完全相同的实例.

A newtype允许您使用与元组相同的基础类型; 但它是类型检查器的单独类型,具有单独的实例.