2011-08-18 77 views
3

我试图使用ocaml的这个线索的实现:http://www.lri.fr/~filliatr/ftp/ocaml/ds/trie.ml.htmlocaml的TRIE实施

这是我实现的模块 “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的实现(标签,中缀等)所不需要的字段。

回答

5

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

现在,Batteries.Map.S包含标准Map.S的所有类型,方法......因此,在使用trie.ml时,只有在稍后尝试应用Make时才会发现问题。但Jean-ChristopheFilliâtre在撰写文件时打算使用标准Map.S。如果您编译trie.ml而不是#使用它,Map.S将被解析为标准库。编译和加载trie.ml的另一个优点是,创建trie模块的函数将被命名为Trie.Make(同样,正如Jean-Christophe所预期的那样:单​​独的Make是不明确的,并且仅在另一个模块中被惯例使用,上下文:Hashtbl.Make,Set.Make,...)