From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 7EE2CBC51 for ; Fri, 12 Nov 2004 17:44:00 +0100 (CET) Received: from pauillac.inria.fr (pauillac.inria.fr [128.93.11.35]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id iACGi0VI029131 for ; Fri, 12 Nov 2004 17:44:00 +0100 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id RAA32296 for ; Fri, 12 Nov 2004 17:43:59 +0100 (MET) Received: from swordfish.havenrock.com ([216.241.35.41]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id iACGhwau029117 for ; Fri, 12 Nov 2004 17:43:59 +0100 Received: by swordfish.havenrock.com (Postfix, from userid 1000) id 1E636AC68; Fri, 12 Nov 2004 09:44:54 -0700 (MST) Date: Fri, 12 Nov 2004 09:44:54 -0700 From: Matt Gushee To: caml-list@inria.fr Subject: Re: [Caml-list] Specifying abstract type in a record Message-ID: <20041112164454.GA7818@swordfish> Reply-To: Matt Gushee Mail-Followup-To: caml-list@inria.fr References: <20041111083547.GA13116@pulp.anu.edu.au> <1100163369.2579.70.camel@pelican.wigram> <20041111090931.GA13972@pulp.anu.edu.au> <20041111104849.29e7e506@mpiat2314> <4194E0C7.4060102@trdlnk.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4194E0C7.4060102@trdlnk.com> User-Agent: Mutt/1.3.27i X-Miltered: at concorde with ID 4194E850.001 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Miltered: at concorde with ID 4194E84E.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; caml-list:01 wrote:01 mli:01 sig:01 polymorphism:01 syntax:01 ...:98 nation:98 nation:98 streets:98 unbound:01 abstract:01 abstract:01 expression:01 structures:01 X-Spam-Checker-Version: SpamAssassin 3.0.0 (2004-09-13) on yquem.inria.fr X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.0.0 X-Spam-Level: On Fri, Nov 12, 2004 at 10:11:51AM -0600, josh wrote: > # type doer = { file_name:string ; actor: ('a -> unit) };; > > But when I do this, it tells me that I've got "Unbound type parameter 'a > ". Your first impulse was on the right track, but see below. > # type t > # type doer = { file_name:string; actor (t -> unit) };; > > It works until I try to use a created record: > > # let b = {file_name = "one"; actor = (fun x -> () ) };; > # b.actor 10;; > The expression has type int but is used with type t Right. You can't directly *use* an abstract type. Generally, you would declare an abstract type in an interface--an .mli file, a module sig, or a class type--then specify it ('type t = ...') in an implementation. Abstract types are good for keeping implementation details hidden from the user, but they don't, by themselves, give you polymorphism. > it doesn't work. So, how _can_ I specify a record with an abstract > field? type 'a doer = { file_name : string; actor : ('a -> unit) } That's known as a parameterized record type. You would also do the same thing for other data structures, and for objects (though the syntax is a bit different in the latter case) -- Matt Gushee When a nation follows the Way, Haven Rock Press Horses bear manure through Englewood, Colorado, USA its fields; books@havenrock.com When a nation ignores the Way, Horses bear soldiers through its streets. --Lao Tzu (Peter Merel, trans.)