不可推演关系

Not deducible relationship

为什么ab之间的关系不可推导?

class Vector a where
    (<.>) :: Num b => a -> a -> b

data Vec2 a
    = Vec2 (a, a)

    deriving Show

instance Num a => Vector (Vec2 a) where
    Vec2 (a, b) <.> Vec2 (c, d) = a * c + b * d

我想要一个 Vec2 代数数据结构,其中组件可以是任何数字。

(<.>) :: Num b => a -> a -> b

以上意味着 (<.>) 能够生成 任何 类型的数字,该函数的 caller 可能需要。

比如x,yVec2 Double,那么x <.> y就可以调用returnInteger。然后编译器抱怨它在发布实例中的实现不够通用,因为它 returns Doubles 而不是调用者可能选择的 any 类型。

我认为这不是该代码旨在建模的内容。

您可能想要切换到多参数 class(您需要启用一些扩展,GHC 会告诉您哪些):

class Vector a b where
    (<.>) :: a -> a -> b

instance Num a => Vector (Vec2 a) a where
    Vec2 (a, b) <.> Vec2 (c, d) = a * c + b * d

因为现在编译器无法根据 x,y 的类型确定 x <.> y 的类型,您可能需要使用

添加函数依赖
class Vector a b | a -> b where
    (<.>) :: a -> a -> b

或者使用类型族

class Vector a where
    type Scalar a
    (<.>) :: a -> a -> Scalar a

instance Num a => Vector (Vec2 a) where
    type Scalar (Vec a) = a
    Vec2 (a, b) <.> Vec2 (c, d) = a * c + b * d

正如@chi 的回答所说,您的代码不会使 b 依赖于 a。要得到我认为你想要的,你可以使用关联类型族:

{-# LANGUAGE TypeFamilies #-}

class Vector a where
    type Element a
    (<.>) :: a -> a -> Element a

data Vec2 a
    = Vec2 (a, a)

    deriving Show

instance Num a => Vector (Vec2 a) where
    type Element (Vec2 a) = a
    Vec2 (a, b) <.> Vec2 (c, d) = a * c + b * d

另一种选择是使用具有函数依赖性的多参数类型类,但我认为这里更复杂。