Что означает <- означает в ocaml? - PullRequest
0 голосов
/ 19 января 2019

Я пытался понять коды в модуле Pq этого большого куска кодов о попытке создать кодировку Хаффмана (я включил коды ниже. И поскольку я не знаком с модулями в Ocaml. Я пытался поиграться с этим. Я пытаюсь понять, что делает <-, который, кажется, обновляет значения в привязке. Кроме того, когда вы можете изменить значение в привязке. </p>

Я написал на верхнем уровне 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, то получил бы видоизмененное значение.

Поскольку я очень новичок в Окамле, я ценю вашу помощь и терпимость к моим глупым вопросам.

На верхнем уровне,

Коды для кодирования Хаффмана, который является решением для Упражнения № 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>

1 Ответ

0 голосов
/ 19 января 2019

<- изменяет значение индекса массива, поскольку массивы представляют собой изменяемые структуры данных или изменяемое поле записи. Отсюда использование ключевого слова mutable в определении записи.

Вы также можете использовать <- для обновления ячеек ref, что на самом деле является просто синтаксическим сахаром для одной записи изменяемого поля.

Я рекомендую вам прочитать главу RWO об императивном программировании , где все это объясняется гораздо более подробно, чем удобно будет здесь в ответе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...