From: Andrew <newsgroups.fr@gmail.com>
To: <caml-list@inria.fr>
Subject: [Caml-list] Strange syntax used in queue.ml -- The "<-" operator
Date: Thu, 20 Jan 2011 17:53:28 +0100 [thread overview]
Message-ID: <4d386889.027bd80a.187c.ffffbda4@mx.google.com> (raw)
Hello everyone,
While browsing the Caml Light library for programming examples, I stumbled
across the following code, taken from the Caml Light queue.ml file:
type 'a queue_cell =
Nil
| Cons of 'a * 'a queue_cell ref
;;
type 'a t =
{ mutable head: 'a queue_cell;
mutable tail: 'a queue_cell }
;;
let add x = function
{ head = h; tail = Nil as t } -> (* if tail = Nil then head = Nil
*)
let c = Cons(x, ref Nil) in
h <- c; t <- c
| { tail = Cons(_, ref newtail) as oldtail } ->
let c = Cons(x, ref Nil) in
newtail <- c; oldtail <- c
;;
This implementation of FIFO data structures puzzles me. I get the general
idea, to keep a pointer to the last entry in the structure, so that
appending at the end is possible. This makes perfect sense to me. However,
it's the syntax of how this is done that bugs me.
Consider the following:
| { tail = Cons(_, ref newtail) as oldtail } ->
let c = Cons(x, ref Nil) in
newtail <- c; oldtail <- c
I have a problem with types here. By the type definition, "newtail" should
be of type "'a queue cell", since it's retrieved using "Cons(_, ref
newtail)" in the pattern matching: if I understand correctly, this would
mean that "newtail" binds the value pointed by the second member of the
"tail" record field (which is a reference).
So what does the "newtail <- c" means? If I try to replace this statement by
"(fun x -> x <- c) newtail", I get a "The identifier x is not mutable.",
whereas the code sounds perfectly similar to the original variant to me.
Would rewriting these few lines to read as follows mean the same?
| { tail = Cons(_, newtail) as oldtail } ->
let c = Cons(x, ref Nil) in
newtail := c; oldtail <- c
Taking the question one step further, what does the following code actually
do?
type t = Nil | Node of (t ref);;
type box = {mutable field: t};;
let poke = function
| {field = Node(ref n)} -> n <- Nil
| {field = Nil} -> ()
;;
let test = {field = Node(ref (Node(ref Nil)))};;
poke test;;
test;;
Is it the same to write
{field = Node(n)} -> n := Nil
and
{field = Node(ref n)} -> n <- Nil
?
Even stranger: the following code returns "The value identifier a is
unbound."
let a = Nil;;
a <- Nil;; (* The value identifier a is unbound. *)
Could someone take the time to clarify the use of "<-" for me? The various
examples here are pretty puzzling to me...
Thanks!
next reply other threads:[~2011-01-20 16:53 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-20 16:53 Andrew [this message]
2011-01-20 17:43 ` bluestorm
2011-01-20 19:44 ` bluestorm
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4d386889.027bd80a.187c.ffffbda4@mx.google.com \
--to=newsgroups.fr@gmail.com \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox