我有此代码:
let n = read_int()
let rec fact n = if n=0 then 1 else n*fact(n-1)
let () = Printf.printf "%d factorial is %d.\n" n fact(n)
我编译,然后编译器说:
File "fat.ml", line 3, characters 23-46:
Error: This expression has type
('a -> 'b, out_channel, unit, unit, unit, 'a -> 'b)
CamlinternalFormatBasics.fmt
but an expression was expected of type
('a -> 'b, out_channel, unit, unit, unit, unit)
CamlinternalFormatBasics.fmt
Type 'a -> 'b is not compatible with type unit
如何打印返回的值?
答案 0 :(得分:3)
问题是fact n
周围缺少括号:
let () = Printf.printf "%d factorial is %d.\n" n (fact n)
有效。
出现复杂类型错误的原因是编译器读取
let () = Printf.printf "%d factorial is %d.\n" n fact(n)
为
let () = Printf.printf "%d factorial is %d.\n" n fact n
换句话说,对于编译器,函数printf
应用于4个参数:"%d factorial is %d.\n"
,n
,fact
和n
。
但是格式字符串,我们称之为fmt
,仅包含两个%d
指定符。因此,编译器还知道printf fmt
应该接受两个参数,然后返回unit。存在差异:Printf.printf fmt n fact
将返回可应用于最后一个参数n
的函数,但它将返回unit。
换句话说,
类型'a->'b与类型单位不兼容
错误的早期部分
此表达式具有类型 ('a->'b,out_channel,unit,unit,unit,'a->'b) CamlinternalFormatBasics.fmt 但是期望一个类型的表达式 ('a->'b,out_channel,单位,单位,单位,单位) CamlinternalFormatBasics.fmt
是因为格式字符串的类型非常灵活,因此类型检查器仅在发现无法打印格式字符串并返回带有提供的参数的unit时失败。