为什么这段代码不起作用:
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
我知道上面的例子是一个疯狂的例子,但是功能依赖的目的不是帮助类型检查器解决这些问题吗?
答案 0 :(得分:4)
实际上它确实解决了歧义。问题是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填写了不在->
右侧的所有类型变量,它就可以填写其余的。
答案 1 :(得分:2)
instance Foo Float Float Int where
foo a b = a + b
即使没有功能依赖,这也是一个错误。如果a
和b
为Float
,则a + b
为Float
,而不是Int
。