我正在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
当我尝试编译该程序时,在过滤器函子的mem
,add
和from_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
由于某种原因,在“过滤器”模块中无法正确传递类型。有人对如何解决此问题有任何建议吗?我一直在梳理头发,试图弄清楚。
答案 0 :(得分:2)
行
module Filter (S : memset) (H : hasher) = ...
表示函子应该适用于任何memset,而与元素S.elt
的类型无关。但是,函子主体假定S.elt
为int
,导致类型错误:
Type int is not compatible with type S.elt
您可以通过在参数签名中指定S.elt
的类型来解决此问题:
module Filter (S : memset with type elt = int) (H : hasher) = ...