Haskell数据类型别名命名

mk1*_*k12 9 haskell types naming-conventions algebraic-data-types type-alias

Vector在Haskell 写了一个数学模块.

所以我开始:

data Vector a = Vector !a !a !a deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)

很好 - 这让我可以使用我想要的任何数值数据类型.问题是,我不希望被编写DoubleVector Double针对我不应该,原因很简单无处不在.所以我补充说:

type Scalar = Double
type Vector = Vector Scalar
Run Code Online (Sandbox Code Playgroud)

但当然第二行是错误的,因为现在有两个声明Vector.那么我该怎么改呢?我想,不,我将在我的代码中写这个,所以我想把类型别名简单地留下来Vector.这意味着我必须更改数据类型名称.但是,如果我改变了,那么我觉得我也应该改变构造函数,这会使一切更加混乱.但是如果让构造函数与类型别名具有相同的名称感觉很尴尬.

现在我有这个:

type Scalar = Double
type Vector = VectorT Scalar

data VectorT a = Vector !a !a !a deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)

T随意挑选(我猜它代表"类型")但我不太确定这一点.通常,当我记录函数时,我会说-- Calculate the magnitude of a Vector,但VectorT我觉得我应该真的使用类型名称.所以我只是将它们称为vectors(不是大写) - 除了我觉得我必须将此约定应用于每种数据类型的每个注释.

有没有人处于类似的情况?在这种情况下,谁能想到更优雅的解决方案?

Tik*_*vis 8

您的特定问题的一个解决方案是将数据类型与类型同义词放在不同的模块中.也就是说,有一个Math.Vector包含数据声明和一些通用函数的模块(即,适用于所有数字类型的函数).然后,当您实际使用Vector Double代码时,只需使用限定导入创建类型同义词:

import qualified Math.Vector as MV

type Scalar = Double
type Vector = MV.Vector Scalar
Run Code Online (Sandbox Code Playgroud)

我认为从代码组织的角度来看这是有道理的.特别是,如果您已经定义了Vector类型以处理所有数字类型,我希望该模块中的函数也适用于所有数字类型.您Vector Double在代码的其他部分中使用了很多这一事实不应该影响Vector实际定义的模块.毕竟,想象Vector Int在你的程序的另一部分中使用了很多东西是完全合理的.

顺便说一句,我不确定这Vector是最好的主意.向量不一定要有三个维度,所以我会把你的数据类型称为Vector3D.这实际上是一些其他API(如Java 3D API)中使用的名称,因此它可能是一个不错的选择.