From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 2269B7EEB4 for ; Sun, 3 Feb 2013 01:13:23 +0100 (CET) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of yallop@gmail.com) identity=pra; client-ip=209.85.212.179; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="yallop@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of yallop@gmail.com designates 209.85.212.179 as permitted sender) identity=mailfrom; client-ip=209.85.212.179; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="yallop@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-wi0-f179.google.com) identity=helo; client-ip=209.85.212.179; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="postmaster@mail-wi0-f179.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AhoCAL+qDVHRVdSzjWdsb2JhbABFhki4YQgWDgEBAQEJCQsJEgYjgh8BAQUjBBkBGx0BAwwGBQsDCgICJgICIQEBEQEFARwGE4d+AQMPo1yLZU+Ce4NzChknDVmIdwEFDIEXinqEIoETA5RHgViLP4MxFimEHg X-IPAS-Result: AhoCAL+qDVHRVdSzjWdsb2JhbABFhki4YQgWDgEBAQEJCQsJEgYjgh8BAQUjBBkBGx0BAwwGBQsDCgICJgICIQEBEQEFARwGE4d+AQMPo1yLZU+Ce4NzChknDVmIdwEFDIEXinqEIoETA5RHgViLP4MxFimEHg X-IronPort-AV: E=Sophos;i="4.84,591,1355094000"; d="scan'208";a="1134932" Received: from mail-wi0-f179.google.com ([209.85.212.179]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 03 Feb 2013 01:13:22 +0100 Received: by mail-wi0-f179.google.com with SMTP id ez12so1802445wid.12 for ; Sat, 02 Feb 2013 16:13:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:x-received:in-reply-to:references:date:message-id :subject:from:to:cc:content-type; bh=N327kXbQyCzqNY6RgrpRC6irg3AJYaGvH1jv2wRGtP0=; b=Aj1QrLcwx4BdMcjtRgJmwiGu+VOa5I5pkOai7QHtJEv8B1zejmHSjb2MHFx5pptkvQ ujow7fUB0bQd/nyHnbqo3bQNz1DLyeeefGcXrsTTfCyErQ2Kr+uxXsWRJZ9AAj0H74Z7 BYpIfGx5zQZEKQFeFqw2pgE9VygU12tjOSJdRvQMPZGeqi3fXwW27juZuO9G07ZCjrpD YZchHSjZ7IYHJVSDCPOpZAivio26zneVeeyqZdgBXKkVaLxLwlEMDQU/aPsMrxSxcUfJ Iojmngwm9fQvTTn9gq9PLeeE26xGkUhnrrnlRJ8DxDNAsxVX9evBt55GTBCvFBXQuOIa vK2Q== MIME-Version: 1.0 X-Received: by 10.194.21.70 with SMTP id t6mr28337959wje.42.1359850402557; Sat, 02 Feb 2013 16:13:22 -0800 (PST) Received: by 10.217.39.129 with HTTP; Sat, 2 Feb 2013 16:13:22 -0800 (PST) In-Reply-To: References: Date: Sun, 3 Feb 2013 00:13:22 +0000 Message-ID: From: Jeremy Yallop To: Reed Wilson Cc: caml-list@inria.fr Content-Type: text/plain; charset=UTF-8 Subject: Re: [Caml-list] Objects and polymorphic variants On 2 February 2013 23:18, Reed Wilson wrote: > What I really want is a signature like this: > method private method_12 : int -> [ > `One | `Two ] > method method_123 : int -> [ `One | `Two | `Three ] > method method_124 : int -> [ `One | `Two | `Four ] > > If I replace method_12 with a function outside the class it works fine, but > for whatever reason method_12 really wants to be the exact same type as > method_123 and method_124. > > Is there any way around this typing requirement for methods? I think that the problem arises because methods are typed similarly to mutually-recursive functions. Unless you give type signatures, both functions that are marked as mutually recursive and methods are assumed to be monomorhpic. For example, in let rec f = fun x -> x and g = fun x -> f (x + 1) the types are val f : int -> int val g : int -> int i.e. f is assigned the type with which it is used in the body of g. If you remove the (unnecessary) mutual recursion then the more general types will be inferred; for example, in let f = fun x -> x let g = fun x -> f (x + 1) the types are val f : 'a -> 'a val g : int -> int It's also possible to ensure that f is assigned the more general type by using a type signature: let rec f : 'a. 'a -> 'a = fun x -> x and g = fun x -> f (x + 1) With objects, the situation is similar, except that you can't mark methods non-recursive, so you have to give a type signature to avoid the monomorphising. So object (self) method f = fun x -> x method g = fun x -> self#f (x + 1) end receives the type < f : int -> int; g : int -> int > whereas object (self) method f : 'a. 'a -> 'a = fun x -> x method g = fun x -> self#f (x + 1) end receives the more general type < f : 'a. 'a -> 'a; g : int -> int > In your example you can ensure that the type you want is inferred by annotating method_12 with a polymorphic signature: object (self) method private method_12 : 'a. int -> ([> `One | `Two] as 'a) = function | 1 -> `One | _ -> `Two method method_123 = function | 3 -> `Three | x -> self#method_12 x method method_124 = function | 4 -> `Four | x -> self#method_12 x end Now the inferred types for method_123 and method_125 are distinct: < method_123 : int -> [> `One | `Three | `Two ]; method_124 : int -> [> `Four | `One | `Two ] > Hope that helps a bit, Jeremy.