Ocaml TRIE实施

时间:2011-08-18 20:55:31

标签: ocaml trie ocaml-batteries

我正在尝试将这个trie实现用于ocaml:http://www.lri.fr/~filliatr/ftp/ocaml/ds/trie.ml.html

这是我对模块“M”的实现:

module M =
    struct     
    type key = int
    type 'a t = (int * 'a) list
    let empty = []
    let equal x y = false
    let compare f x y = 1

    let find x l = 
        let pred e = fst e == x in
        let z = List.find pred l in
        snd z

    let add x t m = (x,t)::m

    let remove x m = filter (fun e -> fst e != x) m

    let map f m = 
        let aux (x,y) = (x, f y) in
        List.map aux m

    let mapi f m =
        let aux i (x,y) = (x, f i y) in
        List.mapi aux m

    let mem x m = 
        let l = List.map snd m in
        List.mem x l

    let iter f m =
        let aux x = f (snd x) in
        List.iter aux m

    let fold f m acc1 =
        let aux acc x = f acc (snd x) in
        List.fold_left aux acc1 m               

    let is_empty m = m == empty

end;;

忽略不正确的语义(等于,比较等)。

我正在使用ocaml电池,这就是我尝试这项工作的方式:

# #use "trie.ml";;
module Make :
  functor (M : Batteries.Map.S) ->
    sig
      type key = list M.key;
      type t 'a = [ Node of option 'a and M.t (t 'a) ];
      value empty : t 'a;
      value find : list M.key -> t 'a -> 'a;
      value mem : list M.key -> t 'a -> bool;
      value add : list M.key -> 'a -> t 'a -> t 'a;
      value remove : list M.key -> t 'a -> t 'a;
      value map : ('a -> 'b) -> t 'a -> t 'b;
      value mapi : (list M.key -> 'a -> 'b) -> t 'a -> t 'b;
      value iter : (list M.key -> 'a -> 'b) -> t 'a -> unit;
      value fold : (list M.key -> 'a -> 'b -> 'b) -> t 'a -> 'b -> 'b;
      value compare : ('a -> 'a -> int) -> t 'a -> t 'a -> int;
      value equal : ('a -> 'a -> bool) -> t 'a -> t 'a -> bool;
      value is_empty : t 'a -> bool;
    end
# #use "m.ml";;
module M :
  sig
    type key = int;
    type t 'a = list (int * 'a);
    value empty : list 'a;
    value equal : 'a -> 'b -> bool;
    value compare : 'a -> 'b -> 'c -> int;
    value find : 'a -> list ('a * 'b) -> 'b;
    value add : 'a -> 'b -> list ('a * 'b) -> list ('a * 'b);
    value remove : 'a -> BatEnum.t ('a * 'b) -> BatEnum.t ('a * 'b);
    value map : ('a -> 'b) -> list ('c * 'a) -> list ('c * 'b);
    value mapi : (int -> 'a -> 'b) -> list ('c * 'a) -> list ('c * 'b);
    value mem : 'a -> list ('b * 'a) -> bool;
    value iter : ('a -> unit) -> list ('b * 'a) -> unit;
    value fold : ('a -> 'b -> 'a) -> list ('c * 'b) -> 'a -> 'a;
    value is_empty : list 'a -> bool;
  end

# module X = Make(M);;
Error: Signature mismatch:
       Modules do not match:
         sig
           type key = int;
           type t 'a = list (int * 'a);
           value empty : list 'a;
           value equal : 'a -> 'b -> bool;
           value compare : 'a -> 'b -> 'c -> int;
           value find : 'a -> list ('a * 'b) -> 'b;
           value add : 'a -> 'b -> list ('a * 'b) -> list ('a * 'b);
           value remove : 'a -> BatEnum.t ('a * 'b) -> BatEnum.t ('a * 'b);
           value map : ('a -> 'b) -> list ('c * 'a) -> list ('c * 'b);
           value mapi : (int -> 'a -> 'b) -> list ('c * 'a) -> list ('c * 'b);
           value mem : 'a -> list ('b * 'a) -> bool;
           value iter : ('a -> unit) -> list ('b * 'a) -> unit;
           value fold : ('a -> 'b -> 'a) -> list ('c * 'b) -> 'a -> 'a;
           value is_empty : list 'a -> bool;
         end
       is not included in
         Batteries.Map.S
       The field `Labels' is required but not provided
       The field `Infix' is required but not provided
       The field `Exceptionless' is required but not provided
       The field `print' is required but not provided
       The field `of_enum' is required but not provided
       The field `backwards' is required but not provided
       The field `enum' is required but not provided
       The field `choose' is required but not provided
       The field `max_binding' is required but not provided
       The field `min_binding' is required but not provided
       The field `values' is required but not provided
       The field `keys' is required but not provided
       The field `filter_map' is required but not provided
       The field `filteri' is required but not provided
       The field `filter' is required but not provided
       The field `modify' is required but not provided
# 

我不明白这个错误。在我看来,我的模块“M”的实现中的方法类型是有效的。

我也不明白为什么ocaml需要TRIE实现不需要的字段(标签,中缀等)。

1 个答案:

答案 0 :(得分:6)

您必须先在您的顶层输入类似open Batteries;;的内容。 因此,trie.ml中的module Make (M : Map.S) = struct被解释为定义签名Make参数的仿函数Batteries.Map.S

现在,Batteries.Map.S包含标准Map.S的所有类型,方法......,所以当你尝试使用#using trie.ml时,你不会注意到这个问题申请Make。但是Jean-ChristopheFilliâtre在撰写文件时打算使用标准Map.S。如果你编译了trie.ml而不是#using它,那么Map.S就会被解析为标准库了。编译和加载trie.ml的另一个好处是,创建trie模块的仿函数将被命名为Trie.Make(再次,如Jean-Christophe所预期的那样:Make单独是模糊的,仅用于按惯例,在给出上下文的另一个模块中:Hashtbl.MakeSet.Make,...)