Haskell:代数数据与元组

时间:2012-05-17 00:07:07

标签: haskell types tuples

data Ray = Ray Vector Vector

type Ray = (Vector, Vector)

在idiomatic haskell中哪个更受欢迎?我为什么要用一个呢? 我不关心表现。

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

trace :: Ray -> …

trace (Ray x d) = …
-- OR
trace (x, d) = …

3 个答案:

答案 0 :(得分:10)

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

然后,可以使用Ray的自定义实例进一步依赖类型系统,并且在元组中无法进行优化。

答案 1 :(得分:6)

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

newtype Ray = Ray (Vector, Vector)

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

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

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

答案 2 :(得分:3)

我觉得非常方便的第四种选择是记录:

data Ray = Ray { from, to :: Vector } 

它们基本上具有“正常”ADT的所有特征,但具有一些额外的语法糖。特别是它们可以更容易地获得值的部分修改副本。确实,在某些情况下记录太有限,但是你可以进一步使用“改进版本”,如fclabels