根据OCaml中的条件附加到列表

时间:2016-07-16 19:13:52

标签: list integer append ocaml

我正在尝试通过附加到列表来创建唯一列表,但是我收到了这个错误。

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函数修复一些小的语法错误。建议?

2 个答案:

答案 0 :(得分:1)

TL; DR:列表在OCaml

中是不可变的

根据您的代码,您似乎相信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_leftList.fold_right),其目的是累积结果。