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 mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by sympa.inria.fr (Postfix) with ESMTPS id 2708E7EC41 for ; Sat, 20 Oct 2012 00:10:48 +0200 (CEST) Received-SPF: None (mail1-smtp-roc.national.inria.fr: no sender authenticity information available from domain of yallop@gmail.com) identity=pra; client-ip=74.125.82.52; receiver=mail1-smtp-roc.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="yallop@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail1-smtp-roc.national.inria.fr: domain of yallop@gmail.com designates 74.125.82.52 as permitted sender) identity=mailfrom; client-ip=74.125.82.52; receiver=mail1-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 (mail1-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-wg0-f52.google.com) identity=helo; client-ip=74.125.82.52; receiver=mail1-smtp-roc.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="postmaster@mail-wg0-f52.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AmYBAEPPgVBKfVI0imdsb2JhbABFhhS6WggjAQEBCgkNBxIGI4IgAQEBBBICDwQZARsdAQMMBgULAwoCAiYCAiIBEQEFARwGEyKHTwEDD51lCQOLWU+CdoUFChknDVmIdQEFDIEUijqFXYESA5VvjlcWKYQS X-IronPort-AV: E=Sophos;i="4.80,617,1344204000"; d="scan'208";a="178076043" Received: from mail-wg0-f52.google.com ([74.125.82.52]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 20 Oct 2012 00:10:47 +0200 Received: by mail-wg0-f52.google.com with SMTP id fg15so701222wgb.9 for ; Fri, 19 Oct 2012 15:10:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=PVwxtTt1R6HG2c2hE94ZqoxZE4PvixM/ql6F4S9oFDI=; b=tk+un5M2ixHFcxett0GkMANZq5kUxNuo6HBWlMX9JJ5Is5tWxpPDiXw60hdNv5hE5i gAV8gUJPzNsTNjmC5hCmzODG/om7Vtis9ZDv42QHKPjXtgvnF71e6bpKIZdwvXxYPbVP yGicaQAIrDlghZb9CAqAE4OFpmFzuuYzuQf1Hhnm8WCbgqiECvMpuS18Td8LmOKo/qv0 1wALsskESmX3dJQluLMPI+rg7W6OWMZUG/dzQo2tqZ3nZn9+Wy+gqaX6xbpVIwc1wKXf WqvXW7PckqMZDYfiL4sIaKWyN8MPJWUqtD29phRPFgWSWujXoUH+9zHJaWGfe/Xbc5Yn 1JuA== MIME-Version: 1.0 Received: by 10.216.139.104 with SMTP id b82mr1534207wej.24.1350684647366; Fri, 19 Oct 2012 15:10:47 -0700 (PDT) Received: by 10.194.58.101 with HTTP; Fri, 19 Oct 2012 15:10:47 -0700 (PDT) In-Reply-To: References: Date: Fri, 19 Oct 2012 23:10:47 +0100 Message-ID: From: Jeremy Yallop To: Yaron Minsky Cc: caml-list@inria.fr, Stephen Weeks , David Powers , Nathan Linger Content-Type: text/plain; charset=UTF-8 Subject: Re: [Caml-list] A confusing example with modules and polymorphic variants On 19 October 2012 22:18, Yaron Minsky wrote: > We've been running into some troubles with polymorphic variants, > modules, and the value restriction, that we're not quite able to > unravel. Here's a stripped down version of the problem. > > module type S = sig > val z : [< `Foo ] > end > > let f z = > let module M : S = struct let z = z end in () I believe the problem here is the monomorphic parameter restriction: the type of S requires the field z to be polymorphic, but type inference only assigns monomorhpic types to function parameters. That is, your example doesn't type check for essentially the same reason that the following code doesn't type check: type s = { z : 'a. 'a -> 'a } let f z = let s = { z = z } in () One way to work around the monomorphic parameter assumption is to wrap the parameter in a record with a polymorphic field. type z_type = { field : 'a. 'a -> 'a} let f z = let s = { z = z.field } in () The parameter is still assigned a monomorphic type (z_type), but the projected field is polymorphic, as required. I don't see how to make that work in your case, though, because of the nature of the polymorphism -- i.e. it's based on a row variable rather than a standard type variable, and there isn't any syntax for quantifying it. However, you *can* modify your example so that it passes type checking by wrapping the argument in a first-class module, since module fields can be row-polymorphic. The easiest way in the cut-down example is to reuse the signature you already have: module type S = sig val z : [< `Foo ] end let f (module Z : S) = let module M : S = struct let z = Z.z end in ()