开发者

Function "who am I" accessible from function and usable as key?

I would like to use a collection of function names as Data.Map keys, and have the key for each function automatically available from within that function. I am willing to consider "unsafe" operations, if necessary.

My specific programming problem is this: I've been developing a simple parser library for textual transformations, which I use in particular for preprocessing and grooming all of my Haskell code. It has the virtue of being small enough to easily hack, with most constructs not requiring explicit monadic do notation. Instead, grammars read almost verbatim like their formal descriptions.

In particular, I've entered the lexical structure of Haskell2010 once, with the idea of modifying this grammar in various ways for different applications. I do this now by creating labels corresponding to each grammar construct, and passing these labels to each construct. I also use these labels as keys for Data.Map. This allows me to provide post-processing for various labels, in different applications of my grammar.

The details of my code don't really matter; the gist of my question should be clear, for any similar application to what I describe here. Here is a (draft) fragment of the grammar for Haskell2010:

program = Program §
  many $ lexeme ∨ whitespace

lexeme = Lexeme §
  reservedop ∨ reservedid ∨ qvarid ∨ qconid ∨ qvarsym ∨ qconsym ∨ literal
  ∨ special

literal = Literal §
  integer ∨ float ∨ hchar ∨ hstring

special = Special §
  oneOf "(),;[]`{}"

whitespace = Whitespace §
  many1 whitestuff

whitestuff = Whitestuff §
  whitechar ∨ comment ∨ ncomment

whitechar  = Whitechar §
  newline ∨ vertab ∨ space ∨ tab ∨ uniWhite

newline = Newline §
  hreturn ◊ linefeed ∨ hreturn ∨ linefeed ∨ formfeed

Having work开发者_StackOverflowed hard to make grammars concise, I find this duplicate boilerplate very ugly. Why can't I just use the function names themselves, and have each function access its own name as needed? (The operators are monadic, so there's a chance to do anything we like, behind the scenes.)

I understand and enjoy the meta-game of arguments that explain why construct "X" in Lisp (Scheme) or any object-oriented language isn't necessary in Haskell, because one just does "Y". In comparison to Haskell, Lisp is both less disciplined and seemingly more flexible. Lisp reminds me of the early "Out of the Inkwell" cartoons at the birth of animation, where a hand could come out from behind the screen and redraw something to bend rules as needed.

From instead an object-oriented point of view (which like all religions I try to avoid) this is a rather routine use of "self". However, I don't want to create an entire object-oriented framework here, I just want a tiny bit of direct access to the symbol table (or the equivalent, whatever gets the job done), as these other languages offer one way or another.

So I'm embarrassed that I can't play this meta-game here. It appears to me that Haskell, tidily and with great discipline, seals off access to symbol tables and runtime environments that would let me golf this code, get rid of this eyesore boilerplate. Or not? I ask here.


I think you can't do that in standard-compliant Haskell because that breaks referential transparency, but using GHC extension named Template Haskell, it can be done. Template Haskell allows you to run custom code in compile-time to generate boilerplate code or do something more interesting (you may want to transform the existing code to achieve your goal).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜