Browse thread
Functional design for a basic simulation pipe.
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Hugo Ferreira <hmf@i...> |
| Subject: | Re: [Caml-list] Functional design for a basic simulation pipe. |
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 >