Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell GHC在使用typeclass时抱怨类型不匹配。_Haskell - Fatal编程技术网

Haskell GHC在使用typeclass时抱怨类型不匹配。

Haskell GHC在使用typeclass时抱怨类型不匹配。,haskell,Haskell,我不明白为什么“点”部分不起作用 class Vector a where add, minus, cross :: a -> a -> a dot :: Num b => a -> a -> b data Vector2D a = Vector2D a a deriving (Read) instance Num a => Vector (Vector2D a) where add (Vector2D x1 y1) (Vector

我不明白为什么“点”部分不起作用

class Vector a where
    add, minus, cross :: a -> a -> a
    dot :: Num b => a -> a -> b

data Vector2D a = Vector2D a a deriving (Read)

instance Num a => Vector (Vector2D a) where
    add (Vector2D x1 y1) (Vector2D x2 y2) = Vector2D (x1 + x2) (y1 + y2)
    minus (Vector2D x1 y1) (Vector2D x2 y2) = Vector2D (x1 - x2) (y1 - y2)
    dot (Vector2D x1 y1) (Vector2D x2 y2) = x1*x2 + y1*y2
错误消息是:

Couldn't match expected type ‘b’ with actual type ‘a’
  ‘a’ is a rigid type variable bound by
      the instance declaration at example.hs:9:10
  ‘b’ is a rigid type variable bound by
      the type signature for
        dot :: Num b => Vector2D a -> Vector2D a -> b
      at example.hs:12:3
Relevant bindings include
  y2 :: a (bound at example.hs:12:37)
  x2 :: a (bound at example.hs:12:34)
  y1 :: a (bound at example.hs:12:20)
  x1 :: a (bound at example.hs:12:17)
  dot :: Vector2D a -> Vector2D a -> b (bound at example.hs:12:3)
In the first argument of ‘(*)’, namely ‘x1’
In the first argument of ‘(+)’, namely ‘x1 * x2’

我看一下点的类型,它是
dot::(numb,向量a)=>a->a->b
。我怎样才能使它正确呢?

问题是类型签名

dot :: Num b => a -> a -> b
表示无论向量类型是什么,
dot
需要能够返回任何数字类型,而表达式
x1*x2+y1*y2
将只返回放入向量中的类型

要解决此问题,可以使用类型族将单个标量类型连接到每个向量类型:

{-# LANGUAGE TypeFamilies #-}

class Vector a where
    type ScalarOf a
    add, minus, cross :: a -> a -> a
    dot :: a -> a -> ScalarOf a

data Vector2D a = Vector2D a a deriving (Read)

instance Num a => Vector (Vector2D a) where
    type ScalarOf (Vector2D a) = a
    add (Vector2D x1 y1) (Vector2D x2 y2) = Vector2D (x1 + x2) (y1 + y2)
    minus (Vector2D x1 y1) (Vector2D x2 y2) = Vector2D (x1 - x2) (y1 - y2)
    dot (Vector2D x1 y1) (Vector2D x2 y2) = x1*x2 + y1*y2
另一种方法是使用多参数类型的类,可能带有函数依赖项

我还想提到,
cross
产品基本上只对三维向量有意义。(我听说你可以让它们在7维上工作,也可以在1维上工作。)

(+)
(*)
都有类型
Num a=>a->a->a
,所以它们必须返回相同的类型。无法将
a
转换为任何数字类型。