简体   繁体   中英

What does <- mean in ocaml?

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 'at = { data: 'a list array; mutable first: int } type 'at = { data: 'a list array; mutable first: int } , I wrote let c= {data= [|[1;2];[3;4]|] ; first = 22} 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>

<- 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM