我刚刚开始学习Idris,我正在阅读使用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中可以无错误地完成相同的操作序列。这是什么原因?
答案 0 :(得分:2)
这确实是一个奇怪的假设,如果你命名中间计算map length werds
,那么Idris能够推断出类型:
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
。如果你在这里没有得到任何满意的答案,我建议你提交a bug report。
答案 1 :(得分:0)
这是一个实施错误。 Idris是用Haskell而不是Idris编写的。由于Haskell没有依赖类型,因此更有可能出现错误。或许,有一天,伊德里斯将会被改写。