Ocaml中带参数的类型的数组

时间:2011-06-01 08:36:25

标签: arrays types ocaml

我在Ocaml做家庭作业......

我的老师说我们必须使用这两种类型:

type 'a zapis = Prazen | Zapis of string * 'a;;
type 'a asocpolje = 'a zapis array;;

我的问题是当我创建一个数组时:

# let a = Array.make 5 Prazen;;
val a : '_a zapis array = [|Prazen; Prazen; Prazen; Prazen; Prazen|]

我不知道在这个数组中可以插入什么值...

a.(0)<-???

有人可以告诉我可以在这个数组中插入哪个值吗?

2 个答案:

答案 0 :(得分:11)

在向数组添加任何内容之前,类型尚未完全定义。这反映在为数组指示的类型中:

val a : '_a zapis array = [|Prazen; Prazen; Prazen; Prazen; Prazen|]

如果你仔细观察,你会发现你作为类型参数提供的'a已成为'_a(请注意_)。这种类型意味着“某种类型,但我还不知道哪一种”。与'a相反,这意味着任何类型。

这意味着此时您可以插入任何类型的Zapis。一旦你这样做,你只能插入那种特殊类型的Zapis(在更进一步的类型中,'_a消失并被替换为正确的类型)。

所以,如果你这样做

a.(0) <- Zapis ("z", 10)

a将成为int zapis array,并且从那一刻开始才接受整数。

如果你改为

a.(0) <- Zapis ("z","z") 

之后它将成为string zapis array只接受字符串。

答案 1 :(得分:5)

  

你能告诉我如何创建一个数组类型asocpolje吗?

'a asocpolje'a zapis array 属于同一类型。根据typer推断你的定义的准确程度,你会得到一个或另一个,但它们完全相同。 'a asocpolje只是'a zapis array别名,而非新类型。

您可以使用显式类型注释帮助OCaml打印正确的类型信息:

let t : 'a asocpolje = Array.make ...

但是我会劝阻这种做法。它以非显而易见的方式运行(例如'a这里的含义可能令人惊讶,它不会强制执行多态)而你真的试图在没有它的地方做出改变(类型是相同的) )。如果确实希望区分两种类型,则应将'a asocpolje定义为新的代数类型(只有一种情况):

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)