Почему эта проверка типа фрагмента Идриса не имеет явного типа?
Я только начинаю изучать Idris и работаю над книгой Type Driven Development с Idris. Одним из примеров упражнений из второй главы является написание функции, которая по заданной строке определяет среднюю длину слова в этой строке. Мое решение было следующим:
average : String -> Double
average phrase =
let werds = words phrase
numWords = length werds
numChars = the Nat (sum (map length werds)) in
cast numChars / cast numWords
Тем не менее, у меня было много проблем с этим решением из-за numChars
линия. По какой-то причине, это не проверка типов, если я не сделаю тип явно the Nat
, Ошибка гласит:
Can't disambiguate since no name has a suitable type:
Prelude.List.length, Prelude.Strings.length
Это не имеет большого смысла для меня, так как независимо от того, какое определение length
используется, тип возвращаемого значения Nat
, Это подтверждается тем фактом, что такая же последовательность операций может быть выполнена без ошибок в REPL. В чем причина этого?
2 ответа
Это действительно странно, учитывая, что если вы называете промежуточное вычисление map length werds
Затем Идрис может вывести тип:
average : String -> Double
average phrase =
let werds = words phrase
numWords = length werds
swerds = map length werds
numChars = sum swerds in
cast numChars / cast numWords
И REPL также может сделать вывод, что sum . map length . words
имеет тип String -> Nat
, Если вы не получили здесь удовлетворительного ответа, я предлагаю подать отчет об ошибке.
Это ошибка реализации. Идрис написан на Хаскеле, а не на самом Идрисе. Поскольку у Haskell нет зависимых типов, ошибки более вероятны. Возможно, однажды Идрис будет переписан сам по себе.