I’m writing a program in OCaml, where sometimes I have to extend an array on the right or on the left.
I want to create two functions (extend_right and extend_left) with the following signatures
int -> 'a -> 'a array -> 'a array.
extend_left 3 0 [|1; 2; 3; 4|]is expected to produce
[|0; 0; 0; 1; 2; 3; 4|]
extend_right 3 0 [|1; 2; 3; 4|]is expected to produce
[|1; 2; 3; 4; 0; 0; 0|]
Since the code is extremely repetitive, I created the following function :
let extend st_cop sz el arr = let sz_arr = Array.length arr in let n_arr = Array.make (sz + sz_arr) el in let () = Array.blit arr 0 n_arr st_cop sz_arr in n_arr
Then, I can simply define :
let extend_left sz = extend sz sz;; let extend_right = extend 0;;
However, if I do that,
extend_right has the type
val extend_right : int -> '_weak1 -> '_weak1 array -> '_weak1 array = <fun>
Which means that as soon as I use it, let’s say on an
int array, its type becomes
val extend_right : int -> int -> int array -> int array = <fun>
and I cannot use it with any other type anymore (which I want to do).
Now comes the extremely surprising part : If I define
extend_right as follow instead,
let extend_right sz = extend 0 sz;;
The type isn’t weak anymore ! It stays polymorphic as I want. Although the semantics is strictly equivalent (I assume).
I’m very curious about why the type checker has this behaviour. (Although I’m not really looking for help, since I have a solution).
Thank you !