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 4C9A47ED5C for ; Wed, 1 Aug 2012 21:13:37 +0200 (CEST) Received-SPF: None (mail1-smtp-roc.national.inria.fr: no sender authenticity information available from domain of markus.mottl@gmail.com) identity=pra; client-ip=74.125.82.180; receiver=mail1-smtp-roc.national.inria.fr; envelope-from="markus.mottl@gmail.com"; x-sender="markus.mottl@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail1-smtp-roc.national.inria.fr: domain of markus.mottl@gmail.com designates 74.125.82.180 as permitted sender) identity=mailfrom; client-ip=74.125.82.180; receiver=mail1-smtp-roc.national.inria.fr; envelope-from="markus.mottl@gmail.com"; x-sender="markus.mottl@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-we0-f180.google.com) identity=helo; client-ip=74.125.82.180; receiver=mail1-smtp-roc.national.inria.fr; envelope-from="markus.mottl@gmail.com"; x-sender="postmaster@mail-we0-f180.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtIBAE1/GVBKfVK0k2dsb2JhbABFuQgIIgEBAQEJCQsJFAQjgjkCExkBFAceAxIQXAEBEQEFASITGweHWwEDDAubOYJhCQOMI4JxhU8KGScNV4hxAQUMilaHcAOTdIFTgRSJdoMmPoQa X-IronPort-AV: E=Sophos;i="4.77,695,1336341600"; d="scan'208";a="168826704" Received: from mail-we0-f180.google.com ([74.125.82.180]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 01 Aug 2012 21:13:22 +0200 Received: by weyt11 with SMTP id t11so7119615wey.39 for ; Wed, 01 Aug 2012 12:13:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=PxmRgXZe+1wTl0swX3UW6nkBqTAWatJ99XaD5SJomgo=; b=Rp7W/bA4eeKnWQkBCaNsXZaSvLHW64PPbzCZO+9OfBLw0zI7elrlttGykgr4DJ31wS wKJqYSFACmR4KQhZNAW5ZjY5VfCQqLLXF1W2gYGAPJjy6Iv1fccM6KJ9Uz4KjkKpNYxa /Wa5OejjctFVMzXVsNZjOxZBd2yJdbG4A64+8ATSnRNVGyXNaRD8O9ucjNRtd6xlUdZ/ k/JfuJkEapUfiAIDsnq7K64NXXdme+GwsHVayAtPIa4WoSZvBL5Ux5A0B+BUdpVpaUDC 49a1idi7nonLyyR+54qXwDF4TnCKmwDJGsyuuVvaPHO5IKURsI0q/wBofQHvoIBdLVzE SEzg== MIME-Version: 1.0 Received: by 10.216.85.149 with SMTP id u21mr8846041wee.147.1343848401554; Wed, 01 Aug 2012 12:13:21 -0700 (PDT) Received: by 10.180.163.232 with HTTP; Wed, 1 Aug 2012 12:13:21 -0700 (PDT) Date: Wed, 1 Aug 2012 15:13:21 -0400 Message-ID: From: Markus Mottl To: OCaml List Content-Type: text/plain; charset=ISO-8859-1 Subject: [Caml-list] "Open" generics? Hi, I've recently been studying some of the nifty encodings for tagless-final interpreters, generics, and open GADTs, especially this one: http://okmij.org/ftp/ML/first-class-modules/index.html#generics This encoding of type representations seems particularly elegant. Given a value of type ('a repr) representing some type ('a), you can obtain a functor that can be instantiated with arbitrary interpreters for this type. You can then define functions like the following with great ease: val show : 'a repr -> 'a -> string val compare : 'a repr -> 'a -> 'a -> bool However, unless I'm mistaken, this particular approach seems to be suffering from one shortcoming: the representation of types cannot be open. One apparently cannot reuse already existing structured types and add e.g. new base types to them without having to duplicate (literally cut&paste) code. For example, this is the definition I use for representing the type of "pairs": let pair (type a) (type b) ((module A) : a repr) ((module B) : b repr) = ((module struct type t = a * b module Interpret (I : Interpretation) = struct module AI = A.Interpret (I) module BI = B.Interpret (I) let res = I.pair AI.res BI.res end end) : (a * b) repr) Lets assume the signature "Interpretation" supports type representations for integers and pairs: type 'a t val int : int t val pair : 'a t -> 'b t -> ('a * 'b) t The module returned by function "pair" contains a functor "Interpret" for interpreting types - but only for the "Interpretation" supporting "int" and "pair". Lets assume I wanted to add a new base type: val string : string t The only way I have managed to do this is by copying&pasting the above definition for "pair" into a context where the signature "Interpretation" also contains the definition for "string". This just doesn't feel right. It seems there must be some way of avoiding this annoying code duplication. Has anybody (Oleg? Jeremy? ;) ever played with these encodings and found a solution to this problem? This would be awesome for defining extensible type representations. Best regards, Markus -- Markus Mottl http://www.ocaml.info markus.mottl@gmail.com