2013-11-21 2 views
10

Функция reify позволяет мне искать информацию об имени. Для функции возвращаемого значение VarI:Как получить объявление функции с помощью `reify`?

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

Здесь я могу исследовать тип функции, и я хотел бы также рассмотреть его заявление. Однако в третьем аргументе VarI я всегда вижу Nothing. Есть ли способ получить объявление функции?

+0

Это отличный вопрос. Я пробовал маркировать определение 'INLINE' или' INLINEABLE', и не имеет никакого значения. Я подозреваю, что это совсем не реализовано, но я не знаю. – Carl

+0

Возможный дубликат [Как использовать шаблон Haskell для получения функции?] (Http://stackoverflow.com/questions/13983391/how-to-use-template-haskell-to-get-the-body-of -функции) – jberryman

ответ

7

От template haskell docs on the VarI Info contructor:

"значение" переменной (в отличие от переменной типа, см TyVarI). Поле Maybe Dec содержит Just декларацию, в которой определена переменная - включая RHS декларации - или Nothing, в случае, когда RHS недоступен для компилятора. В настоящее время это значение равно всегдаNothing: возвращение RHS еще не реализовано из-за отсутствия интереса.

Глядя на ghc source mirror on github, то string VarI only appears twice, и как в compiler/typecheck/TcSplice.lhs реализующего функцию 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) 

Как шаблон Haskell документы, сказал, значение, используемое для этого поля всегда Nothing.

Digging deaper, this code was added in 2003, что выглядит как переписывание системы reify. Поэтому, похоже, он мало заинтересован в том, чтобы заставить его работать, поскольку прошло более 10 лет, когда поле всегда имело значение Nothing. Поэтому я предполагаю, что вам нужна эта функция, которую вам придется реализовать самостоятельно (или предложить хороший вариант использования для списка рассылки ghc development, который побудил бы кого-то еще сделать это).