if语句出现Ocaml错误

时间:2012-02-16 06:02:51

标签: hash ocaml

我有一份清单,例如[[1; 2; 3]; [2]; [3; 4; 5; 6]; [7; 8; 9; 10] 我想将它们放在Hashtbl中,其中键是列表的长度,值是列表列表,其中包含给定长度的所有子列表。

因此,对于上面的示例,哈希将如下所示

Key            Value
 1              [[2]]
 3              [[1;2;3]]
 4              [[3;4;5;6];[7;8;9;10]]

此外,我还试图跟踪最长列表的长度,该数字是函数返回的数字

执行此操作的代码如下。

let hashify lst =
    let hash = Hashtbl.create 123456 in 
        let rec collector curmax lst =
            match lst with 
                    [] -> curmax 
                | h::t -> let len = (List.length h) in 
                                (if ((Hashtbl.mem hash len)=true)
                                then ( let v = (Hashtbl.find hash len) in Hashtbl.add hash len v@[h] ) (* Line 660 *)
                                else ( Hashtbl.add hash len [h]));

                                (collector (max len curmax) t)
        in 
        collector 0 lst
    ;;

现在当我这样做时,上面的代码出现以下错误

File "all_code.ml", line 600, characters 50-72:
Error: This expression has type unit but an expression was expected of type
     'a list

为什么Ocaml需要返回类型的'列表,我该如何解决这个问题。 提前致谢 普尼特

3 个答案:

答案 0 :(得分:4)

您可能应该在(v@[h])中添加括号,以避免将其解析为(Hashtbl.add hash len v)@[h]

您可能不应该将123456传递给Hashtbl.create,而应该将合理的素数传递给307或2017

答案 1 :(得分:4)

你几乎就在那里:@的优先级低于apply,因此,正如Basil所说,Hashtbl.add hash len v@[h]被解析为(Hashtbl.add hash len v)@[h]。而且,你使用太多括号,if ((Hashtbl.mem hash len)=true)是不必要的冗长。因此,编写函数的可能方法是:

let hashify lst =
  let hash = Hashtbl.create 307 in 
  let rec collector curmax = function
    | [] -> curmax 
    | h::t ->
      let len = List.length h in 
      if Hashtbl.mem hash len then
        let v = Hashtbl.find hash len in
        Hashtbl.add hash len (v@[h])
      else
        Hashtbl.add hash len [h];
      collector (max len curmax) t in 
  collector 0 lst

答案 2 :(得分:4)

OCaml中对哈希表的大量工作极大地受益于更新原语。实际上有两个版本,它们根据表中是否存在值来执行不同的操作。这是你想要使用的那个:

(* Binds a value to the key if none is already present, and then updates
   it by applying the provided map function and returns the new value. *)
let update hashtbl key default func = 
  let value = try Hashtbl.find hashtbl key with Not_found -> default in 
  let value' = func value in
  Hashtbl.remove hashtbl key ; Hashtbl.add hashtbl key value' ; value'

使用这些原语,管理列表哈希表变得简单:

let prepend hashtbl key item = 
  update hashtbl key [] (fun list -> item :: list) 

从那里,遍历列表并将所有内容附加到哈希表非常简单:

let hashify lst =
  let hash = Hashtbl.create 607 in 
  List.fold_left (fun acc list -> 
    let l = List.length list in
    let _ = prepend hash l list in 
    max acc l
  ) 0 lst