From: Cedric Auger <Cedric.Auger@lri.fr>
To: Joel Christner <joel.christner@gmail.com>
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Newbie list question
Date: Wed, 13 May 2009 20:06:34 +0200 [thread overview]
Message-ID: <4A0B0C2A.6010303@lri.fr> (raw)
In-Reply-To: <9da743ed0905131024u53a207f0s9e963be782f3f2c6@mail.gmail.com>
Joel Christner a écrit :
> Hello,
>
> I posted this question on a couple of newsgroups as well, please
> pardon the cross-posting and the newbie question.
>
> What I'm wanting to do is create a ref list that contains a series of
> strings, i.e.
> # let varlist = ref [];;
> # let a = "a";;
> # let b = "b";;
> # let c = "c";;
>
> Then throughout the course of program operation, I will be adding data
> into this list, i.e.:
> # varlist.contents <- a::varlist.contents;;
> # varlist.contents <- b::varlist.contents;;
> # varlist.contents <- c::varlist.contents;;
I don't know if you know it, but there exist a notation: "!varlist" as
syntactic sugar for "varlist.contents"
>
> Which is working fine, i.e.
> # varlist.contents;;
> - : string list = ["c"; "b"; "a"]
>
> But what I'm trying to do next I can't figure out how to get working.
> What I'd like to do is have a function that first checks to see if the
> item is already in the ref list. If it is, do nothing. If it isn't,
> add it. Here's what I tried, which is of course failing. If anyone has
> a suggestion on how to make it work would you please help me out?
>
> # let rec addvariable stringdata listname =
> match listname.contents with
> | [] -> (listname.contents <- stringdata::listname.contents); ()
> | [a] -> if a.contents = stringdata then () else (listname.contents <-
> stringdata::listname.contents); ()
> | h::t -> if h.contents = stringdata then () else addvariable
> stringdata t.contents
> ;;
>
> Which returns...
> This expression has type 'a ref but is here used with type 'a
> #
Hopefully!
You want listname to be a (string list) ref, so:
* !listname (listname.contents) is a string list
* addvariable has type string -> (string list) ref -> unit
but your recursive call is:
addvariable stringdata !t
where t is a string list (since h::t=!listname), so t has no field
"contents", so !t has no meaning;
and even if it had a meaning it should be of type string list which
can't be applied to addvariable (which expects a (string list) ref)
A solution should be:
# let addvariable stringdata listnameref =
let rec av listname =
match listname with
| [] -> stringdata::listname
| [a] -> if a = stringdata then listname else stringdata::listname
| h::t -> if h = stringdata then listname else av t
in
listnameref := av !listnameref
;;
But I am not sure that is what you wanted, and I am not sure you really
want to use ref...
And one last point:
(listname.contents <- stringdata::listname.contents); ()
is pointless, since it is same as doing "listname.contents <-
stringdata::listname.contents"
which is already of type unit.
I may be wrong, but you seem to be more familiar to C, where pointers
are everywhere as soon as you have linked lists, and other complex
structures.
In ocaml, pointers are well hidden and you just have to rely on the
garbage collector.
ref are used only when you have no other choice (mainly for a shared
variable for all your module).
>
> Does anyone have any suggestions on how to change the above to make it
> work? Basically I want the function to either 1) add the contents to
> the list if no duplicates exist and return unit or 2) return unit if it
> determines that the string is already there.
Try:
let add_no_dup strdat lst =
if List.exists ((=) strdat) lst
then lst
else strdat::lst
>
> Thanks for any and all help
> Joel
> ------------------------------------------------------------------------
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
--
Cédric AUGER
Univ Paris-Sud, Laboratoire LRI, UMR 8623, F-91405, Orsay
next prev parent reply other threads:[~2009-05-13 18:06 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-05-13 17:24 Joel Christner
2009-05-13 18:06 ` Cedric Auger [this message]
2009-05-13 20:24 ` [Caml-list] " John Li
2009-05-15 13:49 ` Florian Hars
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=4A0B0C2A.6010303@lri.fr \
--to=cedric.auger@lri.fr \
--cc=caml-list@yquem.inria.fr \
--cc=joel.christner@gmail.com \
/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