Reputation: 1113
I was trying to understand the codes in the module Pq of these big chunk of codes about trying to create Huffman coding(I included the codes below. And As I'm not familiar with modules in Ocaml. I tried to play around with it. I'm trying to understand what <-, which seems to update values in a binding, do. Also, when can you change value in a binding.
I wrote on the toplevel let a= []
then a <- [5]
and I get an error saying "The value a is not an instance variable". But Given type 'a t = { data: 'a list array; mutable first: int }
, I wrote let c= {data= [|[1;2];[3;4]|] ; first = 22}
then c.data.(1) <- [3;4;5]
update the second list of data field in c to [3;4;5]. You type c in the toplevel and you see that the value of c changed. Is this overshadowing or actually updating. My guess is that there is no mutable keyword infront of data, So this must be overshadowing. Whereas if I wrote c.first <- 8
, I would get a mutated value.
As I'm very new to Ocaml, I appreciate your help and tolerance for my stupid questions.
In a top level,
Codes for Huffman encoding which is solution to Exercise number 50 in here:
# (* 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>
Upvotes: 2
Views: 1271
Reputation: 29136
<-
modifies the value of an array index, because arrays are mutable data structures, or a mutable record field. Hence the use of the mutable
keyword in the record definition.
You can also use <-
to update ref cells, which is really just syntax sugar for a single mutable field record.
I recommend that you read through the RWO chapter on imperative programming, where all this is explained in much more detail than will fit comfortably in an answer here.
Upvotes: 5