Haskell多态函数(+)处理不同数值类型的类型推断原理咨询
Haskell中
1 + 3.0的类型推导逻辑 首先明确一个核心误解:Haskell中无小数点的数字字面量不是默认Int类型,带小数点的字面量也不是默认Float类型,二者本质都是多态值:
- 无小数点数字字面量的类型为
Num a => a,可以适配任意实现了Num类型类的具体类型 - 带小数点数字字面量的类型为
Fractional a => a,可以适配任意实现了Fractional类型类的具体类型(Fractional是Num的子类,天然满足Num约束)
1 + 3.0的完整推导过程如下:
(+)运算符要求两个参数类型相同,且同时满足Num约束,返回值与参数类型一致- 字面量
3.0携带Fractional约束,优先级高于普通Num约束 - 字面量
1的Num a => a类型可以兼容Fractional约束,编译器会自动将两个参数的类型统一推导为同一个实现了Fractional的具体类型(默认场景下为Double) - 最终运算结果的类型与参数一致,为对应Fractional类型
注意:这个过程不存在「Int转Float」的隐式类型转换,因为
1从始至终都没有被推导为Int类型。如果显式指定1的类型为Int,比如执行(1 :: Int) + 3.0,编译器会直接抛出类型不匹配错误,此时你需要手动调用fromIntegral将Int值转换为Fractional类型才能完成运算。
你可以在GHCi中执行以下命令验证上述逻辑:
- 查看字面量1的类型:
:t 1,返回1 :: Num p => p - 查看
1 + 3.0的类型::t 1 + 3.0,返回1 + 3.0 :: Fractional a => a - 直接求值
1 + 3.0,返回4.0,默认类型为Double
内容的提问来源于stack exchange,提问作者Pastilhas
相关产品推荐
相关产品推荐

