实现无限向量空间在Haskell作为映射从整数到标量



我试图在Haskell中实现无限维向量空间,但我遇到了麻烦。我将使用流作为基本数据类型,并简单地使用为向量空间提供的包,但我希望索引在负方向和正方向上都有。换句话说,我需要从整数(所有整数)到标量值的某种映射。这很容易实现,例如

(^+^) :: (Integer -> Double) -> (Integer -> Double) -> (Integer -> Double)
a ^+^ b = ( n -> (a n) + (b n))
(^*^) :: Double -> (Integer -> Double) -> (Integer -> Double)
c ^*^ a = ( n -> c * (a n))

一样使用
vecA :: (Integer -> Double)
vecB :: (Integer -> Double)
vecA n = fromInteger n
vecB n = fromInteger n
print ((vecA ^+^ vecB) 4) --prints 8.0, as expected

好的,我想让它更通用,naïvely,我想这样写,

class AdditiveGroup v where
  -- | The zero element: identity for '(^+^)'
  zeroV :: v
  -- | Add vectors
  (^+^) :: v -> v -> v
  -- | Additive inverse
  negateV :: v -> v
  -- | Group subtraction
  (^-^) :: v -> v -> v
  v ^-^ v' = v ^+^ negateV v'
class AdditiveGroup v => VectorSpace v where
  type Scalar v :: *
  -- | Scale a vector
  (*^) :: Scalar v -> v -> v

(我从Haskell的类中复制并粘贴了这个定义。)但是,当然,没有一种方法(我可以看到)将我上面的映射实现为数据结构,并且试图改变v的类型会使我遇到问题

--This doesn't even compile
class InfVecSpace v where
    type Index v  :: *
    type Scalar v :: *
    type Member v :: * -> *
    (^+^)   :: (Member v) -> (Member v) -> (Member v)
    zeroV   :: (Member v)
    invertV :: (Member v) -> (Member v)
    (^*^)   :: Scalar v -> (Member v) -> (Member v)

我如何在Haskell的类型系统中实现这一点,最好是尽可能地符合习惯?

绝对没有必要创建一个新类;相反,只需为函数类型创建旧类的实例。例如:

instance AdditiveGroup v => AdditiveGroup (e -> v) where
    zeroV _ = zeroV
    (f ^+^ g) x = f x ^+^ g x
    negateV f x = negateV (f x)
instance VectorSpace v => VectorSpace (e -> v) where
    type Scalar (e -> v) = Scalar v
    (a *^ f) x = a *^ f x

最新更新