3

在 haskell功能依赖 wiki中:

鉴于这些定义:

data Vector = Vector Int Int deriving (Eq, Show)
data Matrix = Matrix Vector Vector deriving (Eq, Show)
instance Num Vector where
  Vector a1 b1 + Vector a2 b2 = Vector (a1+a2) (b1+b2)
  Vector a1 b1 - Vector a2 b2 = Vector (a1-a2) (b1-b2)
  {- ... and so on ... -}

instance Num Matrix where
  Matrix a1 b1 + Matrix a2 b2 = Matrix (a1+a2) (b1+b2)
  Matrix a1 b1 - Matrix a2 b2 = Matrix (a1-a2) (b1-b2)
  {- ... and so on ... -}
class Mult a b c where
  (*) :: a -> b -> c

instance Mult Matrix Matrix Matrix where
  {- ... -}

instance Mult Matrix Vector Vector where
  {- ... -}

我不明白为什么会有模棱两可的类型:

m1, m2, m3 :: Matrix
(m1 * m2) * m3              -- type error; type of (m1*m2) is ambiguous

显然,当m1m2Matrix时,唯一可能的返回类型是Matrix,即应用instance Mult Matrix Matrix Matrix.

4

2 回答 2

6

问题在于类型类声明

class Mult a b c where
  (*) :: a -> b -> c

通过应用(*)两个参数,您无法确定结果的类型。假设您有两个实例:

instance Mult Int Int Int where ...
instance Mult Int Int Integer where ...

然后2 * 4可以是 typeInt以及 of Integer

现在你可以争辩说你只有一个实例,所以编译器不应该抱怨。但是 Haskell 类型的类生活在一个开放的世界中。您总是可以添加更多实例,并且它不能在其他地方破坏代码。因此,即使您只有一个实例,另一个库中的其他人也可以添加另一个实例。而且,您将有两个库,每个库都可以工作,但一起失败。这显然是不正确的。请参阅Real World Haskell中的生活在开放世界中。

因此,通常类型类中函数的返回类型必须可从其参数派生。这正是功能依赖的用途。如果你声明

class Mult a b c | a b -> c where

那么编译器总能分辨出(*).

于 2013-02-04T18:08:10.120 回答
1

因为您忘记了所有其他可能性,例如

 instance Mult Matrix Matrix Vector where
 instance Mult Vector Matrix Vector where
 instance Mult Float Matrix Float where
 instance Mult Matrix Matrix Float where  -- etc.

 a :: Vector
 a = (m1 >< m2:: Vector) >< m3

 b :: Float
 b = (m1 >< m2:: Float) >< m3

向类定义添加功能依赖:

instance Mult a b c | a b -> c

将意味着

instance Mult Matrix Matrix Matrix

决定两个矩阵的问题,并且

instance Mult Matrix Matrix Vector
instance Mult Matrix Matrix Float

被排除在外,因为它们提供了另一种查看“aMatrix和 a的乘积”的方式Matrix。因此,您发现直观的事态是您将获得的功能依赖关系。

如果函数依赖是这样制定的:

 instance Mult a b c | b -> a c

这也将允许您陈述的两个实例,

 instance Mult Matrix Matrix Matrix where
 instance Mult Matrix Vector Vector where

但排除我想象的其他人,他们都Matrix在这个b位置(因为他们不得不这样做,因为在模棱两可的例子m3中被解释为一个Matrix而不是矩阵乘积的结果。

于 2013-02-04T18:05:53.810 回答