为什么这个代码不起作用:
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
即使没有函数依赖项,这也是一个错误。如果a
和b
是Float
,则a + b
是Float
,而不是Int
。