Haskell向量类型:[a] - > [a] - > a的函数

Mis*_*don 6 haskell typeclass

好吧,我正试图绕着类型类包围,所以我试图为几何向量运​​算定义一个类型类.我设法让它在组件方面工作,+,-,*,/;但我正在努力使用dot产品.

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
Run Code Online (Sandbox Code Playgroud)

显然我的(>.)的实例定义不起作用,因为结果是类型的Fractional a,而不是Double.

但我不知道如何从类中的声明中获得此行为.

什么我喜欢做的是:

class GeomVector [a] where
  (>.) :: [a] -> [a] -> a
Run Code Online (Sandbox Code Playgroud)

但这是无效的,因为它[a]是一个类型而不是一个类型变量.

我希望我能更好地解释这一点,但老实说我真的不明白这样做.希望代码能让我更加清楚我正在努力解决的问题.

jbe*_*man 5

这是一个可行的选项:

class GeomVector v where
  (>+) :: Num a=> v a -> v a -> v a
  (>-) :: Num a=> v a -> v a -> v a
  (>*) :: Num a=> v a -> v a -> v a
  (>/) :: Fractional a=> v a -> v a -> v a
  (>.) :: Num a=> v a -> v a -> a

data Vector a = Vec { vecList :: [a] }
              deriving Show

instance GeomVector Vector 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

  (>.) u v = sum $ vecList (u >* v)
Run Code Online (Sandbox Code Playgroud)

所以你的所有实例GeomVector都会有* -> *类似的Monad类.并且这些方法的Fractional类型不仅仅因为你在那里划分某些地方而被不必要地限制在类型中.

您也可以考虑让您的类尽可能小(>.在类之外创建一个多态函数)以及您真正想要的是一个类型类.但这一切都取决于你的设计,我不想假设我比你知道的更好!