Version française
Home     About     Download     Resources     Contact us    
Browse thread
Functional design for a basic simulation pipe.
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Hugo Ferreira <hmf@i...>
Subject: Functional design for a basic simulation pipe.
Hello,

I have been looking at how I may go about developing a very simple
simulation system for my experiments. The simulation consists in
generating a set of events, these events then cause a state change, the
state change is then analyzed and processed in several steps and finally
termination conditions are checked. When said termination condition is
true the simulation ends and the results are saved.

Now I figured this could be done using composition. For example:

# let ( |> ) f g x = g (f x) ;;
val ( |> ) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c = <fun>

# let gen_events s0 = () ;;
val gen_events : 'a -> unit = <fun>

# let gen_states e = () ;;
val gen_states : 'a -> unit = <fun>

# let analyze_data s = () ;;
val analyze_data : 'a -> unit = <fun>

# let check_stop s = () ;;
val check_stop : 'a -> unit = <fun>

Then I could set-up an experiment so:

# let exp = gen_events |> gen_states |> analyze_data |> check_stop ;;
val exp : '_a -> unit = <fun>

And execute it so:

# let start_state = () ;;
val start_state : unit = ()

# let _ = exp start_state ;;
- : unit = ()

Please note that I have used any old types just to get the idea through.
Also note that experiments are set-up with a given set of parameters.
Such parameters can be defined when the "exp" composition is set up.

Ok, so far so good. Now notice how the data events and state change are
potentially infinite. I figured the best way to go about it is with lazy
evaluation so that the calculations terminate when the last function in
the pipe stop "pulling" data in.

This is all "fine and dandy" but the problem I have however is that the
"gen_events" function depends on the last state reached. In other words
"gen_states" updates the current state which should then be made
available to "gen_events" when the next events are "pulled in". Of
course this could be solved with a global reference but this is not
functional. Alternatively we could combine "gen_events" and "gen_state"
into one function (my best bet?).

My question is: how can one design and implement such a "pull pipe" and
solve the problem I have of propagating state back to a previous
function. If this is not possible functionally what other options do I
have? Better yet, what is the better way to implement such a system?

TIA,
Hugo F.