can';t在haskell中使用GADT实现矩阵和向量

can';t在haskell中使用GADT实现矩阵和向量,haskell,vector,Haskell,Vector,我是哈斯克尔的初学者。 我试图在haskell中实现矩阵和向量。我想让它们支持Num typeclass中的所有类型,但不支持其他类型,所以我尝试使用GADTs,但我遇到了错误。你能解释一下为什么我会出现错误吗。或者,如果没有这种方式,我可以获得相同的功能 我的代码: {-# LANGUAGE GADTs #-} class LStruct s where scale :: (Num a) => a -> s -> s add :: s -> s -> s

我是哈斯克尔的初学者。 我试图在haskell中实现矩阵和向量。我想让它们支持Num typeclass中的所有类型,但不支持其他类型,所以我尝试使用GADTs,但我遇到了错误。你能解释一下为什么我会出现错误吗。或者,如果没有这种方式,我可以获得相同的功能

我的代码:

{-# LANGUAGE GADTs #-}

class LStruct s where
  scale :: (Num a) => a -> s -> s
  add :: s -> s -> s


data Vector a where
  Vector :: (Num a) => a -> Vector [a]

data Matrix a where
  Matrix :: (Num a) => a -> Matrix [a]


instance LStruct (Vector a) where
  scale a (Vector xs) = Vector (map (*a) xs)
  add (Vector xs) (Vector ys) = Vector (zipWith (+) xs ys)
错误:

[-Wdeferred-type-errors]
• Could not deduce: a2 ~ [a1]
  from the context: (a ~ [a2], Num a2)
    bound by a pattern with constructor:
               Vector :: forall a. Num a => a -> Vector [a],
             in an equation for ‘scale’
    at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:20:12-20
  ‘a2’ is a rigid type variable bound by
    a pattern with constructor:
      Vector :: forall a. Num a => a -> Vector [a],
    in an equation for ‘scale’
    at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:20:12-20
• In the second argument of ‘map’, namely ‘xs’
  In the first argument of ‘Vector’, namely ‘(map (* a) xs)’
  In the expression: Vector (map (* a) xs)
• Relevant bindings include
    xs :: a2
      (bound at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:20:19)
    a :: a1
      (bound at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:20:9)
    scale :: a1 -> Vector a -> Vector a
      (bound at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:20:3)

[-Wdeferred-type-errors]
• Could not deduce: a2 ~ [c0]
  from the context: (a ~ [a1], Num a1)
    bound by a pattern with constructor:
               Vector :: forall a. Num a => a -> Vector [a],
             in an equation for ‘add’
    at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:21:8-16
  or from: (a ~ [a2], Num a2)
    bound by a pattern with constructor:
               Vector :: forall a. Num a => a -> Vector [a],
             in an equation for ‘add’
    at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-       TEMP.hs:21:20-28
  ‘a2’ is a rigid type variable bound by
    a pattern with constructor:
      Vector :: forall a. Num a => a -> Vector [a],
    in an equation for ‘add’
    at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:21:20-28
  Expected type: [c0]
    Actual type: a1
• In the second argument of ‘zipWith’, namely ‘xs’
  In the first argument of ‘Vector’, namely ‘(zipWith (+) xs ys)’
  In the expression: Vector (zipWith (+) xs ys)
• Relevant bindings include
    ys :: a2
      (bound at /home/d4rk0wl/Playground/hs/Mask/.stack-work/intero/intero10129CJD-TEMP.hs:21:27)

我想你打算写:

data Vector a where
    Vector :: (Num a) => [a] -> Vector a
“矢量或A可以从A的列表中构造”

您问题中的版本采用一个
a
,您得到的错误是GHC试图映射到该单个值

更广泛地说,我建议将
Num
约束从构造函数移动到使用
Vector
的实例和函数。以这种方式编写的代码似乎可以从GHC获得更好的错误消息,并且更易于使用。我不确定这是否有深层次的原因,或者这只是一个GHC开发人员在哪里花费时间的问题

因此,实例声明可能会变成:

instance Num a => LStruct (Vector a) where

实例主体可以保持不变。

我认为您打算写:

data Vector a where
    Vector :: (Num a) => [a] -> Vector a
“矢量或A可以从A的列表中构造”

您问题中的版本采用一个
a
,您得到的错误是GHC试图映射到该单个值

更广泛地说,我建议将
Num
约束从构造函数移动到使用
Vector
的实例和函数。以这种方式编写的代码似乎可以从GHC获得更好的错误消息,并且更易于使用。我不确定这是否有深层次的原因,或者这只是一个GHC开发人员在哪里花费时间的问题

因此,实例声明可能会变成:

instance Num a => LStruct (Vector a) where
实例主体可以保持不变