使用元组时的非法实例声明

Illegal instance declaraion when using tuples

在 Haskell 中闲逛,更深入地了解类型 classes,但我遇到了一些障碍。无论出于何种原因,我都不允许创建我的 Vector class 的实例。有人告诉我这是一个非法的实例声明,因为我没有不同的类型变量?这是怎么回事?

class Vector v where
  vplus :: v -> v -> v
  vmult :: Num a => v -> a -> v

instance Num a => Vector (a, a) where
  (a, b) `vplus` (c, d) = (a + c, b + d)
  (a, b) `vmult` m = (a * m, b * m)

a 在你的 (a,a) 实例中将是一个任意的 Num 实例。 vmult :: Num a => v -> a -> v 中的 a 对此一无所知,即这可能是任何 other Num 实例。

要使 class 正常工作,您需要

  • 确保数字类型可以相互转换。例如,

    class Vector v where
      vplus :: v -> v -> v
      vmult :: RealFrac a => v -> a -> v
    
    instance RealFrac a => Vector (a, a) where
      (a, b) `vplus` (c, d) = (a + c, b + d)
      (a, b) `vmult` m' = (a * m, b * m)
        where m = realToFrac m'
    
  • 确保标量乘数实际上与向量分量的类型相同。 vector-space 库就是这样做的。对于您的代码,它将采用

    形式
    {-# LANGUAGE TypeFamilies, FlexibleInstances #-}
    
    class Vector v where
      type Scalar v :: *
      vplus :: v -> v -> v
      vmult :: v -> Scalar v -> v
    
    instance Num a => Vector (a, a) where
      type Scalar (a,a) = a
      (a, b) `vplus` (c, d) = (a + c, b + d)
      (a, b) `vmult` m = (a * m, b * m)