
Am Mittwoch, den 16.09.2009, 03:23 -0700 schrieb Gregory Propf:
I'm playing around with a little program that implements a simple virtual machine. I want to use a monad to represent machine state. I created a data type for the machine (VM) and a monadic type for the monadic computations using it. I declared this an instance of MonadState and Monad and created the usual operators. That stuff works. My issue is that I want to run some functions in the machine monad, call it VMS - "virtual machine w/state" and then pull the underlying VM data structure out and print it.
I've read about monad transformers, lift, liftM, liftIO and all these instances in the libraries like MonadIO and am rather confused. The most sensible conclusion I can reach is that I probably need to create my own Transformer monad and define liftIO. Is this where I need to go? Also, my VMS monad doesn't really do anything different from the State monad except explicitly specify that state is a VM and not a generic type. Am I doing too much work creating my own instances here? Would a simple "type" statement work?
Yes. You can use the existing implementation of state monads: import Control.Monad.State and define a data type for the machine state data MS = VM { pc :: Int, heap :: MyHeap } and then you can define your monad via type MSM = State MS or, if you want your virtual machine to do some IO, type MSM = StateT IO MS Now functions that operate on the virtual machine state might have the following types: isInStopState :: MSM Bool doOneStep :: MSM () runUntilStopState :: MSM () doSomeSteps :: Int -> MSM Int