Browse thread
state pattern...
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: | 2005-06-28 (00:53) |
From: | Jacques Garrigue <garrigue@m...> |
Subject: | Re: [Caml-list] state pattern... |
From: Michael Wohlwend <micha-1@fantasymail.de> > I have modified the code, so that some method(s) of the state > classes get the context class as parameter; I think it took me 3 > hour to get the type definitions working :-) > > Can this be done simpler? It works, although I don't completly > understand all of it :-) There is a variety of things you could do to simplify your code. If you want to keep the polymorphic-method based approach, you can avoid type annotations in stat1#show an state2#show by writing (this : #state). But another way to simplify things is to switch to subtyping. That is, just have method show : param -> unit in class state, and change context to method show = state_#show (this :> param) Note also that your definition of state as a recursive type will cause problems later, if you try to finalize it in a class. Here is a possibly simpler version of your code. class type param = object method name : string end class type ['next] state = object method show: param -> unit method next: 'next end class ['state] context s = object (this:'self) val name = "context" val state : _ #state = s method state : 'state = state method name = name method show = state#show (this :> param) method run = {< state = state#next >} end class state1 = object (this : _ #state) method show c = print_endline ("state1 of " ^ c#name) method next = new state2 end and state2 = object (this : _ #state) method show c = print_endline ("state2 of " ^ c#name) method next = new state1 end;; let c = new context (new state1) ;; c#show;; let c = c#run;; c#show;; Note that there is an intrinsic weakness to the object-oriented approach in ocaml: state1 and state2 must actually be the same type, since a method of context cannot return context with a different parameter. On the other hand, if you exactly know what a state should be from the beginning, you can eliminate all type parameters. class type param = object method name : string end class type state = object method show: param -> unit method next: state end class context s = object (this) val name = "context" val state : state = s method state = state method name = name method show = state#show (this :> param) method run = {< state = state#next >} end class state1 = object (this : #state) method show c = print_endline ("state1 of " ^ c#name) method next = new state2 end and state2 = object (this : #state) method show c = print_endline ("state2 of " ^ c#name) method next = new state1 end;; But then there is little point in using classes... records and functions would do the job in a clearer way. Jacques Garrigue