【发布时间】:2012-05-24 12:16:57
【问题描述】:
我想要一个函数+++,它将两个数学向量相加。
我可以将向量实现为[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 矢量以外的任何东西,但将其限制在此似乎不太正确。
我想我想要的是具有两个相等长度的列表的函数,或者更好的是,对任意大小的元组进行操作的函数。
任何建议,在实用性、可扩展性、优雅等方面?
【问题讨论】:
-
我知道这个问题有点老了,但你可能想看看vector-space 包。
标签: list math haskell functional-programming tuples