【发布时间】:2012-12-04 22:34:02
【问题描述】:
好的,我正在尝试围绕类型类进行研究,因此我正在尝试为几何矢量运算定义一个类型类。我设法让它在组件方面工作+,-,*,/;,但我在点积上苦苦挣扎。
class GeomVector a where
(>+) :: a -> a -> a
(>-) :: a -> a -> a
(>*) :: a -> a -> a
(>/) :: a -> a -> a
(>.) :: a -> a -> Double
data Vector a = Vec [a]
deriving Show
instance (Fractional a) => GeomVector (Vector a) where
(>+) (Vec u) (Vec v) = Vec $ zipWith (+) u v
(>-) (Vec u) (Vec v) = Vec $ zipWith (-) u v
(>*) (Vec u) (Vec v) = Vec $ zipWith (*) u v
(>/) (Vec u) (Vec v) = Vec $ zipWith (/) u v
(>.) (Vec u) (Vec v) = sum $ u >* v
显然我对 (>.) 的实例定义不起作用,因为结果的类型是 Fractional a,而不是 Double。
但我不知道如何从类中的声明中获得这种行为。
我喜欢做的是:
class GeomVector [a] where
(>.) :: [a] -> [a] -> a
但是这是无效的,因为[a] 是一个类型而不是一个类型变量。
我希望我能更好地解释这一点,但老实说,我的理解还不够。希望代码能让我更清楚我正在努力解决的问题。
【问题讨论】:
-
我认为您需要另一个类型变量来表示标量的类型,即
class GeomVector a s where ... (>.) :: a -> a -> s。 -
您的类声明有缺陷,不仅因为 (>.) 结果类型。您尝试生成
u和v的点积,它们是列表,而不是您的类的实例。 -
@Lambdageek 为什么是同义词?它不只是这里需要的关联类型吗? (
data Scalar a)? -
@DmitryDzhus
Scalar a应该是某个现有类型(例如,对于instance GeomVector [a],它应该是a),而不是全新的数据类型。