goldfirere / units

The home of the units Haskell package
94 stars 19 forks source link

extend makeQuasiQuoter Unit Types #27

Closed nushio3 closed 10 years ago

nushio3 commented 10 years ago

Now that @goldfirere has implemented long-wanted qq-maker for creating unit expressions, I also want TH function for creating unit types.

However, my attempt to insert even basic Q Type s have been failed, although the type signature appears to be nothing wrong for me.

I must confess that I have little experience writing Template Haskells, and I need help.

Data/Metrology/Parser.hs:77:9:
    No instance for (Language.Haskell.TH.Syntax.Lift QuasiQuoter) ...

for https://github.com/goldfirere/units/commit/947e5d051a3f7bf5c68171a3009e96fb25ffede9

    No instance for (Language.Haskell.TH.Syntax.Lift (String -> Q Type))

for https://github.com/goldfirere/units/commit/2fc598af44f13baabc06f27e072e6834e5a9bd20

nushio3 commented 10 years ago

Let me state the issue more concretely (sorry for the confusion.) For example, look at the code snippet:

solarLuminousity :: MkQu_D (D.Energy :/ D.Time)
solarLuminousity = redim $ 3.839e30 % [si| J / s |]

I'd like to also generate the unit type (the first line) from template Haskell, in addition to the unit value (the second line). Moreover, like in Data.Metrology.SI.Mono / Data.Metrology.SI.Poly , it is convenient to have several versions of unit type TH.

c.f. the entire code is found here https://github.com/nushio3/practice/blob/24a8515cd7652181f0fa31c87645a25b019e5ad0/solar-physics/Astrophysics/Sun.hs#L14 https://github.com/nushio3/practice/blob/24a8515cd7652181f0fa31c87645a25b019e5ad0/solar-physics/Astrophysics/Sun.hs#L15

goldfirere commented 10 years ago

The problem is that any local variable in a TH quote must be "lifted" from TH-quote-compile-time to client-code-compile-time. This is because the client code has no other way of accessing the local variable. One solution is just to make the local a global, which is precisely why emptyQQ is a global, not a local variable.

In any case, I'll fix this bug -- won't be hard.

nushio3 commented 10 years ago

Thank you for your Response @goldfirere , The nested generation of TH is someting I haven't experienced, and I still not understand the role of the big [| |] that encloses emptyQQ { ... } . I do have experience on some TH (for generating LaTeX, and so on) therefore once I know how to update quoteType, I think I can gradually implement the type generator by mimicing quoteExp .

However, I believe you are much faster in writing this. If you do so, I'm very happy because I can concentrate on the application part.

goldfirere commented 10 years ago

Well, it wasn't quite so easy, but it's done now. The problem was that I used Exp pervasively in the parser, and I had to generalize over Exp and Type using a GADT. A better way is probably to use some internal representation within the parser and then convert this representation to either Exp or Type at the very end. Not worth revisiting now, though.

Nested generation of TH was something I had never experienced either, but it worked out OK.