我想编写一个将数组中的元素从一个地方复制到另一个地方的函数。 copy_obj就是这样做的功能。现在我给出了一个指针列表,表示我需要复制的元素的位置,因此我需要在列表中的每个元素上应用函数copy_obj,以及我应该开始复制的空闲位置的地址。在我的代码中,它是f。
考虑到函数copy_obj返回一对地址,一个是free的更新值,我需要用来递归调用列表中其他元素的函数。
下面是我编写的代码,它编译但是我在| h::tl -> copy_obj f h
发出警告说这个"表达式应该有类型单位"
我该怎么做才能安排?
let rec funct f myList =
match myList with
| [] -> f
| h::tl->
copy_obj f h;
match (copy_obj f h) with
| (free_n,addr_n) -> funct free_n tl
答案 0 :(得分:4)
你好像是另一个写着Copy GC的学生。 : - )
表达式e1; e2
将按顺序执行e1
和e2
,通常e1
的返回类型应为unit
,这意味着“返回没什么特别的”。如果e1
是一个类型不是unit
的表达式,则OCaml编译器会发出警告:“表达式应该具有类型单位”,因为您可以通过e1
计算有意义的内容但是你扔掉它。它有时是可能的错误的良好迹象。
在您的情况下,copy_obj f h
会返回一个元组,可能是(int * int)
,而不是unit
。因此你得到了警告。如果您确实可以放弃计算结果,则必须写ignore (copy_obj f h)
,其中ignore : 'a -> unit
。
你曾两次致电copy_obj f h
,这看起来很奇怪。如果没有函数的定义,我们无法100%确定,但我猜您不需要第一次调用:
let rec funct f myList =
match myList with
| [] -> f
| h::tl->
match copy_obj f h with
| (free_n,addr_n) -> funct free_n tl
如果您正在实施复制GC,并且如果copy_obj
将对象h
复制到使用副作用的可用位置,则在此处调用该函数两次将h
存储两次。对于GC算法来说,这将是一个严重的错误。警告实际上试图帮助你在这一点!
还有一件事。 match
并不是解构价值的唯一方法。 let
也可以提取元组的元素。通常我们这样写:
let rec funct f myList =
match myList with
| [] -> f
| h::tl->
let (free_n, addr_n) = copy_obj f h in
funct free_n tl
或者你可以简单地写funct (fst (copy_obj f h)) tl
。