[Haskell-cafe] Re: Translating perl -> haskell, string "fill ins" with an error on invalid inputseems awfullycomplex. Is there a way to simplify?

Claus Reinke claus.reinke at talk21.com
Sat Apr 14 08:41:40 EDT 2007

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 
      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. 

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"

More information about the Haskell-Cafe mailing list