功能依赖:两种类型决定第三种类型



为什么这个代码不起作用:

class Foo a b c | a b -> c where
  foo :: a -> b -> c
instance Foo Int Int Int where
  foo a b = a + b  
ghci > foo 4 4  -- This produces run time error

通过使用函数依赖性,以下代码为什么会产生编译时错误:

instance Foo Float Float Int where
  foo a b = a + b

我知道上面的例子是一个疯狂的例子,但函数依赖的目的不是帮助类型检查器解决这些问题吗?

实际上它确实解决了歧义。问题是4 :: Num a => a,所以GHC不能决定您要使用foo :: Int -> Int -> Int。现在,如果你做

foo (4 :: Int) (4 :: Int)
> 8

从现在起,我们想使用哪个实例就很清楚了。为了更清楚,假设我们有

class Foo a b c | a -> b, a -> c where
  ...

现在我们可以做

foo (4 :: Int) 4
> 8

因为一旦GHC填充了不在->右侧的所有类型变量,它就可以填充其余的。

instance Foo Float Float Int where
    foo a b = a + b

即使没有函数依赖项,这也是一个错误。如果abFloat,则a + bFloat,而不是Int

最新更新