[Haskell-cafe] Language Workbenches - the Haskell solution?

Cale Gibbard 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 -
> http://billionairebusinessman.blogspot.com/2005/09/drop-that-schema-and-put-your-hands-in.html
> 
> 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
> implementation:
> 
> source = "#123456789012345678901234567890123456789012345678901234567890\n\
>   \SVCLFOWLER         10101MS0120050313.........................\n\
>   \SVCLHOHPE          10201DX0320050315........................\n\
>   \SVCLTWO           x10301MRP220050329..............................\n\
>          \USGE10301TWO
> x50214..7050329..............................."
> 
> 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.
> 
> Thanks,
>    Yoel
> 
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
> 

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

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

 - Cale


More information about the Haskell-Cafe mailing list