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

shh*_*you 7 haskell typeclass

对于以下代码,

func :: Show a => a -> a
func = id

func3 = func . func
Run Code Online (Sandbox Code Playgroud)

编译抱怨消息

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

但是,在GHCi中查询其类型可以正常工作.

*Main> :t func . func
func . func :: Show c => c -> c
Run Code Online (Sandbox Code Playgroud)

这里发生了什么事?有没有办法让func3自动推断的类型?

ps按照消息中的说明执行帮助,但我不明白这里发生了什么.

Die*_*Epp 12

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

方法1

可以禁用单态限制.

{-# LANGUAGE NoMonomorphismRestriction #-}
Run Code Online (Sandbox Code Playgroud)

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

方法2

如果你这样做了:

func3 x = func . func $ x
Run Code Online (Sandbox Code Playgroud)

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

方法3

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

func3 :: Show a => a -> a
func3 = func . func
Run Code Online (Sandbox Code Playgroud)

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