Effects of monomorphism restriction on type class constraints

穿精又带淫゛_ 提交于 2019-12-03 22:54:47

The equations for baz are in one binding group, generalisation is done after the entire group has been typed. Without a type signature, that means baz is assumed to have a monotype, so the type of [] in the recursive call is given by that (look at ghc's -ddump-simpl output). With a type signature, the compiler is explicitly told that the function is polymorphic, so it can't assume the type of [] in the recursive call to be the same, hence it's ambiguous.

As John L said, in foo, the type is fixed by the occurrence of f - as long as f has a monotype. You can create the same ambiguity by giving f the same type as (==) (which requires Rank2Types),

{-# LANGUAGE Rank2Types #-}
foo :: Eq b => (forall a. Eq a => a -> a -> Bool) -> [b] -> Bool
foo f (x:y:_) = f x y
foo f[_] = foo f []
foo _ [] = False

That gives

Ambiguous type variable `b0' in the constraint:
  (Eq b0) arising from a use of `foo'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: foo f []
In an equation for `foo': foo f [_] = foo f []

Your second example isn't polymorphically recursive. This is because the function f appears on both the LHS and RHS of the recursive definition. Also consider the type of foo, (a -> a -> Bool) -> [a] -> Bool. This fixes the list element type to be identical to the type of f's arguments. As a result, GHC can determine that the empty list on the RHS must have the same type as the input list.

I don't think that the reads example is applicable to the baz case, because GHC is able to compile baz with no type signature and the monomorphism restriction disabled. Therefore I expect that GHC's type algorithm has some other mechanism by which it removes the ambiguity.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!