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: Pietro Abate <Pietro.Abate@a...>
Subject: Re: [Caml-list] Functional design for a basic simulation pipe.
On Thu, Oct 11, 2007 at 02:52:13PM +0100, Hugo Ferreira wrote:
> > 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:
[...]
> > 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.

There are two states. One is the state of the state monad, that is hidden and
that is basically the list of partial results. The other one is the state of
the function (your state), that is explicit.  the latest explicit state is the
variable "state" and the new state, result of the function b, is "newstate", that is
passed back in the loop with a recursive call. To avoid the (horrible)
exception in the middle of the computation, you can try to wrap the state monad
with and exception monad, so to make it more elegant. This is a simple
exception monad functor that you can use to compose the two monads
together.

module ExceptionMonadMake(T:sig type t end) =
struct
    type mt = Just of T.t| Nothing
    let return a = Just a
    let bind m f =
        match m with
        |Just v -> f v
        |Nothing -> Nothing
    let mzero = Nothing
    let mplus = function
        |Just v -> fun _ -> Just v
        |Nothing -> fun m -> m
    let trywith = mplus
    let lift f m = bind m f
end

Something that I haven't figure out yet is how to encode branching
computations using the same pattern to implement a finite state
machine.

pietro