Hello,
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
.
For example
-
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 !
Giltho