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.4 required=5.0 tests=SPF_NEUTRAL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from discorde.inria.fr (discorde.inria.fr [192.93.2.38]) by yquem.inria.fr (Postfix) with ESMTP id 3F5A3BC6C for ; Fri, 4 May 2007 00:31:09 +0200 (CEST) Received: from ug-out-1314.google.com (ug-out-1314.google.com [66.249.92.171]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id l43MV8nG021599 for ; Fri, 4 May 2007 00:31:09 +0200 Received: by ug-out-1314.google.com with SMTP id q2so512132uge for ; Thu, 03 May 2007 15:31:08 -0700 (PDT) DKIM-Signature: a=rsa-sha1; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:sender:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition:x-google-sender-auth; b=BIa9rp7Wlp04s/9KxNgJ29byh3OYCe9UfwTLncn8om+7MubgLyzeYl8tlqZ9DlsFuJsgPg6UOEMtMhS+aYgh3fFPglFxqI8S+mFe6Xbj3wLvDIKnnmS0hR6oV73DZMQAw8lSEPoBqZdqc7wOXDWkyCDdkn7CPT8pOTKqrsuRx5Y= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:sender:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition:x-google-sender-auth; b=XRFZvTsi6sLJ1H+ojQjzqPzQjcf3xMVG1urbFXodSDNszIJQOCiiB6TMvqxOtgLxC/Es39May2xi4w/X4bujsZhmq2aOQdhokmgs0U6B9pCZpibrFvAQGaO8fL6wQLj2vLXx1aQtiMfJazK9dT3iI7dJrhZv4Tyltamq0p1RPWw= Received: by 10.78.193.19 with SMTP id q19mr1194623huf.1178231467816; Thu, 03 May 2007 15:31:07 -0700 (PDT) Received: by 10.78.153.7 with HTTP; Thu, 3 May 2007 15:31:07 -0700 (PDT) Message-ID: <4a051d930705031531m396e42e7i6212137e2fb9cd53@mail.gmail.com> Date: Thu, 3 May 2007 18:31:07 -0400 From: "Christopher L Conway" Sender: christopherleeconway@gmail.com To: caml-list@yquem.inria.fr Subject: wrapping parameterized types MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline X-Google-Sender-Auth: c68fc50fbef853a5 X-Miltered: at discorde with ID 463A62AC.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; ocaml:01 mylist:01 strlist:01 mylist:01 strlist:01 val:01 val:01 functors:01 arises:01 abstraction:01 functions:01 surprising:01 int:01 int:01 expression:02 I recently ran across a rather surprising behavior in the OCaml type system. I hope somebody may be able to advise me how to work around it (or at least explain to me why things are the way they are!). Suppose I want to pass around a restricted, un-parameterized list type: # type mylist = Intlist of int list | Strlist of string list ;; type mylist = Intlist of int list | Strlist of string list Now I end up doing a lot of tedious case splits, like: # let length_of_mylist = function Intlist x -> List.length x | Strlist x -> List.length x ;; val length_of_mylist : mylist -> int = What one would like is something like "app_to_mylist : ('a list -> 'b) -> mylist -> 'b" so one could write "app_to_mylist List.length", but: # let app_to_mylist f = function Intlist x -> f x | Strlist x -> f x ;; Characters 65-66: let app_to_mylist f = function Intlist x -> f x | Strlist x -> f x ;; ^ This expression has type string list but is here used with type int list The solution I've tripped over is to pass in separate functions for the different cases, and then (only somewhat less tediously than above) duplicate the same function at the call site: # let app_to_mylist (fi,fs) = function Intlist x -> fi x | Strlist x -> fs x ;; val app_to_mylist : (int list -> 'a) * (string list -> 'a) -> mylist -> 'a = # let length_of_mylist = app_to_mylist (List.length, List.length);; val length_of_mylist : mylist -> int = I can't help but feel there is a more elegant way to handle this, perhaps drawing in objects or functors. Any suggestions? This question arises from an attempt to use the APRON library, which provides types parameterized by numerical domain, alongside other numerical tools in a uniform way---the APRON interface deals with the parameterized types generically, but I need to hoist the abstraction up one layer and deal with both APRON and non-APRON types generically. The details are far too ugly to wade into here... Thanks, Chris