首页 > 解决方案 > OCaml - 打印递归fatorial函数返回值不起作用

问题描述

我有这个代码:

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

如何打印返回值?

标签: functionrecursionocamlfactorial

解决方案


问题是缺少括号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和。factn

但是格式字符串,我们称之为fmt,只包含两个%d说明符。因此编译器也知道printf fmt应该有两个参数,然后返回单位。存在差异:Printf.printf fmt n fact预计返回一个可应用于最后一个参数的函数,n但它返回单位。或者换句话说,

Type 'a -> 'b 与 type unit 不兼容

错误的前半部分

此表达式的类型为 ('a -> 'b, out_channel, unit, unit, unit, 'a -> 'b) CamlinternalFormatBasics.fmt 但表达式应为 ('a -> 'b, out_channel, unit, unit , 单位, 单位) CamlinternalFormatBasics.fmt

这是由于格式字符串的类型非常灵活,因此类型检查器仅在发现无法打印格式字符串并返回带有提供的参数的单位时才会失败。


推荐阅读