Article View: fa.caml
Article #58Re: [Caml-list] GADT and locally ADT
From: Gabriel Scherer
Date: Tue, 04 Jun 2013 09:23
Date: Tue, 04 Jun 2013 09:23
101 lines
7110 bytes
7110 bytes
In expressions, type variables 'a 'b do not enforce polymorphism, they
are merely name for types that will be inferred.
let f : 'a -> 'a = fun x -> x + 1
is accepted. So your second example with ('a, 'b) does not enforce polymorphism.
This is not in general a problem as if the inferred type is indeed a
type variable, it will be generalized by the inference algorithm and
therefore "turned into polymorphism" after type inference. It is
problematic however for polymorphic recursive functions (this form of
polymorphism would have to be "guessed" before the recursive
definition is type-checked, and therefore requires an annotation), and
for GADTs.
There are two *distinct* notions used to enforce polymorphism:
- polymorphic type variables as in
val f : 'a -> 'a
or
let f : 'a . 'a -> 'a = ...
(useful for polymorphic recursion)
- local abstract types
let f (type t) : t -> t = ...
fun (type t) -> ...
(useful for GADTs)
Local abstract types are documented in
http://caml.inria.fr/pub/docs/manual-ocaml/manual021.html#toc80 . They
are not type variable (they cannot be unified with anything, hence
enforce polymorphism), but type "constructors" syntactically (like
'list' in ('a list), but without a parameter). We say that GADTs
introduce equations and refine types; they can only refine local
abstract types, not type variables. The refinement of GADT types is
similar to what happen when you traverse a module abstraction, outside
you know the abstract type M.t, and inside you know (type M.t = int).
Due to this "implementation detail" of GADTs, the following code (that
enforces polymorphism) would still fail to type-check:
let f : 'b . ('a, 'b) access -> unit = function
| ReadWrite ch -> ()
| Read ch -> ()
while the following work
let f (type t) : ('a, t) access -> unit = function
| ReadWrite ch -> ()
| Read ch -> ()
Finally, the syntax
let f : type t . ('a, t) acc -> unit = function ...
is a merge of both ('a 'b . ...) and ((type t) ...): it provides a
local type constructor, and enables polymorphic recursion. This is
what you should use when you write recursive functions using GADTs.
On Tue, Jun 4, 2013 at 9:23 AM, Ivan Gotovchits <ivg@ieee.org> wrote:
> Gabriel Scherer <gabriel.scherer@gmail.com> writes:
>
>> If the function knows (or infer) that the argument type is (ro), then
>> there is only one case to handle. But there is also a function that is
>> polymorphic over the second argument, and it must be callable with
>> both (ro) and (rw) values : this function works "for any access mode".
>> This is what the annotated function
>>
>>> let f (type t) (inp: ('a,t) access) = match inp with
>>> | ReadWrite (ch) -> ()
>>> | Read (ch) -> ();;
>>
>> does.
>
> Looks reasonable, but can you, please, explain the difference between
> function:
>
> let f (type t) (inp: ('a,t) access) = match inp with
> | ReadWrite ch -> ()
> | Read ch -> ()
>
> that have type
>
> val f : ('a, 'b) access -> unit
>
> and
>
> let f (inp: ('a,'b) access) = match inp with
> | ReadWrite ch -> ()
> | Read ch -> ()
>
> that fails to type check:
>
> Error: This pattern matches values of type ('a, ro) access
> but a pattern was expected which matches values of type
> ('a, rw) access
--
Caml-list mailing list. Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs
Technical Details
Message-ID:
<fa.VzNuip7GYmj600lhLCiyJU+3Vx4@ifi.uio.no>Path:
arc1-ca.pugleaf.net!bp1ni803pbd.1!nntp.google.com!npeer03.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!news.glorb.com!uio.no!nntp.uio.no!.POSTED!not-for-mailReferences:
<fa.5uFIA2a5E/43K8sy3BbYsXbUjtk@ifi.uio.no> <fa.+5gzXTlVscJHgiTcnUiWBvFqC9g@ifi.uio.no> <fa.4wTtUJBjom5lGm7CE7pw++GEMrQ@ifi.uio.no>Show Full Headers
Complete Article Headers
X-Google-Thread: c0fe4b917e,e559dbf6f40dc76e
X-Google-Attributes: gidc0fe4b917e,public,usenet
X-Google-NewGroupId: yes
X-Google-Language: ENGLISH,ASCII-7-bit
X-Received: by 10.66.234.7 with SMTP id ua7mr4232067pac.32.1370337831773;
Tue, 04 Jun 2013 02:23:51 -0700 (PDT)
Path: arc1-ca.pugleaf.net!bp1ni803pbd.1!nntp.google.com!npeer03.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!news.glorb.com!uio.no!nntp.uio.no!.POSTED!not-for-mail
From: Gabriel Scherer <gabriel.scherer@gmail.com>
Newsgroups: fa.caml
Subject: Re: [Caml-list] GADT and locally ADT
Date: Tue, 04 Jun 2013 09:23:51 UTC
Organization: Internet mailing list
Lines: 101
Sender: caml-list-request@inria.fr
Message-ID: <fa.VzNuip7GYmj600lhLCiyJU+3Vx4@ifi.uio.no>
References: <fa.5uFIA2a5E/43K8sy3BbYsXbUjtk@ifi.uio.no> <fa.+5gzXTlVscJHgiTcnUiWBvFqC9g@ifi.uio.no> <fa.4wTtUJBjom5lGm7CE7pw++GEMrQ@ifi.uio.no>
NNTP-Posting-Host: mail-jess.uio.no
Mime-Version: 1.0
X-Trace: readme.uio.no 1370337831 6949 129.240.7.9 (4 Jun 2013 09:23:51 GMT)
X-Complaints-To: abuse@uio.no
NNTP-Posting-Date: Tue, 4 Jun 2013 09:23:51 +0000 (UTC)
Cc: caml-list@inria.fr
To: Ivan Gotovchits <ivg@ieee.org>
X-IronPort-AV: E=Sophos;i="4.87,798,1363129200";
d="scan'208";a="20216255"
X-Original-To: caml-list@sympa.inria.fr
Delivered-To: caml-list@sympa.inria.fr
X-IronPort-Anti-Spam-Filtered: true
X-IronPort-Anti-Spam-Result: ArgAAPKwrVHRVdYvjWdsb2JhbABZgzm/CXoIFg4BAQEBBwsLCRIGJIIjAQEFJxkBGx0BAwwGBQsDCi4hAQERAQUBHAYTh3oBAw8Mnl+MSoJ9hRMKGScNWIguAQUMjECCWgeDWAOVWIFmgSmKdIM+FimENzo
X-IPAS-Result: ArgAAPKwrVHRVdYvjWdsb2JhbABZgzm/CXoIFg4BAQEBBwsLCRIGJIIjAQEFJxkBGx0BAwwGBQsDCi4hAQERAQUBHAYTh3oBAw8Mnl+MSoJ9hRMKGScNWIguAQUMjECCWgeDWAOVWIFmgSmKdIM+FimENzo
X-IronPort-AV: E=Sophos;i="4.87,798,1363129200";
d="scan'208";a="20216158"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=20120113;
h=mime-version:in-reply-to:references:from:date:message-id:subject:to
:cc:content-type;
bh=lh0kaThtg/A6/eDmlQfFzR2ImFeNXF8A5hO53ySD5z4=;
b=p86nuN55iA6c2HnuMr5dbulxoo7hWfBn/7DWSvmrNgxz24dV25AQcYjxzfG6BZ3AOP
FRUnpK+lRznJc3Vvb09nDhIZkftYuii2r59aXsMefQOutl8XqSbhyXUP4jWZN0FZpozq
Gp2TdZ8XayM/NGxyaEWZ8tlJ66L3fgB8PVEJAeQYMB6G5otSmsUND7iACbEE45jXvSEm
T9Iw6nSLhGTdgS/8IQxWFXetnA8Fg1eGhaXoHtWZsiptRAjh8/Q6D6u1KJA2ZpTeVK5j
XGceYvBU3M47zHeMzs+0IKwjEMnDz8G7T2uQ3tKbWm8IrZtwgceG3+hSetrCksWdzjFt
mVow==
X-Received: by 10.204.240.15 with SMTP id ky15mr5724489bkb.144.1370337821173;
Tue, 04 Jun 2013 02:23:41 -0700 (PDT)
In-Reply-To: <87a9n6s5jo.fsf@golf.niidar.ru>
X-Sequence: 6888
X-no-archive: yes
List-Id: <caml-list.inria.fr>
List-Archive: <http://sympa.inria.fr/sympa/arc/caml-list>
List-Help: <mailto:sympa_inria@inria.fr?subject=help>
List-Owner: <mailto:caml-list-request@inria.fr>
List-Post: <mailto:caml-list@inria.fr>
List-Subscribe: <mailto:sympa_inria@inria.fr?subject=subscribe%20caml-list>
List-Unsubscribe: <mailto:sympa_inria@inria.fr?subject=unsubscribe%20caml-list>
Original-Date: Tue, 4 Jun 2013 11:23:01 +0200
Original-Message-Id: <CAPFanBE=Zs_tzNqaJ_2YMjoeH+ycc=O6SF2MAbW6y-kMbgB5aA@mail.gmail.com>
Original-References: <87ehciseni.fsf@golf.niidar.ru> <CAPFanBEau9FFNJAVF+9RyhfnbuLi+smcW3Hc6bk2BMxM3ysnnA@mail.gmail.com>
<87a9n6s5jo.fsf@golf.niidar.ru>
X-Received-Bytes: 6726
Content-Type: text/plain; charset=ISO-8859-1