Thank you all for your prompt replies.
I’m not quite sure what you’re doing with the ^
operator.
I did indeed make a typing error in my last question, I meant to write x * 1 and q * 1.
You are welcome to post on this forum program fragments that at first glance may only be solvable with Obj.magic
and see whether people can help you find a better alternative.
As I have not yet mastered Obj I have tried things on my own without understanding them, I apologize in advance for the horrors that will follow and would read with great interest all the articles I have been advised to understand if only for my culture Obj.
I had tried to create a function that would take two arrays as input and return the sum of the index-by-index product of the elements.
Obj may not be necessary for this problem, but having discovered Obj I wanted to try and use it (which results in a really ugly function and certainly not in the spirit of Ocaml).
The two input arrays can be :
tab 1 : float array , tab2 : float array
tab 1 : int array , tab2 : float array
tab 1 : float array, tab2 : int array
tab 1 : int array, tab2 : int array
I had noticed that the tag of the internal representation of objects of types float and int differed between them, for example:
Obj.tag(Obj.repr(5));; Output : int = 1000
Obj.tag(Obj.repr(9.));; Output : int = 253
This allowed me to know the type of the two input arrays by comparing the tag of the internal representation of the first element of each array with the tag of the internal representation of an object of type float and an object of type int.
To perform sum and multiply operations, I wanted to convert one or two of the input arrays to float Array type if they were of int Array type. This would allow me to perform addition and multiplication operations only with float objects.
I therefore
created exceptions that should have allowed me to convert int array tabels into float array tabels by tag comparison.
However, my function doesn’t work if it’s given two int array tabels as input, e.g. :
ouch_my_brain (Obj.magic([|1;2|])) (Obj.magic([|3;4|]));; it will systematically return 0.
whereas if I choose one or two float arrays, for example
ouch_my_brain (Obj.magic([|1;2|])) (Obj.magic([|3.;4.|]));; it will systematically return a kind of pointer as mentioned in my third question.
Careful not to have a stroke, here’s my horrible function:
exception Cas1
exception Cas2
exception Cas3
let sum (tab1: float array) (tab2: float array) : float =
let sum = ref 0. in
for i = 0 to ((Array.length tab1) - 1) do
sum := !sum +. tab1.(i) *. tab2.(i)
done;
!sum;;
let ouch_my_brain (tab1: Obj.t) (tab2: Obj.t) : float =
let tag1 = Obj.tag (Obj.repr tab1) in
let tag2 = Obj.tag (Obj.repr tab2) in
let tag_rint = Obj.tag (Obj.repr (5 : int)) in
let tag_rflo = Obj.tag (Obj.repr (9.2 : float)) in
try
if tag1 = tag_rint && tag2 = tag_rint then raise Cas1 else
if tag1 = tag_rint && tag2 = tag_rflo then raise Cas2 else
if tag1 = tag_rflo && tag2 = tag_rint then raise Cas3 else
sum (Obj.magic tab1) (Obj.magic tab2)
with
| Cas1 -> sum (Array.map (fun x -> float_of_int x) (Obj.magic tab1)) (Array.map (fun x -> float_of_int x) (Obj.magic tab2))
| Cas2 -> sum (Array.map (fun x -> float_of_int x) (Obj.magic tab1)) (Obj.magic(tab2))
| Cas3 -> sum (Obj.magic(tab1)) (Array.map (fun x -> float_of_int x) (Obj.magic tab2))