caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Goswin von Brederlow <goswin-v-b@web.de>
To: Martin Jambon <martin.jambon@ens-lyon.org>
Cc: Goswin von Brederlow <goswin-v-b@web.de>, caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Bug? Constraints get ignored in methods
Date: Wed, 01 Apr 2009 17:57:28 +0200	[thread overview]
Message-ID: <87wsa49xjr.fsf@frosties.localdomain> (raw)
In-Reply-To: <49D35307.4000502@ens-lyon.org> (Martin Jambon's message of "Wed, 01 Apr 2009 13:41:59 +0200")

Martin Jambon <martin.jambon@ens-lyon.org> writes:

> Would the following work for you:

No. Not just like this.

> type 'a linked = {
>   data : 'a;
>   mutable next : < > linked option
> }
> (* constraint 'a = < .. > *)
>
> let create data next = {
>   data = data;
>   next = (next :> < > linked option)
> }
>
> let set_next x y =
>   x.next <- (y :> < > linked option)
>
>
> class s =
> object
>   method s = "abc"
> end
>
> class i =
> object
>   method i = 123
> end

class s and i have no access to the linked type. You could not remove
a class s or i from the linked structure in O(1) from within class s
or i. So linked would have to handle any function that might require
altering the linked structure and pass parts of it to its data. But
data is an unknown type so no method of it can be called.

I would first need a class type containing the common
functionality. Then 'a needs to be constraint to a superset of that
class and next has to be an linked option of that class.

Only then can the linked type call methods of its data.


Your suggestion has one benefit though. By using a record + normal
functions instead of a class one avoids a recursively constraint
method, which ocaml doesn't like.

MfG
        Goswin

----------------------------------------------------------------------
PS: below is a completly object free solution. It comes at the cost of
requireing Obj.magic though. But its evilness is contained in M alone
and can't escape. Not sure yet what way I will go.

module M :  sig
  type 'a fn = { to_string : 'a -> string; alter : 'a -> 'a }
  type 'a base
  val make : 'a -> 'a fn -> 'a base
  val to_string : 'a base -> string
  val alter : 'a base -> unit
  val iter : ('a base -> unit) -> unit
end = struct
  type 'a fn = { to_string : 'a -> string; alter : 'a -> 'a }
  type 'a base = { mutable next : unit base; mutable prev : unit base; mutable data : 'a; fn : 'a fn }
  let unit_fn = { to_string = (fun () -> ""); alter = (fun () -> ()) }
  let rec head = { next = head; prev = head; data = (); fn = unit_fn }
  let make data fn =
    let e = { next = head; prev = head.prev; data = data; fn = fn }
    in
      head.prev.next <- Obj.magic e;
      head.prev <- Obj.magic e;
      e
  let to_string x = x.fn.to_string x.data
  let alter x = x.data <- x.fn.alter x.data
  let iter (fn : 'a base -> unit) =
    let fn : unit base -> unit = Obj.magic fn in
    let rec loop = function
	x when x == head -> ()
      | x -> fn x; loop x.next
    in
      loop head.next
end

let string_fn = { M.to_string = (fun s -> s); M.alter = (fun s -> s ^ "+") }
let int_fn = { M.to_string = (fun i -> Printf.sprintf "%d" i); M.alter = (fun i -> i +1) }
let s = M.make "s" string_fn
let i = M.make 1 int_fn
let _ = M.iter (fun x -> Printf.printf "%s\n" (M.to_string x))
let _ = M.iter M.alter
let _ = M.iter (fun x -> Printf.printf "%s\n" (M.to_string x))

=>

s
1

s+
2


  reply	other threads:[~2009-04-01 15:57 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-31 22:05 Goswin von Brederlow
2009-03-31 23:01 ` [Caml-list] " Martin Jambon
2009-03-31 23:12   ` Martin Jambon
2009-03-31 23:52   ` Goswin von Brederlow
2009-04-01  0:08   ` Goswin von Brederlow
2009-04-01 11:41     ` Martin Jambon
2009-04-01 15:57       ` Goswin von Brederlow [this message]
2009-04-01 18:45         ` Martin Jambon
2009-04-01  1:24 ` Peng Zang
2009-04-01  3:25   ` Goswin von Brederlow
2009-04-02  8:39 ` Jacques GARRIGUE
2009-04-03 20:53   ` Goswin von Brederlow
2009-04-06  4:30     ` 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=87wsa49xjr.fsf@frosties.localdomain \
    --to=goswin-v-b@web.de \
    --cc=caml-list@yquem.inria.fr \
    --cc=martin.jambon@ens-lyon.org \
    /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;
as well as URLs for NNTP newsgroup(s).