Haskell调用预定义列表出现Integer与Int类型不匹配错误如何解决?
问题成因
- 首先澄清一个认知偏差:
myList不是函数,是顶级值绑定,Haskell中纯值一旦绑定就固定,不会每次调用重新计算。 - 报错核心原因是类型不匹配:
length函数的返回值类型固定为Intdiv函数要求两个输入参数必须是同一Integral类型,类型签名为div :: Integral a => a -> a -> a- 直接在GHCI输入
average [1,2,3,4]时,类型推导会自动把列表元素匹配为Int,sum的结果也是Int,和length返回的Int类型匹配,所以运行正常 - 顶级定义的
myList没有显式指定类型时,Haskell的默认类型推导规则会把数字字面量推导为Integer(任意精度整数类型),sum myList的结果是Integer,和length返回的Int类型不符,触发类型错误。
解决方法
以下是三种常用可行方案:
- 方案1:给
myList显式指定[Int]类型
代码修改为:
显式约束列表元素为myList :: [Int] myList = [1, 2, 3, 4, 5, 6, 7]Int类型后,sum结果就和length返回值类型匹配。 - 方案2:修改
average函数适配不同整数类型,通用性更强
使用fromIntegral函数把length返回的Int转为通用Integral类型:
该方案下不管输入列表元素是average ns = sum ns `div` fromIntegral (length ns)Int还是Integer都可以正常运行。 - 方案3:给
average函数显式指定输入输出类型
代码修改为:
强制约束输入必须为average :: [Int] -> Int average ns = sum ns `div` length ns[Int]类型,调用时如果传入元素为Integer的列表会提前触发明确的类型提示。
内容的提问来源于stack exchange,提问作者Pastilhas
相关产品推荐
相关产品推荐

