Возможно, немного проще понять значение этой ошибки в следующем примере:
roundTrip :: String -> String
roundTrip = show . read
Итак roundTrip
read
s String
, а затем show
s обратно в (предположительно идентичные) String
.
Но read
- это полиморфная функция: она анализирует входную строку способом, который зависит от типа вывода. Синтаксический анализ Int
- это совсем другой запрос, чем синтаксический анализ Bool
!
Разработчик решает, какую конкретную реализацию read
использовать, рассматривая предполагаемый тип возврата read
. Но в выражении show . read
промежуточным типом может быть любой тип a
, который реализует как Show
, так и Read
. Как компилятор должен выбирать реализацию?
Вы можете утверждать, что в вашем примере это не имеет значения, потому что length :: [a] -> Int
обрабатывает аргумент типа единообразно. length [zer]
всегда 1
, независимо от того, через какой экземпляр Bits
вы проходите. Такая ситуация сложна для обнаружения компилятором в целом, поэтому проще и предсказуемее просто всегда отвергать неоднозначные типы.
Вы можете решить проблему, указав конкретную аннотацию типа.
> length ([zer] :: [Bool])
1