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=0.3 required=5.0 tests=AWL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 3EB16BBC1 for ; Mon, 24 Mar 2008 23:19:15 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgUCAHfF50fRVYa6d2dsb2JhbACRFwEMBQIFCRSSWYQi X-IronPort-AV: E=Sophos;i="4.25,548,1199660400"; d="scan'208";a="24134966" Received: from mu-out-0910.google.com ([209.85.134.186]) by mail4-smtp-sop.national.inria.fr with ESMTP; 24 Mar 2008 23:19:14 +0100 Received: by mu-out-0910.google.com with SMTP id w8so4065428mue.4 for ; Mon, 24 Mar 2008 15:19:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:sender:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references:x-google-sender-auth; bh=nqi33fOgkPk1oq7AoVocbWOrOBfF3/YgGP+zpF8XSyA=; b=Fe115cGfeX+cPjoYR7nRFjRtUdgaKxaPJzNvABkFnQ338sXBhOmrl/5grfw3nSPlSK2yc+JZALg6eneRMg41ZWnhiqn8may/sq/ArS68+/sTk85SNe+g7yR+coembmFmkljzkfah9EYrRd1OHw+WXlvDx2BYRpLnIIFUrpVPUo8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=message-id:date:from:sender:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references:x-google-sender-auth; b=sAbiK23/JGfZ8KP3a435ioPsE4Ad+priPFtnHHu8dUcZZ6uRN3zWhzx2qlym408hwnV0K5J55T2KA9WGiXPp8VYIqN6J/pQrKt0UxR6O4lGflvl09I16xzoMfKSGbI0pAVRJmJKVP+M+hYjLKFnt/q0z2r8mIvcQA5Im1W8MEYU= Received: by 10.78.178.5 with SMTP id a5mr17213435huf.5.1206397154154; Mon, 24 Mar 2008 15:19:14 -0700 (PDT) Received: by 10.78.157.6 with HTTP; Mon, 24 Mar 2008 15:19:14 -0700 (PDT) Message-ID: <4a051d930803241519j36c2cc7cm7d3cb745acaa6af@mail.gmail.com> Date: Mon, 24 Mar 2008 18:19:14 -0400 From: "Christopher L Conway" Sender: christopherleeconway@gmail.com To: "Dario Teixeira" Subject: Re: [Caml-list] Sources, sinks, and unbound parameter types Cc: caml-list@yquem.inria.fr In-Reply-To: <535050.42465.qm@web54603.mail.re2.yahoo.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <535050.42465.qm@web54603.mail.re2.yahoo.com> X-Google-Sender-Auth: d446095944da9088 X-Spam: no; 0.00; haskell:01 datatype:01 node:01 transforming:01 ocaml:01 node:01 nodes:01 inputs:01 inputs:01 printf:01 printf:01 compiler:01 statically:01 syntax:01 ocaml:01 This looks a lot like the "Lists of Composable Functions" example using existentials cited here last week [1]. Your comment about the type of Source and Sink being too general is interesting. In general, you're asking for GADTs [2], though this instance is simple enough you could possibly hack up a solution without them. Chris [1] http://groups.google.com/group/fa.caml/msg/8f11bc7839aac98f [2] http://www.haskell.org/haskellwiki/Generalised_algebraic_datatype On Mon, Mar 24, 2008 at 5:56 PM, Dario Teixeira wrote: > Hi, > > I'm looking for a way to express the composition of functional components > in a tree-like data structure. Each node in the tree is either: > > a) a Source, producing values "out of nowhere": unit -> 'a > b) a Sink, end point of the tree: 'b -> unit > c) a Processor, transforming values from one type to another: 'c -> 'd > > > The Ocaml type that represents a node is as follows: (pretty > straightforward, though I wonder if there's a way to explicitly > say that "Source is of 'a -> 'b where 'a must be of type unit") > > type ('a, 'b) node_t = > | Source of (unit -> 'b) > | Sink of ('a -> unit) > | Processor of ('a -> 'b) > > > In addition, there are two types of connectors linking these nodes in the tree: > > a) a Pipe, connecting one node that outputs a value of type 'a into > another that inputs an 'a. > b) a Splitter, essentially like a Pipe, but able to feed the same > value into multiple inputs. > > > If you'll pardon the ASCII art, here's a diagram of one such simple tree: > > > | =========== > | | source1 | > | =========== > | | > | | > | O Pipe > | | > | | > | ============ > | | process1 | > | ============ > | | > | | > | ----------------O---------------- > | | Splitter | > | | | > | =========== =========== > | | sink1 | | sink2 | > | =========== =========== > > > Where each component node can, for example, be defined as follows: > > let source1 () = 10 > let process1 n = 2.0 *. (float_of_int n) > let sink1 x = Printf.printf "Sink1: %f\n" x > let sink2 x = Printf.printf "Sink2: %f\n" x > > > To define the tree type, I would like to express something like the code > below. Note that I am trying to get to the compiler to statically enforce > that outputs and inputs are correctly matched type-wise. > > type ('a, 'b) tree_t = > | Node of ('a, 'b) node_t > | Pipe of ('a, 'c) tree_t * ('c, 'b) tree_t > | Splitter of ('a, 'c) tree_t * ('c, 'b) tree_t list > > > The code above obviously won't work because of the unbound type parameter 'c. > (Also, please ignore for now the fact it allows splitters with an empty > output list -- that can easily be circumvented). > > So, my question is if there is any way to express what I want? I guess there > is a solution involving the creation of a syntax extension, but I'm looking > for a pure Ocaml way. > > Thanks in advance for your time! > Best regards, > Dario Teixeira > > > > > > > ___________________________________________________________ > Rise to the challenge for Sport Relief with Yahoo! For Good > > http://uk.promotions.yahoo.com/forgood/ > > _______________________________________________ > Caml-list mailing list. Subscription management: > http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list > Archives: http://caml.inria.fr > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs > >