我正在尝试在for循环上将(int * int)类型的元组添加到列表中,但是我收到一条错误消息:该表达式应具有类型单位。
这就是我现在拥有的:
let addtuple k lst =
for i=0 to k - 1 do
let (n,j) =Scanf.scanf " %d %d" (fun a b->(a,b))
in
(n,j)::lst
done;;
答案 0 :(得分:3)
OCaml for
的目的是做,而不是计算值。因此,循环的主体应该是具有有用副作用(例如打印值)的OCaml表达式。因此,for
循环的主体应具有类型unit
,该类型用于没有有趣值的表达式。但是您的循环的主体是一个列表。编译器告诉您(正确),这表明有问题。
您编写的代码假定表达式(n, j) :: lst
将更改lst
的值。但这种情况并非如此。在OCaml这样的功能语言中,您无法更改变量的值。
如果您的函数应该返回列表,则它不能基于for
循环,该循环始终返回()
(类型为unit的唯一值)。很有可能应该基于折叠(在处理一系列输入时会累积一个值)或您自己的递归函数。
答案 1 :(得分:1)
使用for
时,您需要使用ref
:
let addtuple k lst =
let r = ref lst in
for i = 1 to k do
r := (Scanf.scanf " %d %d" (fun x y -> (x, y))) :: !r
done;
!r;;
使用递归函数的更具功能性的方法:
let rec addtuple k lst =
match k with
| 0 -> lst
| _ -> addtuple (k - 1) ((Scanf.scanf " %d %d" (fun x y -> (x, y))) :: lst);;