类别101:GHC太"渴望"派生实例?

ftl*_*ftl 4 haskell instances

给出以下代码:

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
Run Code Online (Sandbox Code Playgroud)

现在,如果我尝试调用pf,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
Run Code Online (Sandbox Code Playgroud)

我觉得有点令人惊讶,因为f只接受一个必须是类型类C的实例的"a".这是什么原因?

编辑:我知道我没有为C定义任何实例,但不应该是"正确的"响应:

p f :: (C a) => a -> a 
Run Code Online (Sandbox Code Playgroud)

Cir*_*dec 8

当你将一个简单的表达式放入ghci时,它基本上就是尝试print它,所以

> p f
Run Code Online (Sandbox Code Playgroud)

与在文件中具有以下内容大致相同

main :: IO ()
main = print $ p f
Run Code Online (Sandbox Code Playgroud)

正如你所指出的那样p f :: (C a) => a -> a.为了print $ p fGHC需要评估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'
Run Code Online (Sandbox Code Playgroud)