Как получить объявление функции с помощью `reify`?

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

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

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


person Petr    schedule 21.11.2013    source источник
comment
Это отличный вопрос. Я пробовал помечать определение INLINE или INLINEABLE, и это не имело никакого значения. Я подозреваю, что это вообще не реализовано, но я не знаю.   -  person Carl    schedule 21.11.2013
comment
возможный дубликат Как использовать Template Haskell для получения тело функции?   -  person jberryman    schedule 21.11.2013


Ответы (1)


Из документов по шаблону haskell на VarI Инфо конструктор:

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

Глядя на зеркало исходного кода ghc на github, строка VarI появляется только дважды, и оба в 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.

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

person David Miani    schedule 21.11.2013