不可扣除的关系

Sán*_*zai 1 haskell typeclass

为什么之间的关系a,并b不能推断出?

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
Run Code Online (Sandbox Code Playgroud)

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

chi*_*chi 7

(<.>) :: Num b => a -> a -> b
Run Code Online (Sandbox Code Playgroud)

上述意味着(<.>)能够产生该函数调用者可能想要的任何类型的数字.

例如,如果x,yVec2 Double,则x <.> y可以调用返回Integer.编译器然后抱怨它在发布的实例中的实现不够通用,因为它返回Doubles而不是调用者可能选择的任何类型.

我认为这不是该代码打算建模的内容.

您可能希望切换到多参数类(您需要启用一些扩展,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
Run Code Online (Sandbox Code Playgroud)

由于现在编译器无法确定类型x <.> y的类型x,y,您可能希望使用添加功能依赖

class Vector a b | a -> b where
    (<.>) :: a -> a -> b
Run Code Online (Sandbox Code Playgroud)

或者使用类型系列

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
Run Code Online (Sandbox Code Playgroud)