[
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: | Markus Mottl <mottl@m...> |
| Subject: | Re: Language Design |
On Fri, 01 Sep 2000, Dave Berry wrote: > Given a value in a monad, e.g. IO v, how can I remove v from the Monad? > Surely this would be required to seamlessly integrate stateful and > functional code? Well, that's the idea behind monads that you (normally) shouldn't: you must not be able to run a function with the same arguments and get a different result. That's the way I/O-monads work in e.g. Haskell. However, there are different monads, e.g. "state monads", which allow for a function that takes a state, the computation (in the monad) and runs the computation on (in) the given state, returning the result as "normal" value. This does not circumvent referential transparancy unless running the computation in the monad in the same state can yield different results (e.g. you use I/O, random numbers, etc.). You can find an OCaml-implementation of state monads here (with an example application, namely an interpreter for a simple imperative language): http://miss.wu-wien.ac.at/~mottl/ocaml_sources/IMP-1.0-2/monad E.g. the following program: --------------------------------------------------------------------------- open State_monad open Printf let test = fetchST >>= fun state -> unitST (printf "First state: %d\n" state) >> assignST 2 >> unitST "is 42" >>= fun answer -> unitST (printf "Answer %s\n" answer) >> fetchST >>= fun state -> unitST (printf "Second state: %d\n" state) >> assignST 3 let _ = printf "State in monad: %d\n" (initST 1 (test >> fetchST)) --------------------------------------------------------------------------- prints: First state: 1 Answer is 42 Second state: 2 State in monad: 3 As you seen in the code, the state is propagated implicitely. Only when you want to "look" at it, you use "fetchST", and you use "assignST" to overwrite it. "initST" does what you asked for: it "runs" the computation in "test" starting with a specific state (the integer 1) and returns whatever the monad wants to return. In this case we force the monad to return the internal state by attaching "fetchST" to "test". Best regards, Markus Mottl -- Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl