为什么不能推断出类型类约束而变得模棱两可?

时间:2014-02-09 01:38:28

标签: haskell typeclass

对于以下代码,

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。按照消息中的说明做帮助,但我不明白这里发生了什么。

1 个答案:

答案 0 :(得分:12)

您可以通过三种方式编译代码。

方法1

可以禁用单态限制。

{-# LANGUAGE NoMonomorphismRestriction #-}

单态限制发挥作用,因为func3未使用函数语法定义。这导致方法2:

方法2

如果您这样做了:

func3 x = func . func $ x

一切都会没事的。单态限制是一种保护您不会“意外”定义多态值的规则。众所周知,在一些常见情况下,它有点过于严格,并且偏离标准的Hindley-Milner类型推断。

方法3

当然,你可以做的最后一件事就是给你的函数一个明确的类型签名。

func3 :: Show a => a -> a
func3 = func . func

单态限制意味着任何没有函数语法声明的值(即=的左侧没有参数)都不会自动获得多态类型。