调用 OCaml 函数,例如:'a hash_entry list array -> string -> 'a -> unit

Calling OCaml functions like: 'a hash_entry list array -> string -> 'a -> unit

我正在阅读一本关于 OCaml 的书,我是 OCaml 的新手,所以我正在做练习和示例——尽管不是所有的东西都能编译。 在这种情况下,我今晚的项目是一个哈希 table 的示例,它可以编译并且非常有趣,但我无法让它工作。

let random_numbers =
  [|0x316666;   0x2d331c;   0x4de673;   0x63a91e;   0x87bee8|]
let random_length = Array.length random_numbers
type hash_info = { mutable hash_index : int; mutable hash_value : int }
let hash_char info c =
  let i = Char.code c in
  let index = (info.hash_index + i + 1) mod random_length in
info.hash_value <- (info.hash_value * 3) lxor random_numbers.(index);
info.hash_index <- index
let hash s =
  let info = { hash_index = 0; hash_value = 0 } in
  for i = 0 to String.length s - 1 do
    hash_char info s.[i]
  done;
  info.hash_value
type 'a hash_entry = { key : string; value : 'a }
type 'a hash_table = 'a hash_entry list array
let create () =
  Array.make 101 []
let add table key value =
  let index = (hash key) mod (Array.length table) in
  table.(index) <- { key = key; value = value } :: table.(index)
let rec find_entry key = function
  { key = key' ; value = value } :: _ when key' = key -> value
  | _ :: entries -> find_entry key entries
  | [] -> raise Not_found
let find table key =
    let index = (hash key) mod (Array.length table) in
    find_entry key table.(index);;

不幸的是,作者会说 'a string -> unit 会这样做或那样做,但实际上并非如此。例如,我正在处理的是:

utop # add = { key = "9999999" ; value = "one of these days" };;
Line 1, characters 6-55:
Error: This expression has type string hash_entry
       but an expression was expected of type
         'a hash_entry list array -> string -> 'a -> unit

我对这些广泛的陈述感到沮丧。这是什么意思?

'a hash_entry list array -> string -> 'a -> unit

我不是要它的各个部分的定义,我如何使用这个语句来调用函数?我知道理解其中的各个部分当然很重要,这些东西是如何工作的?几天过去了,再举一个例子,我被困在期待类型单位上,“类型单位”到底应该是什么? 具体来说,我如何生成这个(知道它需要一个 key/value 对):

'a hash_entry list array -> string -> 'a -> unit

这是您遇到问题的表达方式:

add = { key = "9999999" ; value = "one of these days" }

这是一个表达式,但不是对 add 的调用。 add 是一个有 3 个参数的函数,所以调用看起来像这样:

add mytable mykey myvalue

相反,这个表达式是一个比较,即它测试两个事物是否相等。那是因为表达式中唯一的运算符是 =,即相等比较运算符。

由于 add 是一个函数,它甚至不是与记录比较的正确类型,记录比较的右侧显示的是什么。所以这就是解释器出错的原因。

如果您想测试添加的调用,它看起来更像这样:

# let table = create ();;
val table : '_weak1 list array = ...
# add table "mykey" "myvalue";;
- : unit = ()
# find table "mykey";;
- : string = "myvalue"

斯科菲尔德先生的指示是这样的:

val create : unit -> 'a list array = <fun>
val add : 'a hash_entry list array -> string -> 'a -> unit = <fun>
val find_entry : string -> 'a hash_entry list -> 'a = <fun>
val find : 'a hash_entry list array -> string -> 'a = <fun>
─( 19:55:55 )─< command 30 >─────────────────────────────────────{ counter: 0 }─
utop # let table = create ();;
val table : '_weak2 list array =
  [|[]; []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; 
    []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; 
    []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; 
    []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; 
    []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; 
    []; []; []; []; []; []; []; []; []; []; []; []; []; []; []; []|]
─( 20:14:42 )─< command 31 >─────────────────────────────────────{ counter: 0 }─
utop # add table "mykey" "myvalue";;
- : unit = ()
─( 20:14:58 )─< command 32 >─────────────────────────────────────{ counter: 0 }─
utop # find table "mykey";;
- : string = "myvalue"
─( 20:15:15 )─< command 33 >─────────────────────────────────────{ counter: 0 }─

val create (unit -> 'a list array = ) val add ('a hash_entry list array -> string -> 'a -> unit = ) 和 val find ('a hash_entry 列表数组 -> 字符串 -> 'a = )

谢谢杰弗瑞·斯科菲尔德