From: Alain Frisch <frisch@clipper.ens.fr>
To: John Max Skaller <skaller@ozemail.com.au>
Cc: Caml list <caml-list@inria.fr>
Subject: Re: [Caml-list] equi-recursive Fold isomorphism
Date: Sun, 28 Jul 2002 22:14:59 +0200 (MET DST) [thread overview]
Message-ID: <Pine.SOL.4.44.0207282143060.10604-100000@clipper.ens.fr> (raw)
In-Reply-To: <3D434CC3.6030508@ozemail.com.au>
On Sun, 28 Jul 2002, John Max Skaller wrote:
> Hmmm: Ocaml 3.04+15 with -rectypes
>
>
> # let rec x = (1,(1,(1,x)));;
> val x : int * (int * (int * 'a)) as 'a =
> ....
>
> Seem like Ocaml doesn't minimise the type, but:
>
>
> let rec y = (1,y);;
>
> x = y;;
>
> Works correctly (so it knows the two types are comparable).
> Interestingly, the answer is false
Are you sure ? It seems that the comparison doesn't terminate,
as expected (as it does not consume memory). The manual
says:
<<
Equality between cyclic data structures may not terminate.
>>
: both data structures
> consist of an infinite stream of 1's, represented by
> cycles of distinct lengths. No item by item comparison
> could reveal any distinction: the infinite tree expansions
> of the data structures are the same. Is Ocaml's answer correct?
As you know, to implement the comparison between cyclic values with the
expected behaviour, one has to use a coinductive algorithm with some kind
of memoization. This would be much slower for the non-cyclic case, and
many people expect a fast generic compare function. I would like to say
that you can always take the code in byterun/compare.c and implement your
own equirecursive generic comparison in C, but this is actually not
possible (you need the Is_young and Is_in_heap macros that are not
available). Using the mentioned Recurse module, you could do:
module I = struct
type 'a t = Int of int | Pair of 'a * 'a
let map f = function
| Int i -> Int i
| Pair (a,b) -> Pair (f a, f b)
let equal f x y =
match (x,y) with
| (Int i, Int j) when i = j -> ()
| (Pair (a1,b1), Pair (a2,b2)) -> f a1 a2; f b1 b2
| _ -> raise Recursive.NotEqual
let iter f x = ignore (map f x)
let hash f x = Hashtbl.hash (map f x)
let deep = 4
end
module X = Recursive.Make(I)
let cons x = let n = X.make () in X.define n x; n
let recurs f = let n = X.make () in X.define n (f n); n
let int' i = I.Int i
let int i = cons (int' i)
let pair' a b = I.Pair (a,b)
let pair a b = cons (pair' a b)
let x = recurs (fun x -> pair' (int 1) (pair (int 1) (pair (int 1) x)))
let y = recurs (fun y -> pair' (int 1) y)
let x = X.internalize x and y = X.internalize y
let () = Printf.printf "%i;%i;%b\n" (X.id x) (X.id y) (x = y)
(the equility test is specified by Recurse to run in constant time)
Side-note: be careful if you implement a language with subtyping and both
recursive types and recursive (cyclic) values. Indeed, the usual
equi-recursive definition of subtyping is not sound if you allow cyclic
values. For instance, the algorithm would say that the type ('a * 'a) as
'a is empty, even though it is inhabited by values.
-- Alain
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
next prev parent reply other threads:[~2002-07-28 20:15 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-07-27 17:32 John Max Skaller
2002-07-27 19:43 ` Alain Frisch
2002-07-28 1:45 ` John Max Skaller
2002-07-28 20:14 ` Alain Frisch [this message]
2002-08-01 14:49 ` [Caml-list] Question about distribution John Max Skaller
2002-08-01 15:48 ` Xavier Leroy
2002-08-03 17:34 ` Daniel de Rauglaudre
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=Pine.SOL.4.44.0207282143060.10604-100000@clipper.ens.fr \
--to=frisch@clipper.ens.fr \
--cc=caml-list@inria.fr \
--cc=skaller@ozemail.com.au \
/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