Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Pal-Kristian Engstad <pal_engstad@naughtydog.com>
To: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Self type cannot be unified with a closed object type
Date: Wed, 3 Nov 2004 15:31:55 -0800	[thread overview]
Message-ID: <200411031531.55805.pal_engstad@naughtydog.com> (raw)
In-Reply-To: <E1CP8IP-00029f-Mt@syrma.ccs.neu.edu>

On Tuesday 02 November 2004 03:42 pm, Philippe Meunier wrote:
> Hi,
>
> I'm trying to implement the state pattern in Ocaml and I'm looking for
> help.  I have two classes itv1 and itv2 representing two kinds of
> state.  I'm trying to coerce objects from these two classes to a
> single class nl_v so I can use them indefferently inside objects of
> the class anl:

Hi, 

The state pattern is useful in OO languages since switches aren't safe. 
However, I will assume that you do need to extend the state class, so I won't 
go on about how you can use union types. 

Your only problem is that the 'self' type is extendible. Therefore, while 
OCaml parses your recursive structure, there is no specific closed type of 
self. If the type of 'self' was closed, then you could not extend your class.

The easiest solution in your case is to make adapt return a closed type, 
namely your nl_vp class type. Simply change "method adapt : 'a" to "method 
adapt: nl_vp": 

type itv2stub = { mutable ival : int }

let new_itv2_stub () = { ival = 0 }
let get_itv2_stub s = s.ival
let set_itv2_stub s v = (s.ival <- v; s)

class type nl_vp = object
    method get : int
    method set : int -> nl_vp
    method adapt : nl_vp
  end;;
 
class itv1 : nl_vp =
  object (self)
    val mutable itv1_val = ~-1 
    method get = itv1_val
    method set i = {< itv1_val = i >}
    method adapt = if self#get = 2 then (new itv2 :> nl_vp) else (self :> 
nl_vp)
  end
and itv2 : nl_vp =
  object (self)
    val mutable itv2_val = new_itv2_stub () 
    method get = get_itv2_stub itv2_val
    method set i = {< itv2_val = set_itv2_stub itv2_val i >}
    method adapt = if self#get = 7 then ((new itv1) :> nl_vp) else (self :> 
nl_vp)
  end;;
 
class anl =
  object
    val mutable nl = (new itv1 :> nl_vp)
 
    method get = nl#get
    method set i = {< nl = (nl#set i)#adapt >}
    method adapt = {< nl = nl#adapt >}
  end;;

By the way, notice that {< itv1_val = i >} creates a _new_ object, hence it 
might not do what you expect. I.e. the "mutable" keyword is not nescessary in 
itv1.

Hope this helps.

PKE.


  reply	other threads:[~2004-11-03 23:33 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-11-02 23:42 Philippe Meunier
2004-11-03 23:31 ` Pal-Kristian Engstad [this message]
2004-11-03 23:43 ` [Caml-list] " Tony Edgin
2004-11-04  0:17 ` Jacques Garrigue
2004-11-04 18:22 Philippe Meunier

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=200411031531.55805.pal_engstad@naughtydog.com \
    --to=pal_engstad@naughtydog.com \
    --cc=caml-list@yquem.inria.fr \
    /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