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

Claus and Evan ++; that was very helpful. FWIW, my gut feeling is that Claus's first version was easier to understand than the revision with printf, which seems to me to involve a lot more monadic wizardry (Functor, MonadError, fmap, mapm). The first version, which just used maybe, was clear to me within seconds. But again, I learned a lot. Thanks.

{---- Hello, Here is a variation on Claus' code which returns an Either type rather than fails with error. This could be further generalized to use any instance of MonadError, rather than Either. -Jeff ----} import Control.Monad.Error financial_output :: String -> String -> String -> String -> Either 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 ("no company file for " ++ company) company company_to_companyfile modeString = lookupWith ("no mode string for " ++ displaymode) displaymode displaymode_to_modestring titleEnd = lookupWith ("no title end for " ++ displaymode) displaymode displaymode_to_titleend lookupWith :: (Eq a) => String -> a -> [(a,String)] -> Either String String lookupWith error key assocs = maybe (Left error) Right $ lookup key assocs class MyString a where mystr :: a -> Either String String instance MyString (Either String String) where mystr = id instance MyString String where mystr = Right x <++> y = do xv <- mystr x yv <- mystr y return $ xv ++ yv

With regards to the variable interpolation in strings problem, it's
probably worth watching
http://groups.google.de/group/fa.haskell/browse_thread/thread/34741c2a5c311a17/286dbd62748ef1c1?lnk=st&q=%22haskell+cafe%22+%22template+system%22&rnum=1&hl=en#286dbd62748ef1c1
which mentions some perl/python-like template systems in the works for haskell.
2007/4/16, jeff p
{----
Hello,
Here is a variation on Claus' code which returns an Either type rather than fails with error. This could be further generalized to use any instance of MonadError, rather than Either.
-Jeff
----}
import Control.Monad.Error
financial_output :: String -> String -> String -> String -> Either 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 ("no company file for " ++ company) company company_to_companyfile
modeString = lookupWith ("no mode string for " ++ displaymode) displaymode displaymode_to_modestring
titleEnd = lookupWith ("no title end for " ++ displaymode) displaymode displaymode_to_titleend
lookupWith :: (Eq a) => String -> a -> [(a,String)] -> Either String String lookupWith error key assocs = maybe (Left error) Right $ lookup key assocs
class MyString a where mystr :: a -> Either String String instance MyString (Either String String) where mystr = id instance MyString String where mystr = Right
x <++> y = do xv <- mystr x yv <- mystr y return $ xv ++ yv

With regards to the variable interpolation in strings problem, ..
as i mentioned, it is not difficult to hack something up, and in many cases, efficiency doesn't matter much for this part of the problem (though a standard, efficient, well-designed library would be welcome). but if we compare the attached example with here docs in perl or shell or .., we find that we can get rid of all that escaping and concatenation in strings, but: - the file name should be implicit (the current source) - the dictionary should be implicit (the current variable environment) the former might be easy to add to the language, and the latter would be a minor subset of template haskell functionality. but they need to be standardized and widely available to be of much use. claus ps here's the output: $ runhaskell Here.hs this is a poor man's here-document with quotes ", and escapes \, and line-breaks, and layout without escaping \" \\ \n, without concatenation. oh, and with some variables, $(too). <html> <head><title>very important page</title></head> <body> <verb> this is a poor man's here-document with quotes ", and escapes \, and line-breaks, and layout without escaping \" \\ \n, without concatenation. oh, and with some variables, $(too). </verb> </body> </html>

I put this on the haskell wiki at
http://haskell.org/haskellwiki/Poor_Man%27s_Heredoc_in_Haskell
So far I have only linked this from
http://haskell.org/haskellwiki/Simple_unix_tools
I feel like the wiki deserves a section on "Haskell Template
Solutions" distinct from this. However, there is a bit of a namespace
conflict, as "template haskell" is a ghc extension, and so if you
google on it you will get all stuff first.
I wonder if anyone has an opinion on a good title for a wiki page about this.
Haskell String Interpolation?
Haskell String Templates?
But these sound clunky to me.
2007/4/16, Claus Reinke
With regards to the variable interpolation in strings problem, ..
as i mentioned, it is not difficult to hack something up, and in many cases, efficiency doesn't matter much for this part of the problem (though a standard, efficient, well-designed library would be welcome). but if we compare the attached example with here docs in perl or shell or .., we find that we can get rid of all that escaping and concatenation in strings, but:
- the file name should be implicit (the current source) - the dictionary should be implicit (the current variable environment)
the former might be easy to add to the language, and the latter would be a minor subset of template haskell functionality. but they need to be standardized and widely available to be of much use.
claus
ps here's the output:
$ runhaskell Here.hs
this is a poor man's here-document
with quotes ", and escapes \, and line-breaks, and layout without escaping \" \\ \n, without concatenation.
oh, and with some variables, $(too).
<html> <head><title>very important page</title></head> <body> <verb>
this is a poor man's here-document
with quotes ", and escapes \, and line-breaks, and layout without escaping \" \\ \n, without concatenation.
oh, and with some variables, $(too).
</verb> </body> </html>

Looks like this needs to be run with
#!/usr/lib/ghc-6.6/bin/runghc
{-# OPTIONS_GHC -fglasgow-exts #-}
to get
instance MyString (Either String String)
where mystr = id
instance MyString String
where mystr = Right
to work.
I'm curious if there is a community feeling on whether glasgow-exts is
sort of a de-facto standard now? Or is it common to try to get things
to work without this, for maximum portability?
Is there an easy way to get the above to work without the compiler flag?
2007/4/16, jeff p
{----
Hello,
Here is a variation on Claus' code which returns an Either type rather than fails with error. This could be further generalized to use any instance of MonadError, rather than Either.
-Jeff
----}
import Control.Monad.Error
financial_output :: String -> String -> String -> String -> Either 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 ("no company file for " ++ company) company company_to_companyfile
modeString = lookupWith ("no mode string for " ++ displaymode) displaymode displaymode_to_modestring
titleEnd = lookupWith ("no title end for " ++ displaymode) displaymode displaymode_to_titleend
lookupWith :: (Eq a) => String -> a -> [(a,String)] -> Either String String lookupWith error key assocs = maybe (Left error) Right $ lookup key assocs
class MyString a where mystr :: a -> Either String String instance MyString (Either String String) where mystr = id instance MyString String where mystr = Right
x <++> y = do xv <- mystr x yv <- mystr y return $ xv ++ yv

Without the flag:
thartman@linodehaskell:~/websites/gnuplotwebinterface/cgi-bin/gnuplot-scripts>./financial2.hs
cisco candles 31-May-04 11-Jun-04
./financial2.hs:58:0:
Illegal instance declaration for `MyString (Either String String)'
(The instance type must be of form (T a b c)
where T is not a synonym, and a,b,c are distinct type variables)
In the instance declaration for `MyString (Either String String)'
./financial2.hs:61:0:
Illegal instance declaration for `MyString String'
(The instance type must be of form (T a b c)
where T is not a synonym, and a,b,c are distinct type variables)
In the instance declaration for `MyString String'
thartman@linodehaskell:~/websites/gnuplotwebinterface/cgi-bin/gnuplot-scripts>cat
--number financial2.hs | tail
58 instance MyString (Either String String)
59 where mystr = id
60
61 instance MyString String
62 where mystr = Right
63
64 x <++> y = do xv <- mystr x
65 yv <- mystr y
66 return $ xv ++ yv
67
2007/4/18, Thomas Hartman
Looks like this needs to be run with
#!/usr/lib/ghc-6.6/bin/runghc {-# OPTIONS_GHC -fglasgow-exts #-}
to get
instance MyString (Either String String) where mystr = id
instance MyString String where mystr = Right
to work.
I'm curious if there is a community feeling on whether glasgow-exts is sort of a de-facto standard now? Or is it common to try to get things to work without this, for maximum portability?
Is there an easy way to get the above to work without the compiler flag?
2007/4/16, jeff p
: {----
Hello,
Here is a variation on Claus' code which returns an Either type rather than fails with error. This could be further generalized to use any instance of MonadError, rather than Either.
-Jeff
----}
import Control.Monad.Error
financial_output :: String -> String -> String -> String -> Either 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 ("no company file for " ++ company) company company_to_companyfile
modeString = lookupWith ("no mode string for " ++ displaymode) displaymode displaymode_to_modestring
titleEnd = lookupWith ("no title end for " ++ displaymode) displaymode displaymode_to_titleend
lookupWith :: (Eq a) => String -> a -> [(a,String)] -> Either String String lookupWith error key assocs = maybe (Left error) Right $ lookup key assocs
class MyString a where mystr :: a -> Either String String instance MyString (Either String String) where mystr = id instance MyString String where mystr = Right
x <++> y = do xv <- mystr x yv <- mystr y return $ xv ++ yv
participants (3)
-
Claus Reinke
-
jeff p
-
Thomas Hartman