From: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
To: Goswin von Brederlow <goswin-v-b@web.de>
Cc: OCaML Mailing List <caml-list@inria.fr>
Subject: Re: [Caml-list] A shallow option type
Date: Mon, 7 May 2012 11:34:02 +0900 [thread overview]
Message-ID: <9EAA1066-D3CE-4260-BCBC-9F044F450EB0@math.nagoya-u.ac.jp> (raw)
In-Reply-To: <4A169BB4-3316-437A-9E73-FABEAEDB9D2F@math.nagoya-u.ac.jp>
Sorry, the marshaling part was wrong.
Of course we need to do something about received values.
So here is a version that automatically attempts to internalize values
with tag sopt_tag when we apply either some or arg to them.
This should be safe, as if sopt_tag was used for another
type, this should be in a functional way.
Jacques
module Sopt : sig
type +'a t
val none : 'a t
val some : 'a -> 'a t
val is_none : 'a t -> bool
val arg : 'a t -> 'a
val intern : 'a t -> 'a t
val depth : 'a t -> int
end = struct
type 'a t = Obj.t
let sopt_tag = Obj.lazy_tag - 1
let none = Obj.new_block sopt_tag 0
let last = 31
let area = Array.create (last+1) none
let () =
for i = 1 to last do
let stub = Obj.new_block sopt_tag 1 in
Obj.set_field stub 0 area.(i-1);
area.(i) <- stub
done
let is_none x = (x == none)
let rec intern_aux x i =
if i > last || Obj.is_int x || Obj.tag x <> sopt_tag || Obj.size x > 1 then
invalid_arg "Sopt.intern"
else
if Obj.size x = 0 then i else intern_aux (Obj.field x 0) (i+1)
let intern x = Obj.obj area.(intern_aux (Obj.repr x) 0)
let rec some_aux x i =
if i < last then
if x == area.(i) then area.(i+1) else some_aux x (i+1)
else (* i = last *)
if x == area.(last) then invalid_arg "Sopt.some" else
let i = intern_aux x 0 in
if i >= last then invalid_arg "Sopt.some" else area.(i+1)
let some (x : 'a) : 'a t =
let x = Obj.repr x in
if Obj.is_int x || Obj.tag x <> sopt_tag then Obj.obj x
else Obj.obj (some_aux x 0)
let rec arg_aux x i =
if i <= last then
if x == area.(i) then area.(i-1) else arg_aux x (i+1)
else
if x == area.(0) then invalid_arg "Sopt.arg" else
let i = intern_aux x 0 in
if i = 0 then invalid_arg "Sopt.arg" else area.(i-1)
let arg (x : 'a t) : 'a =
let x = Obj.repr x in
if Obj.is_int x || Obj.tag x <> sopt_tag then Obj.obj x
else Obj.obj (arg_aux x 1)
let rec depth_aux x i =
if i <= last then
if x == area.(i) then i else depth_aux x (i+1)
else -1
let depth x = depth_aux (Obj.repr x) 0
end
On 2012/05/07, at 10:27, Jacques Garrigue wrote:
> Here is another variant using normal values.
> The advantage is that it does no tricks with bits, and supports
> marshaling.
> It is less efficient because the search is linear, but by using as
> tag (lazy_tag -1) we can avoid being too inefficient in most cases.
> Note however that after marshaling the values are going to
> have the same tag, so this is going to be much less efficient.
>
> Jacques
[...]
next prev parent reply other threads:[~2012-05-07 2:34 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-05 13:33 Goswin von Brederlow
2012-05-05 13:50 ` Gabriel Scherer
2012-05-05 14:48 ` Andreas Rossberg
2012-05-05 15:07 ` Andreas Rossberg
2012-05-05 16:22 ` Goswin von Brederlow
2012-05-05 17:11 ` Gabriel Scherer
2012-05-06 10:12 ` Goswin von Brederlow
2012-05-06 10:20 ` Goswin von Brederlow
2012-05-06 13:01 ` Jacques Garrigue
2012-05-06 15:34 ` Goswin von Brederlow
2012-05-07 0:29 ` Jacques Garrigue
2012-05-07 1:27 ` Jacques Garrigue
2012-05-07 2:34 ` Jacques Garrigue [this message]
2012-05-07 8:11 ` Jacques Garrigue
2012-05-07 17:07 ` Goswin von Brederlow
2012-05-08 0:07 ` 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=9EAA1066-D3CE-4260-BCBC-9F044F450EB0@math.nagoya-u.ac.jp \
--to=garrigue@math.nagoya-u.ac.jp \
--cc=caml-list@inria.fr \
--cc=goswin-v-b@web.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