OCaml结合Zarith库时类型信息显示不匹配问题咨询
为什么fib_acc的类型不是多态的
'a -> 'a -> 'a -> 'a -> 'a? 你的函数被推断出具体的Z.t -> Z.t -> Z.t -> Z.t -> Z.t类型,核心原因是函数内部使用了Z模块专属的类型绑定操作,OCaml的类型推断系统会根据这些操作把原本可能的多态类型锁定为具体的Z.t类型。
具体看代码里的几个关键约束点:
- 调用
Z.equal n Z.one:Z.equal的类型是Z.t -> Z.t -> bool,这要求参数n必须是Z.t类型;而Z.one本身就是Z.t常量,进一步坐实了n的类型。 - 调用
Z.add n Z.minus_one、Z.add n_1 n_2:Z.add的类型是Z.t -> Z.t -> Z.t,这意味着参与运算的n、n_1、n_2都得是Z.t,运算结果也必然是Z.t。而你把这些结果作为递归调用fib_acc的参数,自然就让所有参数和返回值的类型都被约束成Z.t了。
如果想要让函数保持多态性(即类型为'a -> 'a -> 'a -> 'a -> 'a),你需要把依赖的具体操作抽象成参数传入,而不是直接使用Z模块的函数。比如:
let rec fib_acc equal add one two minus_one n n_1 n_2 acc = if (equal n one) || (equal n two) then acc else fib_acc equal add one two minus_one (add n minus_one) n_2 (add n_1 n_2) (add n_1 n_2);;
这个版本的类型会是('a -> 'b -> bool) -> ('a -> 'a -> 'a) -> 'b -> 'b -> 'a -> 'a -> 'a -> 'a -> 'a,如果调整参数让equal的两个参数类型一致,就能得到更贴近你预期的多态类型。
内容的提问来源于stack exchange,提问作者smwikipedia
相关产品推荐
相关产品推荐

