val mutable [x; y] : syntax error
Bonjour, je me trompe peut-être à chaque ligne en essayant d'utiliser une liste pour me créer une classe point :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
class point x_init y_init =
object
val mutable [x; y] = [x_init; y_init]
method get_x = [x; _]
method get_y = [_; y]
method set_x x1 = [x; _] <- [x1; _]
method set_y y1 = [_; y] <- [_; y1]
method translate x1 y1 = [x; y] <- [x+x1; y+y1]
method move_to x1 y1 = [x; y] <- [x1; y1]
method draw = Gr.plot x y
end;; |
j'obtiens une "syntax error" ici : Ca doit être évident, mais je débute en ocaml ^^, quelle est mon erreur ?
Ceci est une réponse à coté de la plaque
Hi MrGecko !
Je ne suis pas franchement un pro de la partie objet de OCaml, donc je ne peux pas particulièrement t'aider dans ce domaine, mais je vais tenter de te mettre sur la voie : Une liste n'est pas faites pour stocker un nombre donné d'élements. Pour celà, il y a les tuples. Pour la paire par exemple, la syntaxe est (x, y). Mais en l'occurence, vu que tu accèdes plutôt séparement à chaque composante de ton point, pourquoi ne pas plutôt avoir deux attributs abscisse et ordonnée ?
En revanche (et c'est là que la réponse commence à être completement à coté de la plaque), si tu es vraiment un débutant en OCaml, crois moi, tu ne *veux pas* commencer par les objets ! Ce n'est clairement pas la meilleure part d'OCaml...
Tu peux plutôt faire un truc comme :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
(*** Définition de la signature ***)
module type TypePoint =
sig
type t
val new_t : int -> int -> t
val get_x : t -> int
val get_y : t -> int
val set_x : t -> int -> unit
val set_y : t -> int -> unit
val translate : t -> int -> int -> unit
val move_to : t -> int -> int -> unit
end
(*** définition du module ***)
module Point:TypePoint =
struct
type t = {mutable x : int;
mutable y : int}
let new_t x y = {x = x; y = y}
let get_x t = t.x
let get_y t = t.y
let set_x t x1 = t.x <- x1
let set_y t y1 = t.y <- y1
let translate t x1 y1 =
t.x <- t.x + x1;
t.y <- t.y + y1
let move_to t x1 y1 =
t.x <- x1;
t.y <- y1
end |
C'est la définition de la signature du module (qui est inféré automatiquement par "ocamlc -i", puis "tuné" pour cacher certaines choses) qui permet l'encapsulation. Si dans la suite du code tu ouvres le module (open Point), tu pourras faire "let p = new_t 3 4", mais tu ne pourras pas faire "p.x", car la signature cache le fait que le type "t" est une structure avec deux enregistrements. Donc si un jour tu veux la changer, pas de problème.
Et supposons que tu te dises "oui mais parfois, mais points ont des coordonnées flottante" ? et bien c'est là que la magie des foncteurs entre en jeu :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
(*** signature du module argument ***)
module type Coord =
sig
type t
val add : t -> t -> t
end
(*** signature du module point ***)
module type TypePoint =
sig
type coord
type t
val new_t : coord -> coord -> t
val get_x : t -> coord
val get_y : t -> coord
val set_x : t -> coord -> unit
val set_y : t -> coord -> unit
val translate : t -> coord -> coord -> unit
val move_to : t -> coord -> coord -> unit
end
(*** définition du foncteur.
Prend en argument un module C de signature Coord
et produit un module signature TypePoint avec coord = C.t ***)
module MakePoint (C:Coord) : TypePoint with type coord = C.t =
struct
type coord = C.t
let (+) = C.add
type t = {mutable x : coord;
mutable y : coord}
let new_t x y = {x = x; y = y}
let get_x t = t.x
let get_y t = t.y
let set_x t x1 = t.x <- x1
let set_y t y1 = t.y <- y1
let translate t x1 y1 =
t.x <- t.x + x1;
t.y <- t.y + y1
let move_to t x1 y1 =
t.x <- x1;
t.y <- y1
end
(*** exemple avec les entier ***)
module CoordInt =
struct
type t = int
let add = (+)
end
module PointInt = MakePoint (CoordInt)
(*** let les flotants ***)
module CoordFloat =
struct
type t = float
let add = (+.)
end
module PointFloat = MakePoint (CoordFloat) |
Les foncteurs étaient quelque chose qui me "faisait peur" il y a peu, mais maintenant que j'ai vraiment découvert, c'est un vrai bonheur !
Bref, pour résumer, familiarise toi d'abord avec les types, l'approche fonctionnelle, le polymorphisme, les modules, les foncteurs... Et il sera temps à ce moment de s'attaquer aux objets :-)