我在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)<-???
有人可以告诉我可以在这个数组中插入哪个值吗?
答案 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)