Array of a type with a parameter in Ocaml
I have a homework exercise to do in Ocaml...
My teacher said that we must use these 2 types:
type 'a zapis = Prazen | Zapis of string * 'a;;
type 'a asocpolje = 'a zapis array;;
My problem is that when I create an array:
# let a = Array.make 5 Prazen;;
val a : '_a zapis array = [|Prazen; Prazen; Prazen; Prazen; Prazen|]
I don't know what values can be inserted in this array...
a.(0)<-???
Can someone tell me whi开发者_开发技巧ch value can be inserted in this array?
Until you add anything to the array the type is not fully defined. This is reflected in the type indicated for the array:
val a : '_a zapis array = [|Prazen; Prazen; Prazen; Prazen; Prazen|]
If you look closely you will see that the 'a
you gave as type parameter has become a '_a
(note the _
). This type means "some type, but I do not know which one yet". As opposed to 'a
which means any type.
This means at this point you can insert any kind of Zapis. Once you do that, you can only insert Zapis of that special type (in further types the '_a
goes away and is replaced with the correct type).
So if you do
a.(0) <- Zapis ("z", 10)
a
will become a int zapis array
and only accept ints from that moment on.
if you do instead
a.(0) <- Zapis ("z","z")
it will become a string zapis array
only accept strings afterwards.
Can you tell me how to create an array type asocpolje?
'a asocpolje
and 'a zapis array
are the same type. Depending on how exactly the typer infer your definitions, you will get one or the other, but they're exactly equivalent. 'a asocpolje
is just an alias for 'a zapis array
, not a new type.
You can help OCaml print the right type information by using an explicit type annotation :
let t : 'a asocpolje = Array.make ...
I would however discourage this practice. It behaves in non-obvious ways (eg. the meaning of 'a
here may be surprising, it does not enforce polymorphism) and you're really trying to make a difference where there isn't (the types are the same). If you really want a distinction between both types, you should define 'a asocpolje
as a new algebraic type (with only one case):
type 'a zapis = Prazen | Zapis of string * 'a;;
type 'a asocpolje = Asocpolje of 'a zapis array;;
let t = Asocpolje (Array.make ...)
let get (Asocpolje t) n = t.(n)
精彩评论