我想要一个+++
添加两个数学向量的函数。
我可以将向量实现为[x, y, z]
并使用:
(+++) :: (Num a) => [a] -> [a] -> [a]
(+++) = zipWith (+)
因此可以容纳任何n维向量(所以这也适用[x, y]
)。
或者我可以将向量实现为(x, y, z)
并使用:
type Triple a = (a, a, a)
merge :: (a -> b -> c) -> Triple a -> Triple b -> Triple c
merge f (a, b, c) (x, y, z) = (f a x, f b y, f c z)
(+++) :: (Num a) => Triple a -> Triple a -> Triple a
(+++) = merge (+)
当然,这稍微复杂一些,但是当我实现所有其他向量函数时,这是无关紧要的(50 行而不是 40 行)。
列表方法的问题是我可以将 2D 向量与 3D 向量相加。在这种情况下,zipWith
只需切断 3D 矢量的z
分量。虽然这可能是有道理的(更有可能它应该将 2D 向量扩展为[x, y, 0]
),但对于其他功能,我认为无论是静默发生都可能是有问题的。元组方法的问题在于它将向量限制为 3 个分量。
直观地说,我认为将向量表示为 更有意义(x, y, z)
,因为数学向量具有固定数量的分量,并且将分量添加到向量中并没有真正意义。
另一方面,虽然我不太可能需要除 3D 矢量以外的任何东西,但将其限制在此似乎不太正确。
我想我想要的是具有两个相等长度的列表的函数,或者更好的函数,这些函数对任意大小的元组进行操作。
在实用性、可扩展性、优雅等方面有什么建议吗?