[Haskell-cafe] Language Workbenches - the Haskell solution?
cgibbard at gmail.com
Sun Sep 11 17:06:08 EDT 2005
On 08/09/05, Yoel Jacobsen <yoel at emet.co.il> wrote:
> It seems that Martin Fowler's article "Language Workbenches: The
> killer-App for Domain Specific Languages?" -
> http://www.martinfowler.com/articles/languageWorkbench.html - has
> generated some nice dynamic solution where a configuration file is
> written in the same language as the program. Notable examples are lisp -
> http://lispm.dyndns.org/news?ID=NEWS-2005-07-08-1 and python -
> I'm trying to create an _elegant_ solution in Haskell. But I'm stuck.
> Since the native record-like access in Haskell syntax is using labelled
> fields in datatype decleration but the later are strictly compile-time.
> Therefore, if I compile my program and add a field in the configuration
> file (written in Haskell, using, for instance hs-plugins), I'll need to
> recompile the data declaration as well.
> Further, what is the type of the parser? Consider the following
> source = "#123456789012345678901234567890123456789012345678901234567890\n\
> \SVCLFOWLER 10101MS0120050313.........................\n\
> \SVCLHOHPE 10201DX0320050315........................\n\
> \SVCLTWO x10301MRP220050329..............................\n\
> data Configuration = Config String [(String, Int, Int)]
> config = [
> Config "SVCL" [("CustomerName", 4, 18),
> ("CustomerID", 19, 23),
> ("CallTypeCode", 24, 27),
> ("DateOfCallString", 28, 35)],
> Config "USGE" [("CustomerID", 4, 8),
> ("CustomerName", 9, 22),
> ("Cycle", 30, 30),
> ("ReadDAte", 31, 36)]]
> -- parse takes the configuration, a line from the source string and
> generate a record
> parse :: Configuration -> String -> Record
> What is the type of Record?
> Anyway, any elegant solution or a hint towards one are most welcome.
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
You could have a large record configuration type capable of storing
all possible necessary information (say, using Maybe to indicate that
fields are optional), and use combinators to build more complex
configurations out of simpler ones. If there are a very large number
of potential fields and you only care about chopping the strings
apart, a (Map String String) might be useful. You may want something
more complicated though where the numbers and dates etc. are all
parsed. For that, you basically need to figure out how your data are
(There is also the possibility of including the type in the config
file, deriving Data, and using Data.Generics in the program to
manipulate the records, but if you can specify the possible fields
beforehand, it will probably be much easier to write your program.)
Further, it looks like your configurations are just the parameters
describing the format in which to parse strings. You might consider
just using Parsec and just building the parsers directly in the
configuration file, perhaps writing a few specific combinators to help
with this specific app.
More information about the Haskell-Cafe