2015-11-06 4 views
1

Предположим, я определяю свой собственный тип аннотаций:Получение аннотаций из того же модуля

{-# LANGUAGE DeriveDataTypeable #-} 
module Def where 

import Data.Data 

data MyAnn = MyAnn Int deriving (Show, Typeable, Data) 

и некоторые функции шаблона Haskell для доступа к нему:

module TH where 

import Def 
import Language.Haskell.TH.Syntax 

myAnn :: Name -> Q Exp 
myAnn name = do 
    [MyAnn x] <- reifyAnnotations (AnnLookupName name) 
    lift x 

Теперь я хотел бы использовать его как это:

{-# LANGUAGE TemplateHaskell #-} 
module Client where 

import Def 
import TH 

x ::() 
x =() 
{-# ANN x (MyAnn 42) #-} 

y :: Int 
y = $(myAnn 'x) 

Но это не удается, потому что myAnn вызов в определении y получает пустой список от reifyAnnotations.

Это работает, если я разделить Client так:

module Client1 where 

import Def 

x ::() 
x =() 
{-# ANN x (MyAnn 42) #-} 

{-# LANGUAGE TemplateHaskell #-} 
module Client2 where 

import Client1 
import TH 

y :: Int 
y = $(myAnn 'x) 

Есть ли способ, чтобы получить что-то вроде монолитных Client модуля для работы?

+0

Вдохновленных [этот вопрос] (HTTPS: //stackoverflow.com/questions/33561183/c-style-enum-in-haskell), для которого у меня была идея для аккуратного решения на основе аннотаций. – Cactus

+0

Это скорее обходной путь, не так ли? Может, у кого-то есть реальное решение? –

ответ

0

Это, как представляется, ожидаемое поведение в соответствии с the docs:

Соответственно, среда типа рассматривается reify включает в себя все декларации верхнего уровня до конца, непосредственно предшествующей декларации группы, но не более.

Эффективный способ решения вашей проблемы является силы начала отдельной декларации группы путем включения пустого верхнего уровня декларации сращивания, т.е. просто

$(return []) 
+0

Отредактировано из полезного комментария @ DominiqueDevriese. – Cactus

Смежные вопросы