2011-06-01 18 views
8

Tengo un ejercicio de tarea para hacer en Ocaml ...matriz de un tipo con un parámetro en Ocaml

Mi maestra dijo que debemos utilizar estos 2 tipos:

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

mi problema es que cuando se crea una matriz:

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

no sé qué valores pueden ser insertados en esta matriz ...

a.(0)<-??? 

¿Alguien me puede decir qué valor se puede insertar en esta matriz?

Respuesta

11

Hasta que agregue nada a la matriz, el tipo no está completamente definido. Esto se refleja en el tipo indicado para la matriz:

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

Si se mira de cerca, verá que el 'a que dio como parámetro de tipo se ha convertido en un '_a (nótese el _). Este tipo significa "algún tipo, pero aún no sé cuál". A diferencia de 'a que significa cualquier tipo.

Esto significa que en este momento puede insertar cualquier tipo de Zapis. Una vez que lo haga, solo puede insertar Zapis de ese tipo especial (en otros tipos, el '_a desaparece y se reemplaza con el tipo correcto).

por lo que si

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

a se convertirá en un int zapis array y sólo aceptar enteros desde ese momento en adelante.

si lo hace en lugar

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

se convertirá en un string zapis array sólo aceptan cuerdas después.

+0

gracias por esto ... Yo realmente lo necesito :) – Cevap

+0

¿Se puede decir ¿cómo crear un tipo de matriz asocpolje? – Cevap

5

¿Puede decirme cómo crear una matriz tipo asocpolje?

'a asocpolje y 'a zapis array son el mismo tipo. Dependiendo de cómo exactamente Typer infiera sus definiciones, obtendrá una u otra, pero son exactamente equivalentes. 'a asocpolje es solo un alias para 'a zapis array, no es un tipo nuevo.

Puede ayudar a OCaml imprimir la información de tipo de derecho mediante el uso de un tipo de anotación explícita:

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

Me habría sin embargo desalentar esta práctica. Se comporta de manera no obvia (por ejemplo, el significado de 'a aquí puede ser sorprendente, no impone el polimorfismo) y realmente está tratando de hacer una diferencia donde no lo hay (los tipos son los mismos).Si realmente desea una distinción entre los dos tipos, debe definir 'a asocpolje como un nuevo tipo algebraica (con un solo caso):

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) 
Cuestiones relacionadas