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
转换为任何数字类型。