给出以下代码:
class C a where
foo :: a -> a
f :: (C a) => a -> a
f = id
p :: (C a) => (a -> a) -> a -> a
p g = foo . g
现在,如果我尝试调用p f,GHC会抱怨:
> p f
No instance for (C a0) arising from a use of `p'
In the expression: p f
In an equation for `it': it = p f
我发现有点令人惊讶,因为f只接受一个必须是类型类C的实例的“a”。这是什么原因?
编辑:我知道我没有为C定义任何实例,但不应该是“正确的”响应:
p f :: (C a) => a -> a
答案 0 :(得分:8)
当你将一个简单的表达式放入ghci时,它基本上是试图print
,所以
> p f
与在文件中具有以下内容大致相同
main :: IO ()
main = print $ p f
正如您所指出的,p f :: (C a) => a -> a
。为了print $ p f
GHC需要评估p f
。 GHC无法在不选择要传入的字典的情况下使用类型类上下文来评估值。为此,它需要为所有C a
找到一个a
实例,它不会退出。它还需要为Show
找到a -> a
个实例。无法找到这两种结果导致两个错误
No instance for (Show (a -> a)) arising from a use of `print'
No instance for (C a) arising from a use of `p'
答案 1 :(得分:4)
这是可怕的monomorphism restriction。默认情况下,如果推断类型具有类约束,GHC不允许我们具有没有类型注释的顶级值定义。
可以解决问题 a。)通过在源代码顶部添加{-# LANGUAGE NoMonomorphismRestriction #-}
来关闭限制。
b。)向受影响的顶级绑定添加类型注释:
foo :: C a => a -> a
foo = p f
c。)扩展功能定义(如果可能):
foo x = p f x