Почему я не могу написать предполагаемый тип runcountacc в коде?
Короткий ответ: если вы создали полиморфную рекурсию по ошибке, то вывод типа не должен работатьвообще, если присутствует полиморфная рекурсия.
GHC дает лучшее сообщение об ошибке:
orig.hs:5:24:
Ambiguous type variable `a0' in the constraint:
(Eq a0) arising from a use of `runcountacc'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: runcountacc (n + 1) []
In an equation for `runcountacc':
runcountacc n (_ : []) = runcountacc (n + 1) []
Там он не может вывести тип для правой стороны []
.Следующая подпись решает проблему, потому что без нее не ясно пустой список того, что следует использовать:
runcountacc n (_:[]) = runcountacc (n+1) ([] :: [a])
У нас есть некая (бесконечная) полиморфная рекурсия здесь.Тип пустого списка справа может быть любым, и GHC не может понять, какой именно.Например, все еще действует следующее:
runcountacc n (_:[]) = runcountacc (n+1) ([] :: [String])
Вопрос о том, почему проблема исчезает без сигнатур типов, остается открытым.
Идея @pigworker заключается в том, что если вы опустите сигнатуры,Haskell запрещает полиморфную рекурсию, и с мономорфным рекурсией нет никакой двусмысленности.
Примечание: у вас неправильный базовый случай рекурсии - бесконечный цикл не должен появляться на первом месте.