2017-05-22 5 views
1

단일 TH 기능을 가지고 유형을 정의하고 유형을 사용하는 방법이 있습니까? 아래 관련 코드. PersonPoly2makeRecordSplice에 의해 정의 된 후 TH 함수이기도 한 makeAdaptorAndInstance (Opalaye에서)으로 전달됩니다.TemplateHaskell 함수에서 유형을 정의하고 같은 함수에서 사용하는 방법은 무엇입니까?

{-# LANGUAGE FlexibleContexts  #-} 
{-# LANGUAGE FlexibleInstances  #-} 
{-# LANGUAGE FunctionalDependencies #-} 
{-# LANGUAGE MultiParamTypeClasses #-} 
{-# LANGUAGE OverloadedStrings  #-} 
{-# LANGUAGE TemplateHaskell  #-} 

module Lib where 

import   Data.Profunctor.Product.TH    (makeAdaptorAndInstance) 
import Language.Haskell.TH 

makeRecordSplice :: Q [Dec] 
makeRecordSplice = [d| 
    data PersonPoly2 a b = Person2 
    { id :: a 
    , name :: b 
    } 
    |] 

makeRecordAndAdapter :: Q [Dec] 
makeRecordAndAdapter = do 
    record <- makeRecordSplice 
    adapter <- makeAdaptorAndInstance "pPerson2" (mkName "PersonPoly2") 
    return $ record ++ adapter 


------------- 

/home/Projects/scratch/app/Main.hs:26:1: error: 
    ‘PersonPoly2’ is not in scope at a reify 
Failed, modules loaded: Lib. 

답변

1

당신이 겪고있는 문제는 makeRecordSplice 필요가 인스턴스화되는 것과 다른 모듈에 있어야한다는 것입니다.이 템플릿 하스켈 제한은 컴파일시에 비 원형 종속성을 보장합니다. 그것은 성가신 제한이지만 지나치기는 어렵지 않습니다. 여기 당신이 그것을 할 수있는 한 방법입니다 : 당신은 분명히 makeAdaptorAndInstance "pPerson2" (mkName "PersonPoly2")에 대해 별명을 작성하고 Lib에 숨길 수

{-# LANGUAGE FlexibleContexts  #-} 
{-# LANGUAGE FlexibleInstances  #-} 
{-# LANGUAGE FunctionalDependencies #-} 
{-# LANGUAGE MultiParamTypeClasses #-} 
{-# LANGUAGE OverloadedStrings  #-} 
{-# LANGUAGE TemplateHaskell  #-} 

module Main where 

import   Data.Profunctor.Product.TH (makeAdaptorAndInstance) 
import   Language.Haskell.TH 
import   Lib      (makeRecordSplice) 


$(makeRecordSplice) 
$(makeAdaptorAndInstance "pPerson2" (mkName "PersonPoly2")) 

main :: IO() 
main = undefined 
{-# LANGUAGE FlexibleContexts  #-} 
{-# LANGUAGE FlexibleInstances  #-} 
{-# LANGUAGE FunctionalDependencies #-} 
{-# LANGUAGE MultiParamTypeClasses #-} 
{-# LANGUAGE OverloadedStrings  #-} 
{-# LANGUAGE TemplateHaskell  #-} 

module Lib where 

import   Data.Profunctor.Product.TH (makeAdaptorAndInstance) 
import   Language.Haskell.TH 

makeRecordSplice :: Q [Dec] 
makeRecordSplice = [d| 
    data PersonPoly2 a b = Person2 
    { id :: a 
    , name :: b 
    } 
    |] 

, 당신은 다른 일에 따라 스플 라이스을 가질 수 없습니다 같은 모듈.

희망이 도움이됩니다. :-)

+0

O.P.는 모나드 내부에서 TH 함수를 호출하려고 시도하고있었습니다. 그건 잘못되었습니다 : TH는 프로그램의 최상위 레벨에 나타나야하는 선언을 작성하고 있습니다. 그래서 당신의 대답은 정확하게 스플 라이스를 최상위에 두는 것입니다. – AntC