Jump to content
  • Advertisement
Sign in to follow this  
metalyric

how to update a tuple in ocaml???

This topic is 4712 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hi all, i set a tuple -a pair- with let x = (5, 5);; and i now need to change the content of this. we can get the first by fst(x), and second by snd(x); but how could i update them? trying x <- (3, 3) or fst(x) <- 3 didn't work. i also googled on this issue but got hothing :( any help will be greatly appreciated. thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
Actually, there is no "content" there that you can change. "x" IS the tuple, so you cannot change "x" (since the tuple is constant).

There are however several solutions to your problem:

- Replace x by another variable with the same name, as in:

let x = (5,5) in
let x = (3,3) in
x;;

Output: (3,3)

- Make x a reference object (which has contents, and can therefore have these changed):

let x = ref (5,5);;
x := (3,3);;
!x;;

Output: (3,3)

- Make x a tuple of reference types

let x = (ref 5, ref 5);;
(fst x) := 3;;
!(fst x);;

Output: 3

- Make x a type with mutable fields

type mutablefields = { mutable int fst; mutable int snd }

let x = { fst = 5; snd = 5; }
x.fst <- 3;;
x.fst;;

Output: 3

Share this post


Link to post
Share on other sites
hi ToohrVyk,

thank you very much for your response and more than one solutions! i will try them.

by the way, do you know how to create an array of reference type tuples?

Share this post


Link to post
Share on other sites
Quote:
Original post by metalyric
hi ToohrVyk,

thank you very much for your response and more than one solutions! i will try them.

by the way, do you know how to create an array of reference type tuples?


You should give more information on what you're attempting to do. There is more likely a more efficient way to do what you are attempting to do.

Share this post


Link to post
Share on other sites
Quote:
Original post by jperalta

You should give more information on what you're attempting to do. There is more likely a more efficient way to do what you are attempting to do.


hi jperalta,

i'm new to ocaml, and sure you're right on this. i'm trying to keep coordinates of a number of elements, and change the coordinates when they needed to be changed -in a board game-. i thought using pairs for this purpose would be good, but as you see my previous posts on this topic it was not easy to me.

anyway, at last i decided to use a 2xn -n is a fixed value- array like this:

let myArr = Array.make n [|0; 0|];;

now when i need to change an element's position, i simply do it like this:

myArr(i) <- [|newX, newY|];

this way it worked, but if you offer a more appropriate way, i appreciate it.

Share this post


Link to post
Share on other sites
It would be good, except for the fact that Array.make fills it with the physical value, not with structural duplicates. Since arrays are mutable, every entry in your array will be the same element; changing one changes all.

What you want is "Array.init n (fun _ -> [| 0; 0 |])", not Array.make.

For the newbies; ints and chars are immutable and stored on the stack; meaning they stay only in the context you use them in. All others are mutable and stored on the heap, meaning they are handled internally not directly but via pointers.

This is why OCaml has the = operator testing structural equivalence ("same value") and == testing physical equivalence ("same instance") (with their negations being <> and !=, respectively).

To quote the OCaml manual... "On integers and characters, physical equality is identical to structural equality. On mutable structures, e1 == e2 is true if and only if physical modification of e1 also affects e2. On non-mutable structures, the behavior of (==) is implementation-dependent; however, it is guaranteed that e1 == e2 implies compare e1 e2 = 0."

Mutable structures are arrays, channels, objects, etc. Non-mutable structures are tuples, list elements, which compare as physically equal under some implementations, but not all. Integers and characters are somewhat different. It would be a bit much to explain why some implementations implement == differently, but let me simply say it has to do with the format of structures on the heap, which can be used to decipher the contents of the structure in a type-safe and type-independant fashion.

With all that done, I highly suggest you use tuples instead of arrays for storing position; a tuple is always preferable to an array or list when the number of fields is fixed and known at code-authoring time (which it is; two integer fields, and that's that).

[Edited by - Wyrframe on June 19, 2005 3:32:54 AM]

Share this post


Link to post
Share on other sites
Wyrframe is right; using an array of tuples is probably a better idea than an array of arrays. Then to update you can just do array.(foo) <- (newX, newY).

Another idea that may be more efficient is to use two arrays of ints/floats/whatevers, one for the X coordinate and one for the Y coordinate. Depending on how you're using it, that could be easier to write, since if you only have one value you could just do
arrayX.(foo)
instead of
let xval, _ = array.(foo) in ...
or
fst array.(foo)


Also, from what I remember of the O'Caml internals, an array of tuples is really an array of pointers, which point to tuples on the heap, while an array of numbers holds the numbers directly. So it could be slightly more efficient.

Share this post


Link to post
Share on other sites
Quote:
Original post by Wyrframe
It would be good, except for the fact that Array.make fills it with the physical value, not with structural duplicates. Since arrays are mutable, every entry in your array will be the same element; changing one changes all.


Wyrframe, are you sure of this? i mean, i used Array.make, and filled the array in a for loop -with different values, depended on the for loop counter i-, then changed only one element. then the other remain the same.

let myArr = Array.make 8 [|0; 0|];;

for i = 0 to 7
myArr.(i) <- [|i, 1|];
done;;

..
..
..

myArr.(3) <- [|5; 7|];;

now when i look at the other elements in the array, i see they are remained the same as initialized in the for loop. for example myArr.(0) is still [|0, 1|]. i'm using the latest version of ocaml. i got it using apt-get on my debian system.

anyway, i share your opinion. the best way to implement this is using an array of pairs.

Share this post


Link to post
Share on other sites
Quote:
Original post by metalyric
Quote:
Original post by Wyrframe
It would be good, except for the fact that Array.make fills it with the physical value, not with structural duplicates. Since arrays are mutable, every entry in your array will be the same element; changing one changes all.


Wyrframe, are you sure of this? i mean, i used Array.make, and filled the array in a for loop -with different values, depended on the for loop counter i-, then changed only one element. then the other remain the same.


Thus placing yourself in a case other than the one metalyric covered... has you not filled the array with a for loop, all elements in the array would have been duplicates.

Quote:

let myArr = Array.make 8 [|0; 0|];;

for i = 0 to 7
myArr.(i) <- [|i, 1|];
done;;


This is done in a more optimal way by Array.init and in any case, you're allocating one element too much (you only need to overwrite 7 of the 8).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!