【问题标题】:Haskell Vector Typeclass: Function of [a] -> [a] -> aHaskell Vector Typeclass:[a] -> [a] -> a 的函数
【发布时间】: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
  • 您的类声明有缺陷,不仅因为 (>.) 结果类型。您尝试生成 uv 的点积,它们是列表,而不是您的类的实例。
  • @Lambdageek 为什么是同义词?它不只是这里需要的关联类型吗? (data Scalar a)?
  • @DmitryDzhus Scalar a 应该是某个现有类型(例如,对于 instance GeomVector [a],它应该是 a),而不是全新的数据类型。

标签: haskell typeclass


【解决方案1】:

这是一个可行的选择:

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)

所以你所有的GeomVector 实例都会有一个类似* -> *Monad 类。并且这些方法的类型并没有不必要地限制为 Fractional 类型,因为你在其中的某个地方进行了划分。

您还可以考虑使您的类尽可能小(使>. 成为类外部的多态函数)以及您真正想要的是否是一个类型类。但这一切都取决于你的设计,我不想假设我比你更了解这一点!

【讨论】:

  • 可能无法将>. 移出类,因为它需要知道GeomVector 的每个实例的内部结构才能进行求和。
  • 对,对不起。因此,如果有意义的话,一种选择是创建类class (Foldable v)=> GeomVector v
  • 此外,对于 zippy 的 Applicative,逐点操作都等于 liftA2,因此 Vector 也可能是 ZipList
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-15
  • 1970-01-01
相关资源
最近更新 更多