
As others have pointed out, you can't go from operation to representation, but you can pair operations and expressions with their representations.
This idea is also implemented in my little 'repr' package:
And probably more completely/comfortably!-) The version I pointed to, which I have occasionally mentioned here over the years, was deliberately simplified and reduced. I think Lennart also had a fairly complete version. Wasn't there also a version in one of the IRC bots? This kind of trick also comes up in embedded DSLs, especially if used for embedded compilers / code generators (eg, I used to generate VRML and Javascript from a Haskell DSEL, and by changing the expression representation to Javascript, running the Haskell-embedded expression would generate Javascript). I first encountered this idea when learning about type classes: I was trying to convince myself that overloading does not break referential transparency, even though this example clearly shows that the same expression can have different meanings, depending only on type context. Claus