2009-02-02 6 views
2

J'ai des problèmes avec les listes dans OCaml. J'ai lu des instructions contradictoires indiquant si les listes peuvent être modifiées ou non à l'exécution. L'opérateur cons peut-il être utilisé lors de l'exécution?OCaml typage structurel et listes

En outre, pourquoi un doberman (voir ci-dessous) est-il autorisé à figurer dans une liste de chihuahuas? Comment pourrait-on ajouter un autre chihuahua sur la liste (comme essayé avec la dernière ligne)?

class virtual dog = 
object 
method virtual bark : unit 
end;; 

class chihuahua = 
object 
inherit dog 
method bark = Printf.printf "Yip!" 

end;; 

class doberman = 
object 
inherit dog 
method bark = Printf.printf "Roar!" 

end;; 

let c1 = new chihuahua;; 
let c2 = new chihuahua;; 
let c3 = new chihuahua;; 
let d1 = new doberman;; 

let arrayOfDogs = [c1;c2;d1];; 
arrayOfDogs :: c3;; 

Répondre

3

vous devez avoir votre liste sur le côté droit, pas sur la gauche. Par exemple:

c3 :: arrayOfDogs;; 

C'est pourquoi la dernière ligne échoue.

En ce qui concerne la construction de la liste, étant donné que OCaml est dérivé de type, l'interpréteur a probablement compris que vous construisiez une liste de chiens, étant donné que vous avez ajouté le doberman en construction. Par conséquent, ce n'est pas une liste de Chihuahuas.

1

Que rapporte OCaml comme type de arrayOfDogs?

Peut-être vous dire: c3 :: arrayOfDogs;;

7

1) Vous pouvez utiliser l'opérateur lors de l'exécution contre, il retourne simplement une nouvelle liste plutôt que la liste des muter entrée.

2) Les types de classe dans OCaml utilisent un sous-typage "structurel", plutôt qu'un sous-typage "nominal" de type Java. Le type inféré de arrayOfDogs sera "un objet avec une méthode nommée bark de type unit -> unit (pas nécessairement un dog)". Par exemple:

# class cat = object 
    method bark = print_endline "meow" 
    end ;; 
class cat : object method bark : unit end 
# let c = new cat ;; 
val c : cat = <obj> 
# c :: arrayOfDogs ;; 
- : cat list = [<obj>; <obj>; <obj>; <obj>] 

3) Le problème avec arrayOfDogs :: c3 est que vous l'avez dans le mauvais sens. Le type de :: est 'a -> 'a list -> 'a list. Pour ajouter c3 au début, utilisez

c3 :: arrayOfDogs 

Pour l'ajouter à la fin, utilisez l'opérateur « ajouter » @

arrayOfDogs @ [c3]