From: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
To: micha-1@fantasymail.de
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] state pattern...
Date: Tue, 28 Jun 2005 09:54:06 +0900 (JST) [thread overview]
Message-ID: <20050628.095406.112629429.garrigue@math.nagoya-u.ac.jp> (raw)
In-Reply-To: <200506280123.55251.micha-1@fantasymail.de>
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
next prev parent reply other threads:[~2005-06-28 0:53 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-06-26 19:57 Michael Wohlwend
2005-06-26 22:13 ` [Caml-list] " james woodyatt
2005-06-26 22:45 ` Michael Wohlwend
2005-06-27 23:23 ` Michael Wohlwend
2005-06-28 0:54 ` Jacques Garrigue [this message]
2005-06-28 12:24 ` Michael Wohlwend
2005-06-28 13:20 ` Jacques Garrigue
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20050628.095406.112629429.garrigue@math.nagoya-u.ac.jp \
--to=garrigue@math.nagoya-u.ac.jp \
--cc=caml-list@yquem.inria.fr \
--cc=micha-1@fantasymail.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox