2013-11-21 10 views
10

La funzione reify mi consente di cercare informazioni su un determinato nome. Per una funzione il valore restituito è VarI:Come ottenere la dichiarazione di una funzione usando `reify`?

data Info = ... | VarI Name Type (Maybe Dec) Fixity | ... 

Qui posso esaminare il tipo di funzione, e mi piacerebbe anche esaminare la sua dichiarazione. Tuttavia, nel terzo argomento su VarI vedo sempre Nothing. C'è un modo per ottenere la dichiarazione della funzione?

+0

Questa è una domanda eccellente. Ho provato a marcare la definizione 'INLINE' o' INLINEABLE', e nessuno dei due ha fatto alcuna differenza. Sospetto che non sia affatto implementato, ma non lo so. – Carl

+0

possibile duplicato di [Come utilizzare Template Haskell per ottenere il corpo della funzione?] (Http://stackoverflow.com/questions/13983391/how-to-use-template-haskell-to-get-the-body-of -funzione) – jberryman

risposta

7

Dal template haskell docs on the VarI Info contructor:

A "valore" variabile (al contrario di una variabile di tipo, vedi TyVarI). Il campo Maybe Dec contiene Just la dichiarazione che definisce la variabile - incluso l'RHS della dichiarazione - oppure Nothing, nel caso in cui l'RHS non sia disponibile per il compilatore. Allo stato attuale, questo valore è sempreNothing: restituire l'RHS non è ancora stato implementato a causa della mancanza di interesse.

Guardando il ghc source mirror on github, il string VarI only appears twice, e sia nel compiler/typecheck/TcSplice.lhs attuazione della funzione reifyThing:

reifyThing :: TcTyThing -> TcM TH.Info 
-- The only reason this is monadic is for error reporting, 
-- which in turn is mainly for the case when TH can't express 
-- some random GHC extension 

reifyThing (AGlobal (AnId id)) 
    = do { ty <- reifyType (idType id) 
     ; fix <- reifyFixity (idName id) 
     ; let v = reifyName id 
     ; case idDetails id of 
      ClassOpId cls -> return (TH.ClassOpI v ty (reifyName cls) fix) 
      _    -> return (TH.VarI  v ty Nothing fix) 
    } 

reifyThing (AGlobal (ATyCon tc)) = reifyTyCon tc 
reifyThing (AGlobal (ADataCon dc)) 
    = do { let name = dataConName dc 
     ; ty <- reifyType (idType (dataConWrapId dc)) 
     ; fix <- reifyFixity name 
     ; return (TH.DataConI (reifyName name) ty 
           (reifyName (dataConOrigTyCon dc)) fix) 
     } 

reifyThing (ATcId {tct_id = id}) 
    = do { ty1 <- zonkTcType (idType id) -- Make use of all the info we have, even 
             -- though it may be incomplete 
     ; ty2 <- reifyType ty1 
     ; fix <- reifyFixity (idName id) 
     ; return (TH.VarI (reifyName id) ty2 Nothing fix) } 

reifyThing (ATyVar tv tv1) 
    = do { ty1 <- zonkTcTyVar tv1 
     ; ty2 <- reifyType ty1 
     ; return (TH.TyVarI (reifyName tv) ty2) } 

reifyThing thing = pprPanic "reifyThing" (pprTcTyThingCategory thing) 

Come i documenti modello Haskell Detto questo, il valore utilizzato per il campo è sempre Nothing.

Digging deaper, this code was added in 2003, in quello che sembra una riscrittura del sistema reify. Quindi sembra essere poco interesse nel farlo funzionare poiché è stato più di 10 anni che il campo ha sempre avuto il valore Nothing. Quindi suppongo che se vuoi la funzionalità dovrai implementarla tu stesso (o proporre un buon use case alla mailing list di sviluppo ghc che incoraggi qualcuno a farlo).

Problemi correlati