类型类 101:GHC 也 "eager" 来派生实例?
Typeclasses 101: GHC too "eager" to derive instance?
给定以下代码:
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 定义任何实例,但 "proper" 响应不应该是:
p f :: (C a) => a -> a
可怕的 monomorphism restriction 正在发生。默认情况下,如果推断类型具有 class 约束,GHC 不允许我们在没有类型注释的情况下拥有顶级值定义。您可以通过
来补救这种情况
a.) 通过将 {-# LANGUAGE NoMonomorphismRestriction #-}
添加到源代码的顶部来关闭限制。
b.) 向受影响的顶级绑定添加类型注释:
foo :: C a => a -> a
foo = p f
c.) 扩展函数定义(如果可能):
foo x = p f x
当你将一个简单的表达式放入 ghci 时,它基本上是在尝试 print
它,所以
> p f
与在文件中包含以下内容大致相同
main :: IO ()
main = print $ p f
正如您所指出的,p f :: (C a) => a -> a
。为了 print $ p f
GHC 需要评估 p f
。如果不选择要传入的字典,GHC 无法评估具有类型 class 上下文的值。为此,它需要为所有 a
找到一个 C a
实例,该实例不会退出.它还需要为 a -> a
找到一个 Show
实例。无法找到其中任何一个会导致两个错误
No instance for (Show (a -> a)) arising from a use of `print'
No instance for (C a) arising from a use of `p'
给定以下代码:
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 定义任何实例,但 "proper" 响应不应该是:
p f :: (C a) => a -> a
可怕的 monomorphism restriction 正在发生。默认情况下,如果推断类型具有 class 约束,GHC 不允许我们在没有类型注释的情况下拥有顶级值定义。您可以通过
来补救这种情况a.) 通过将 {-# LANGUAGE NoMonomorphismRestriction #-}
添加到源代码的顶部来关闭限制。
b.) 向受影响的顶级绑定添加类型注释:
foo :: C a => a -> a
foo = p f
c.) 扩展函数定义(如果可能):
foo x = p f x
当你将一个简单的表达式放入 ghci 时,它基本上是在尝试 print
它,所以
> p f
与在文件中包含以下内容大致相同
main :: IO ()
main = print $ p f
正如您所指出的,p f :: (C a) => a -> a
。为了 print $ p f
GHC 需要评估 p f
。如果不选择要传入的字典,GHC 无法评估具有类型 class 上下文的值。为此,它需要为所有 a
找到一个 C a
实例,该实例不会退出.它还需要为 a -> a
找到一个 Show
实例。无法找到其中任何一个会导致两个错误
No instance for (Show (a -> a)) arising from a use of `print'
No instance for (C a) arising from a use of `p'