Answering my own plea for help, I now have the following, which seems neater to me.
checking Maybes is best done in the Maybe Monad, or if you need specific error messages, using maybe. that, in turn can be abstracted out into a lookup with error message. once the checking is done in the wrapper, there is no need to repeat it in the generator. also, the interface to the generator is too wide for the small amount of extra functionality it provides, so it is probably best inlined, and there seems to be no need to commit to IO so early. i also tend to use [String], with a final unlines before output, but that is a matter of opinion, i guess. financial_output :: String -> String -> String -> String -> String financial_output company displaymode startDate endDate = financial_script where financial_script = gnuplot_timeseries_settings ++ "\n" ++ "plot [\"" ++ startDate ++ "\":\"" ++ endDate ++ "\"]" ++ " '" ++ companyFile ++ "'" ++ modeString ++ " title \"" ++ company ++ " " ++ titleEnd ++ "\"" companyFile = lookupWith (error $ "no company file for " ++ company) company company_to_companyfile modeString = lookupWith (error $ "no mode string for " ++ displaymode) displaymode displaymode_to_modestring titleEnd = lookupWith (error $ "no title end for " ++ displaymode) displaymode displaymode_to_titleend lookupWith error key assocs = maybe error id $ lookup key assocs hth, claus