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.2 required=5.0 tests=AWL,SPF_SOFTFAIL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by yquem.inria.fr (Postfix) with ESMTP id 0BB2EBC6C for ; Thu, 11 Oct 2007 15:53:39 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAANbHDUfAI/YBnWdsb2JhbACBWoxwAQEBAQsP X-IronPort-AV: E=Sophos;i="4.21,260,1188770400"; d="scan'208";a="2872087" Received: from ns.inescn.pt (HELO animal.inescn.pt) ([192.35.246.1]) by mail2-smtp-roc.national.inria.fr with ESMTP; 11 Oct 2007 15:53:38 +0200 Received: from localhost (localhost [127.0.0.1]) by animal.inescn.pt (8.13.8/8.13.6/9) with ESMTP id l9BDrQAM010724; Thu, 11 Oct 2007 14:53:26 +0100 (WEST) X-Virus-Scanned: amavisd-new at inescporto.pt Received: from animal.inescn.pt ([127.0.0.1]) by localhost (animal.inescn.pt [127.0.0.1]) (amavisd-new, port 10024) with LMTP id dk0WH39CQw0H; Thu, 11 Oct 2007 14:52:51 +0100 (WEST) Received: from [194.117.30.94] (morfina.inescn.pt [194.117.30.94]) by animal.inescn.pt (8.13.8/8.13.8/26) with ESMTP id l9BDqGXM010538; Thu, 11 Oct 2007 14:52:16 +0100 (WEST) Message-ID: <470E2A8D.4040704@inescporto.pt> Date: Thu, 11 Oct 2007 14:52:13 +0100 From: Hugo Ferreira User-Agent: Thunderbird 2.0.0.6 (X11/20070806) MIME-Version: 1.0 To: Pietro Abate Cc: caml-list@yquem.inria.fr Subject: Re: [Caml-list] Functional design for a basic simulation pipe. References: <470C8199.4080708@inescporto.pt> <1192005274.6285.4.camel@rosella.wigram> <470CA488.1070804@inescporto.pt> <3EDA3D93-DE9A-4336-B65E-03593A3B9723@yahoo.fr> <470CAFC2.2020406@inescporto.pt> <20071011120139.GA8588@pulp.rsise.anu.edu.au> In-Reply-To: <20071011120139.GA8588@pulp.rsise.anu.edu.au> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Spam: no; 0.00; 0100,:01 monads:01 sig:01 struct:01 struct:01 endline:01 0,1:01 printf:01 printf:01 iter:01 ocaml:01 beginner's:01 ocaml:01 bug:01 beginner's:01 Hi, Pietro Abate wrote: > Hi, > > On Wed, Oct 10, 2007 at 11:56:02AM +0100, Hugo Ferreira wrote: >>>> a: requires the input of a state and outputs an event >>>> b: requires input of a state and the event generated at that state and >>>> outputs processed data >>>> c: consumes n number elements of processed data and stops when it >>>> requires no more such data >>>> >>>> Note that "c" will "pull in" for example 10 states and check for >>>> termination, "b" will therefore need "pull in" 10 events. Each time it >>>> pulls in an event it generates a state. This last state must be made >>>> available to "a" so that it may generate its next event. >>>> >>>> The issue here is how can I implement this so that I can flexibly >>>> configure experiments by "constructing" a chain of actions but still be >>>> able to pass back the state to one of those actions. Something like: >>>> >>>> let exp = a |> b (output 1 back to a) |> c > I'm not entirely sure this is correct. Note that I've used an exception > to get out of the loop just because I'm too lazy to wrap my head around > the exception monad. I'm also not sure that is the best way of using a > state monad... Any monad-experts out there to comment ? > I am going to have to look at this very carefully (read: learn something about monads). Comment below. > This is the code: > > type inputstate = int > type output = int > type final = int > type event = int > > module StateMonadMake(T:sig type t end) = > struct > type 'state mt = 'state -> T.t * 'state > > let return a = fun s -> a, s > let bind m f = fun s -> let a, s = m s in f a s > let fetch = fun s -> return s s > let store = fun s -> fun _ -> return () s > let modify f = fun s -> return () (f s) > end > > module SM = StateMonadMake(struct type t = inputstate end) > exception Stop of final > > let a (s : inputstate) : event = 1 > > let b (e : event) ( s : inputstate ) : (inputstate * output) = > match s with > 0 -> print_endline "final state" ; (0,1) > |_ -> Printf.printf "at state %i\n" s ; (s-1,s+1) > > let c ( l : output list ) : final = > List.iter print_int l ; > List.fold_left (+) 0 l > > let rec exp inputstate = > SM.bind inputstate (fun state -> > let newevent = a state in > let (newstate,newdata) = b newevent state in > SM.bind (SM.modify (fun olddata -> newdata::olddata)) (fun _ -> > if newstate = 0 then > SM.bind (SM.fetch) (fun data -> > raise ( Stop ( c (data) )) > ) > else exp (SM.return newstate) > ) > ) > ;; > I can however see that "exp" seems to be a loop. Cannot see however were you tie the latest state of "a" with the next use of "b" 8-(. I will really have to see how this stuff works. Thanks. Hugo F. > let run = > try exp (SM.return 10) [] > with Stop(i) -> Printf.printf "final %i\n" i > > $ocaml hf.ml > at state 10 > at state 9 > at state 8 > at state 7 > at state 6 > at state 5 > at state 4 > at state 3 > at state 2 > at state 1 > 234567891011final 65 > > > pietro > >>> Just to be sure I understood well, here is a diagram: >>> >>> --> a --> b -+-------------------------------------------------> output1 >>> | >>> +--state1-> a --> b -+----------------------------> output2 >>> | >>> +-state2-> a --> b -+--------> output3 >>> | >>> ... >>> -> outputn >>> >>> | >>> | >>> | >>> V >>> >>> c >>> >>> >>> Do you agree with this ? (n beeing a variable of course...) >> Not quite. More like: >> >> (_,s0) >> -> a-> s0,e1 -> b -+--------------------------------------> s1 >> | >> +--s1-> a -> s1,e2 -> b-+--------------> s2 >> | >> ... >> -> sn >> | >> | >> | >> V >> c >> >> Note that "a" doesn't generates states "sn" it just passes it on. >> It only generates events "en". "b" simple takes a state "sn-1" and the >> events "en" and generates a new state "sn". >> >>> Shall c also take the states ? >>> >> Yes. But the idea is to add other functions to the "pipe" that will >> change states to other data types for further processing. >> >> Note also that only the last function actually knows how much data is >> required. >> >>> (I believe in good drawings to help finding an answer...) >> Well it certainly easier to express the flow of the data. >> >> >> >>> _______________________________________________ >>> 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 >>> >>> >> _______________________________________________ >> 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 >