Functor无法正确继承签名

时间:2019-05-02 03:48:19

标签: ocaml caml

我正在OCaml中使用Bloom Bloom过滤器,我真的很困惑。

首先,我定义一个与bloom过滤器交互的签名,以便可以通过多种不同方式实现bloom过滤器:

module type memset = sig
    type elt (* type of values stored in the set *)
    type t (* abstract type used to represent a set *)
    val mem : elt -> t -> bool
    val empty : t
    val is_empty : t -> bool
    val add : elt -> t -> t
    val from_list : elt list -> t
    val union : t -> t -> t
    val inter : t -> t -> t
  end

bloom过滤器当前有两个实现:

SparseSet
通过使用列表存储所有整数来实现SparseSet。

module SparseSet : (memset with type elt = int) = struct
    include Set.Make(struct
        let compare = Pervasives.compare
        type t = int
    end)

    let from_list l = List.fold_left (fun acc x -> add x acc) empty l
end

BoolSet
通过存储一个布尔数组来实现布隆过滤器,其中,如果对应的索引= true,则整数是集合的成员。

module BoolSet : (memset with type elt = int) = struct
    type elt = int
    type t = bool array

    (* implementation details hidden for clarity's sake *)
  end

为了存储集合中是否存在不是整数的项目,我定义了一个hasher签名:

module type hasher = sig
    type t (* the type of elements that are being hashed *)
    val hashes : t -> int list
end

最后,我定义一个Filter函数,该函数接受Bloom过滤器实现和哈希器。要添加项目,将使用三种不同的方法对项目进行哈希处理以生成3个整数。这三个整数存储在传递给Filter函数的基础memset模块中。要检查集合中是否存在某个项目,请获取并检查其3个散列。如果集合中存在所有三个哈希整数,则该项目包含在集合中。过滤函子允许实现布隆集,并且可以替换掉哈希方法:

module Filter (S : memset) (H : hasher)
    : memset
    with type elt = H.t
    with type t = S.t = struct

    type elt = H.t
    type t = S.t

    let mem x arr = [] = List.filter (fun y -> not (S.mem y arr)) (H.hashes x)
    let empty = S.empty
    let is_empty = S.is_empty
    let add x arr = List.fold_left (fun acc x -> S.add x acc) empty (H.hashes x)
    let add x arr = empty
    let from_list l = S.from_list l
    let union l1 l2 = S.union l1 l2
    let inter l1 l2 = S.inter l1 l2
  end

当我尝试编译该程序时,在过滤器函子的memaddfrom_list函数处收到以下编译时错误:

File "bloom.ml", line 75, characters 66-78:
Error: This expression has type int list but an expression was expected of type
         S.elt list
       Type int is not compatible with type S.elt 

由于某种原因,在“过滤器”模块中无法正确传递类型。有人对如何解决此问题有任何建议吗?我一直在梳理头发,试图弄清楚。

1 个答案:

答案 0 :(得分:2)

module Filter (S : memset) (H : hasher) = ...

表示函子应该适用于任何memset,而与元素S.elt的类型无关。但是,函子主体假定S.eltint,导致类型错误:

 Type int is not compatible with type S.elt

您可以通过在参数签名中指定S.elt的类型来解决此问题:

module Filter (S : memset with type elt = int) (H : hasher) = ...