2017-05-22 56 views
1

有沒有什麼辦法讓單個TH功能,定義一個類型,並使用類型?下面的相關代碼。 PersonPoly2makeRecordSplice定義,然後傳遞給makeAdaptorAndInstance(來自Opalaye),這也是TH函數。如何在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需要是在不同的模塊比它在實例化的一個,這個模板-Haskell的限制確保了非圓形的依賴關係在編譯時。這是一個令人討厭的限制,但不是很難走開。這裏是你可以做的一種方式:

{-# 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 
    } 
    |] 

可以明顯的makeAdaptorAndInstance "pPerson2" (mkName "PersonPoly2")創建別名,並把它藏在Lib,你就不能有依賴於另外一個在剪接相同的模塊。

希望這會有所幫助! :-)

+0

O.P.試圖調用monad中的TH函數。這是錯誤的:TH正在創建必須出現在程序頂層的聲明。所以你的回答是正確地把接頭放在頂層。 – AntC

相關問題