我用 Haskell 编写了一个数学 Vector
模块。
所以我开始:
data Vector a = Vector !a !a !a deriving (Eq, Show)
很好——这让我可以使用我想要的任何数字数据类型。问题是我不想到处写 Double
和 Vector Double
,原因很简单,我不应该这样做。所以我补充一下:
type Scalar = Double
type Vector = Vector Scalar
但是第二行当然是错误的,因为现在有两个 Vector
声明。那我应该把它改成什么呢?我对自己说,不,我将在我的代码中编写这些内容,所以我想将类型别名简单地保留为 Vector
。这意味着我必须更改数据类型名称。但如果我改变它,那么我觉得我也应该改变构造函数,这会让一切变得更加困惑。但是如果这样让构造函数与类型别名具有相同的名称感觉很尴尬。
现在我有这个:
type Scalar = Double
type Vector = VectorT Scalar
data VectorT a = Vector !a !a !a deriving (Eq, Show)
我任意选择了T
(我猜它代表“类型”),但我对此不太确定。通常,当我记录函数时,我会说--计算向量的大小
,但是对于VectorT
,我觉得我真的应该使用那个键入名称。因此,我只是将它们称为向量
(不大写),但我觉得我必须将这个约定应用于每种数据类型的每个评论。
有人遇到过类似的情况吗?在这种情况下,有人能想到更优雅的解决方案吗?
最佳答案
解决您的特定问题的一个解决方案是将数据类型与类型同义词放在不同的模块中。也就是说,有一个 Math.Vector 模块,其中包含数据声明和一些通用函数(即适用于所有数字类型的函数)。然后,当您在代码中实际大量使用 Vector Double
时,只需使用限定导入创建类型同义词即可:
import qualified Math.Vector as MV
type Scalar = Double
type Vector = MV.Vector Scalar
我认为从代码组织的角度来看这是有道理的。特别是,如果您已将 Vector
类型定义为适用于所有数字类型,我希望该模块中的函数也适用于所有数字类型。事实上,您在代码的其他部分大量使用 Vector Double
不会影响实际定义 Vector
的模块。毕竟,想象在程序的另一部分大量使用 Vector Int
是完全合理的。
顺便说一句,我不确定将其称为Vector
是最好的主意。向量不一定必须具有三个维度,因此我将您的数据类型称为 Vector3D
。这实际上是其他一些 API(例如 Java 3D API)中使用的名称,因此它可能是一个不错的选择。
关于Haskell 数据类型别名命名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11380761/