【问题标题】:Set notation OCaml设置符号 OCaml
【发布时间】:2013-02-04 03:14:30
【问题描述】:

这只是一个关于 OCaml 中的符号的问题。

我正在尝试测试功能

let rec add (x : 'a) (l : 'a set) : bool =
begin match l with
| [] -> []
| hd :: rest -> if x = hd then rest else (hd :: (add x rest))
end

我的测试用例是

let test () : bool =
add (3 [1; 2; 4]) = [1; 2; 3; 4]
;; run_test "add 3 [1; 2; 4]" test

我收到“此表达式不是函数,无法应用”错误

我的符号有问题吗?

【问题讨论】:

  • 错误来自(3 [1; 2; 4]),您将3 应用到[1; 2; 4]。在上下文中,您可能打算将函数add 应用于参数3[1; 2; 4]。您可以使用符号add 3 [1; 2; 4] 执行此操作

标签: ocaml


【解决方案1】:

OCaml 没有内置的集合类型(而是有一个 Set 模块或库)。因此,集合常量也没有内置符号。

对于较小的集合,通常使用列表。而且,事实上,List.mem 是一个对列表(而不是集合)进行操作的函数。列表的符号如下:[1; 2; 3; 4]

(作为旁注,您的名为 add 的函数没有添加任何内容。但也许您才刚刚开始。)

【讨论】:

  • 谢谢!我实际上编辑了我的帖子,我的功能出错了。现在我得到了另一个错误,即使我改变了它。它指的是什么?
  • OCaml 中的函数参数没有括号。拨打add你想:add 3 [1; 2; 4]。我看到了其他一些问题,但一次只有一件事!
  • 我改变了我的添加功能。我认为递归部分可能有问题,但我不太确定它是什么。
  • 实际上递归对我来说看起来不错。但其他东西是错误的。想想 (a) 当元素已经在集合中时 (b) 函数的返回类型 (c) 如何判断两个集合是否相等。
  • 如果您选择将集合保留为排序列表,则没有区别。如果您只需要测试成员资格并插入值,则不需要保持排序。如果您有强烈的要求和大量的元素,请使用真实的集合(如 gasche 建议的那样)。
【解决方案2】:

OCaml 中没有集合表示法。我不知道您的'a set 类型是什么,我不明白为什么要使用List.mem 测试成员资格,但它应该没有特定的符号。

标准库中有一个Set.Make 函子,由一个模块实例化,该模块至少有一个类型和一个键上的比较函数(see here):

module StringSet = Set.Make(String)
let set = StringSet.(add 0 (add 1 (add 2 empty)))
let test = StringSet.mem 3 set

如果您想要一种方便的表示法,最好的办法是使用从列表到集合的转换函数,并使用列表表示法:

let set_of_list li = List.fold_left (fun s v -> StringSet.add v s) StringSet.empty li
let set = set_of_list [0; 1; 2]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    • 1970-01-01
    • 2021-03-04
    相关资源
    最近更新 更多