我试图了解有关尝试创建霍夫曼编码的这些大代码块的模块Pq中的代码(我包括以下代码。由于我对Ocaml中的模块不熟悉。我尝试玩转我试图理解什么<-,似乎可以更新绑定中的值。此外,什么时候可以更改绑定中的值。
我先在顶级let a= []
上写过,然后在a <- [5]
上写了一个错误,说“值a不是实例变量”。但是给定type 'a t = { data: 'a list array; mutable first: int }
,我写了let c= {data= [|[1;2];[3;4]|] ; first = 22}
,然后c.data.(1) <- [3;4;5]
将c中的第二个数据字段列表更新为[3; 4; 5]。您在顶层键入c,您会看到c的值已更改。这是阴影还是实际更新。我的猜测是在数据的前面没有可变的关键字,因此这一定是令人难以置信的。而如果我写c.first <- 8
,我会得到一个突变值。
由于我是Ocaml的新手,非常感谢您对我的愚蠢问题的帮助和宽容。
在顶层
霍夫曼编码的代码,它是here中练习编号50的解决方案:
# (* Simple priority queue where the priorities are integers 0..100.
The node with the lowest probability comes first. *)
module Pq = struct
type 'a t = { data: 'a list array; mutable first: int }
let make() = { data = Array.make 101 []; first = 101 }
let add q p x =
q.data.(p) <- x :: q.data.(p); q.first <- min p q.first
let get_min q =
if q.first = 101 then None
else
match q.data.(q.first) with
| [] -> assert false
| x :: tl ->
let p = q.first in
q.data.(q.first) <- tl;
while q.first < 101 && q.data.(q.first) = [] do
q.first <- q.first + 1
done;
Some(p, x)
end
type tree =
| Leaf of string
| Node of tree * tree
let rec huffman_tree q =
match Pq.get_min q, Pq.get_min q with
| Some(p1, t1), Some(p2, t2) -> Pq.add q (p1 + p2) (Node(t1, t2));
huffman_tree q
| Some(_, t), None | None, Some(_, t) -> t
| None, None -> assert false
(* Build the prefix-free binary code from the tree *)
let rec prefixes_of_tree prefix = function
| Leaf s -> [(s, prefix)]
| Node(t0, t1) -> prefixes_of_tree (prefix ^ "0") t0
@ prefixes_of_tree (prefix ^ "1") t1
let huffman fs =
if List.fold_left (fun s (_,p) -> s + p) 0 fs <> 100 then
failwith "huffman: sum of weights must be 100";
let q = Pq.make() in
List.iter (fun (s,f) -> Pq.add q f (Leaf s)) fs;
prefixes_of_tree "" (huffman_tree q);;
module Pq :
sig
type 'a t = { data : 'a list array; mutable first : int; }
val make : unit -> 'a t
val add : 'a t -> int -> 'a -> unit
val get_min : 'a t -> (int * 'a) option
end
type tree = Leaf of string | Node of tree * tree
val huffman_tree : tree Pq.t -> tree = <fun>
val prefixes_of_tree : string -> tree -> (string * string) list = <fun>
val huffman : (string * int) list -> (string * string) list = <fun>
答案 0 :(得分:3)
<-
修改数组索引的值,因为数组是可变数据结构或可变记录字段。因此,在记录定义中使用mutable
关键字。
您还可以使用<-
更新ref单元,这实际上只是单个可变字段记录的语法糖。
我建议您通读the RWO chapter on imperative programming,在此详细解释所有内容,而不是在此处轻松回答。