From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: * X-Spam-Status: No, score=1.5 required=5.0 tests=AWL,DNS_FROM_RFC_POST autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 9501EBBAF for ; Wed, 11 Mar 2009 03:46:03 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtkBAALDtkmArgWolGdsb2JhbACVLgEBAQEJCwgJEQS8QweEBgY X-IronPort-AV: E=Sophos;i="4.38,339,1233529200"; d="scan'208";a="36375259" Received: from expredir7.cites.uiuc.edu ([128.174.5.168]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 11 Mar 2009 03:46:02 +0100 Received: from axyr (aryx.cs.uiuc.edu [128.174.236.106]) by expredir7.cites.uiuc.edu (8.14.2/8.14.2) with ESMTP id n2B2k0A0005290; Tue, 10 Mar 2009 21:46:00 -0500 (CDT) To: Caml-list List Subject: typing problem with sexplib and mutually recursive polymorphic types From: Yoann Padioleau Date: Tue, 10 Mar 2009 21:45:58 -0500 Message-ID: <87prgoydy1.fsf@aryx.cs.uiuc.edu> User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Spam: no; 0.00; recursive:01 foo:01 sexp:01 sexp:01 foo:01 ocaml:01 ocaml:01 'int':01 'int':01 'let:01 polymorphic:01 rec:01 rec:01 rewrite:01 typing:01 Hi, I tried a slightly modified version of sexplib by jane street on this simple file foo.ml: type 'a x1 = 'a * 'a and x2 = int x1 and x3 = string x1 (* with sexp *) and succeeded to generate another file containing the sexp_of_xx code in a file foo2.ml: open Foo let rec x1_of_sexp__ = let _loc = "Xxx.x1" in fun _of_a -> function | Sexp.List ([ v1; v2 ]) -> let v1 = _of_a v1 and v2 = _of_a v2 in (v1, v2) | sexp -> Conv_error.tuple_of_size_n_expected _loc 2 sexp and x1_of_sexp _of_a sexp = try x1_of_sexp__ _of_a sexp with | Conv_error.No_variant_match ((msg, sexp)) -> Conv.of_sexp_error msg sexp and x2_of_sexp__ = let _loc = "Xxx.x2" in fun sexp -> x1_of_sexp Conv.int_of_sexp sexp and x2_of_sexp sexp = try x2_of_sexp__ sexp with | Conv_error.No_variant_match ((msg, sexp)) -> Conv.of_sexp_error msg sexp and x3_of_sexp__ = let _loc = "Xxx.x3" in fun sexp -> x1_of_sexp Conv.string_of_sexp sexp and x3_of_sexp sexp = try x3_of_sexp__ sexp with | Conv_error.No_variant_match ((msg, sexp)) -> Conv.of_sexp_error msg sexp let rec sexp_of_x1 _of_a (v1, v2) = let v1 = _of_a v1 and v2 = _of_a v2 in Sexp.List [ v1; v2 ] and sexp_of_x2 v = sexp_of_x1 Conv.sexp_of_int v and sexp_of_x3 v = sexp_of_x1 Conv.sexp_of_string v But then the ocaml type system refuses to type this second file with the error message: File "foo2.ml", line 22, characters 48-67: This expression has type Sexp.t -> string but is here used with type Sexp.t -> int Apparently the problem is that ocaml was not able to generalize the type of x1_of_sexp and that it's first utilisation with an 'int' force the x1_of_sexp to always return an 'int' instead of a 'string' in the second case. Is there a way to rewrite this generated code to avoid this typing problem ? Is it because of those 'let _loc = ... in fun ... ->" that distrubs the ocaml type system ?