
by utilizing Text.Printf.printf, extracting some more common functionality for the lookups, and changing the error handling (check for errors before giving results, but use throwError instead of error, letting the caller decide whether errors are fatal or not), we arrive at something like: financial_output :: (Functor m, MonadError String m) => String -> String -> String -> String -> m String financial_output company displaymode startDate endDate = fmap financial_script $ mapM lookupWith lookups where financial_script [companyFile,modeString,titleEnd] = gnuplot_timeseries_settings ++ "\n" ++ printf "plot [\"%s\":\"%s\"] '%s'%s title \"%s %s\"" startDate endDate companyFile modeString company titleEnd lookups = [ ("no company file for ", company, company_to_companyfile) , ("no mode string for ", displaymode, displaymode_to_modestring) , ("no title end for ", displaymode, displaymode_to_titleend) ] lookupWith (msg,key,assocs) = maybe (throwError $ msg ++ key) return $ lookup key assocs which perhaps isn't all that bad? the main thing i miss in Haskell for this kind of code generators are here-documents. there are workarounds (Hugs has a form of here docs, string interpolation isn't difficult to hack up, unlines gets rid of ++ and "\n"), and for more complex code generators, use of Text.PrettyPrint may be more appropriate, but for everyday scripting with code generation, nothing is as simple, readable, or portable as good old here-documents. hth, claus ps. calling the modified function: Main> either error putStrLn $ financial_output "ibm" "point" "start" "end" Program error: no mode string for point Main> either error putStrLn $ financial_output "ibm" "points" "start" "end" set terminal png transparent nocrop enhanced size 600,400 set pm3d implicit at s set xdata time # The x axis data is time set timefmt "%d-%b-%y" # The dates in the file look like 10-Jun-04 set format x "%b %d" #On the x-axis, we want tics like Jun 10 plot ["start":"end"] 'data/ibm.dat'using 1:2 with linespoints title "ibm daily prices"