Уравнения для baz
находятся в одной группе связывания, обобщение выполняется после того, как была напечатана вся группа. Без сигнатуры типа это означает, что baz
предполагается, что имеет монотип, поэтому тип []
в рекурсивном вызове задается этим (посмотрите на вывод -hddump-simp ghc). С сигнатурой типа компилятору явно говорят, что функция полиморфна, поэтому он не может предположить, что тип []
в рекурсивном вызове будет таким же, следовательно, он неоднозначен.
Как сказал Джон Л., в foo
тип фиксируется появлением f
- до тех пор, пока f
имеет монотип. Вы можете создать ту же неоднозначность, задав f
того же типа, что и (==)
(для этого требуется 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
Это дает
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 []