
In my music translation program, I have a ton of data and configuration that goes into every note computation, so I've decided to use the State monad to pass it around. Also, the generated output is just a list of MIDI events, so I think I'll use Writer to gather the output. I will be dealing with several different MIDI synthesizers, which have different specifications and manner of control. But there is enough in common that I can write a single function to do the translation, provided that I provide that function with some data that is specific to the synth, and also I need to configure it with some functions specific to the synth. Let's say my State/Writer type is called Tr. type Tr a = StateT Configuration (Writer [MidiEvent]) a This is the data I provide to StateT: data Configuration = Configuration { t1 :: SynthSpecificData , f1 :: Tr SynthSpecificComputationResult , score :: WholeMusicalScore } So I need to write translate :: Tr () computeMidiEvents = runWriter (runStateT translate theConfig) So inside 'translate' I want to call 'f1' among many other things. Let's just consider the f1 call first. I wrote this first: translate = do f <- gets f1 f That works but looks a little weird. I think this works also: translate = join (gets f1) Is that better? D