我正在尝试通过附加到列表来创建唯一列表,但是我收到了这个错误。
Error: This expression has type 'a list
but an expression was expected of type unit
in_list是一个布尔函数,用于检查值是否在列表中。
if(in_list x seen_list) then print_string("Already found") else seen_list@x in
List.iter uniq check_list;;
似乎我需要为append函数修复一些小的语法错误。建议?
答案 0 :(得分:1)
根据您的代码,您似乎相信OCaml中的列表是可变的,而它们不是。因此seen_list@x
计算新列表但不会更改seen_list
。
您可以将代码更改为
let uniq seen_list x =
if in_list x seen_list then
(Printf.printf: "uniq: %d: Already seen.\n" x; seen_list)
else x :: seen_list
in
List.fold_left uniq [] check_list
uniq
函数将整数列表映射到整数列表而不重复,记录它跳过的条目。
这段代码显然是学习材料,我想,不过你应该知道它很可能实现了Shlemiel the painter's algorithm。
答案 1 :(得分:0)
这是类型错误,而不是语法错误。
OCaml函数必须始终返回相同类型的结果。现在,当项目在列表中时,您的函数会尝试返回与项目不在列表中的类型不同的类型。
具体来说,当项目已经存在时,您的函数会调用print_string
,并返回()
。这称为unit
,是一个占位符,表示没有任何有趣的值。当项目尚未存在时,您的函数将返回类型'a list
的值。几乎可以肯定,您需要做的就是在所有情况下都返回一个列表。
如果没有看到更多代码,很难说更多,但处理这种情况的最常用方法是在项目已经存在时返回旧列表,并在项目不存在时返回新的更长列表已经在那里了。
<强>更新强>
此代码中有许多问题需要解决,但这是我假设的练习点。
你的下一个问题似乎是List.iter
是一个命令功能,即它想要做某事而不是产生结果。因此,它在列表上迭代的函数应该返回单元(如上所述)。您正在使用函数uniq
代替,它会返回一个列表。
如果你想使用像List.iter
这样优秀的OCaml风格的高阶函数,你需要使用折叠(List.fold_left
或List.fold_right
),其目的是累积结果。