对于以下代码,
func :: Show a => a -> a
func = id
func3 = func . func
编译抱怨消息
Ambiguous type variable `c0' in the constraint:
(Show c0) arising from a use of `func'
Possible cause: the monomorphism restriction applied to the following:
func3 :: c0 -> c0 (bound at test.hs:6:1)
Probable fix: give these definition(s) an explicit type signature
or use -XNoMonomorphismRestriction.
但是,在GHCi中查询其类型可以正常工作。
*Main> :t func . func
func . func :: Show c => c -> c
这里发生了什么?有没有办法让func3
类型自动推断出来?
P.S。按照消息中的说明做帮助,但我不明白这里发生了什么。
答案 0 :(得分:12)
您可以通过三种方式编译代码。
你可以禁用单态限制。
{-# LANGUAGE NoMonomorphismRestriction #-}
单态限制发挥作用,因为func3
未使用函数语法定义。这导致方法2:
如果您这样做了:
func3 x = func . func $ x
一切都会没事的。单态限制是一种保护您不会“意外”定义多态值的规则。众所周知,在一些常见情况下,它有点过于严格,并且偏离标准的Hindley-Milner类型推断。
当然,你可以做的最后一件事就是给你的函数一个明确的类型签名。
func3 :: Show a => a -> a
func3 = func . func
单态限制意味着任何没有函数语法声明的值(即=
的左侧没有参数)都不会自动获得多态类型。