caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Mikhail Mandrykin <mandrykin@ispras.ru>
To: caml-list@inria.fr
Cc: Markus Mottl <markus.mottl@gmail.com>
Subject: Re: [Caml-list] Covariant GADTs
Date: Mon, 19 Sep 2016 13:18:19 +0300	[thread overview]
Message-ID: <2161155.JggR3X9ZFM@molnar> (raw)
In-Reply-To: <a4859b23-5300-4205-3cac-3f19888c30dd@polychoron.fr>

[-- Attachment #1: Type: text/plain, Size: 2247 bytes --]

Hello,

On понедельник, 19 сентября 2016 г. 10:58:29 MSK you wrote:
> Hi Markus,
> 
> Therefore, these fields are neither readable nor writable directly. A
> direct manifestation of the problem is that, as you observed, you cannot
> assign new values to either prev or next without use of `Obj.magic`. For
> instance,

As far as I know quite common  approach in this case is introduction of one-
constructor wrapper types to hide the existential variable and allow mutability 
e.g.

type ('el, _) t =
     | Empty : ('el, [ `empty ]) t
     | Elt : {
         mutable prev : 'el link;
         el : 'el;
         mutable next : 'el link;
       } -> ('el, [ `elt ]) t
and 'el link = Link : ('el, _) t -> 'el link;;

So the link type wraps the type parameter of the next element and thus allows 
safe mutation, otherwise it's only possible to update the field with the element of 
exactly same type that doesn't allow e.g. deleting an element at the end of the list 
without reallocating the corresponding record of the previous element (and if one 
decides to keep more precise information e.g. about the number of elements, the 
whole list needs to be re-allocated). With the link wrapper as above it's possible to 
define add, remove and also a get operation without and extra pattern matching:

let add : type a. _ -> (_, a) t -> (_, [`elt]) t = fun el ->
  function
  | Empty -> Elt { el; prev = Link Empty; next = Link Empty }
  | Elt _ as n -> Elt { el; prev = Link Empty; next = Link n };;

let remove : type a. ('el, a) t -> 'el link =
  function
  | Empty -> Link Empty
  | Elt { prev = Link p as prev; next = Link n as next} ->
    (match p with Empty -> () | Elt p -> p.next <- next);
    (match n with Empty -> () | Elt n -> n.prev <- prev);
    next;;

let get : (_, [`elt]) t -> _ = function Elt { el; _ } -> el

Also note the GPR#606(https://github.com/ocaml/ocaml/pull/606[1] ) that should 
allow constructing and deconstructing links (Link l) without overhead.

Regards, Mikhail



-- 
Mikhail Mandrykin
Linux Verification Center, ISPRAS
web: http://linuxtesting.org
e-mail: mandrykin@ispras.ru

--------
[1] https://github.com/ocaml/ocaml/pull/606

[-- Attachment #2: Type: text/html, Size: 9761 bytes --]

  reply	other threads:[~2016-09-19 10:18 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-17 17:38 Markus Mottl
2016-09-18  8:17 ` Petter A. Urkedal
2016-09-19  1:52   ` Markus Mottl
2016-09-19  8:58     ` octachron
2016-09-19 10:18       ` Mikhail Mandrykin [this message]
2016-09-19 13:37         ` Mikhail Mandrykin
2016-09-19 14:46         ` Markus Mottl
2016-09-19 14:53           ` Mikhail Mandrykin
2016-09-19 15:03             ` Markus Mottl
2016-09-20 21:07               ` Markus Mottl
2016-09-21 10:11                 ` Lukasz Stafiniak
2016-09-21 10:14                   ` Lukasz Stafiniak
2016-09-21 17:04                     ` Markus Mottl
2016-09-21 21:40                       ` Gabriel Scherer
2016-09-22  0:39                         ` Markus Mottl
2016-09-24  5:09                           ` Yaron Minsky
2016-10-04 10:33                 ` Jacques Garrigue
2016-09-19 14:39       ` Markus Mottl
2016-09-19 10:05     ` Goswin von Brederlow

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=2161155.JggR3X9ZFM@molnar \
    --to=mandrykin@ispras.ru \
    --cc=caml-list@inria.fr \
    --cc=markus.mottl@gmail.com \
    /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).