OCaml - 表达式'b list'

时间:2017-10-02 01:15:48

标签: ocaml typeerror

我正在尝试编写一个函数来检查集合(由列表表示)是否是另一个集合的子集。

我已经编写了一个辅助函数,它给了我交集:

let rec intersect_helper a b =
    match a, b with
    | [], _ -> []
    | _, [] -> []
    | ah :: at, bh :: bt ->
        if ah > bh then
            intersect_helper a bt
        else if ah < bh then
            intersect_helper at b
        else
            ah :: intersect_helper at bt

我正在尝试在子集函数中使用它(如果A是B的子集,那么A = A与B相交):

let subset a_ b_ =
    let a = List.sort_uniq a_
    and b = List.sort_uniq b_
    in intersect_helper a b;;
  

错误:此表达式的类型为“列表 - &gt; '列表但是表达式需要'b list

类型

这到底出了什么问题?我可以自己完全使用intersect_helper,但是在这里用列表调用它不起作用。根据我对'a的了解,它只是第一个参数类型的占位符。列表也不应该是'a list类型的颜色吗?

2 个答案:

答案 0 :(得分:2)

我很高兴你能解决自己的问题,但你的代码对我来说似乎非常复杂。

如果我理解正确,你需要一个函数来告诉列表是否是另一个列表的子集。换句话说,您想知道列表a 中列表b的所有元素是否都存在。

因此,你的函数的签名应该是

val subset : 'a list -> 'a list -> bool

标准库附带了各种操作列表的功能。

let subset l1 l2 =
  List.for_all (fun x -> List.mem x l2) l1

List.for_all检查列表中的所有元素是否满足给定条件。 List.mem检查列表中是否存在值。

你有它。我们来看看结果:

# subset [1;2;3] [4;2;3;5;1];;
- : bool = true

# subset [1;2;6] [4;2;3;5;1];;
- : bool = false

# subset [1;1;1] [1;1];; (* Doesn't work with duplicates, though. *)
- : bool = true

备注:使用List.for_all的一小部分优势在于它是short-circuit operator。这意味着只要项目不匹配就会停止,这样可以提高整体性能。

此外,由于您特别询问了集合,因此标准库为它们提供了一个模块。但是,集合使用起来有点复杂,因为它们需要您使用仿函数创建新模块。

module Int = struct
  type t = int
  let compare = Pervasives.compare
end

module IntSet = Set.Make(Int)

额外的开销是值得的,因为现在IntSet可以使用整个Set接口,其中包括IntSet.subset函数。

# IntSet.subset (IntSet.of_list [1;2;3]) (IntSet.subset [4;2;3;5;1]);;
- : bool = true

答案 1 :(得分:0)

而不是:

let a = List.sort_uniq a_

应该致电:

let a = List.sort_uniq compare a_