有没有办法让单个TH函数,定义类型,并使用类型?相关代码如下。 PersonPoly2
正在定义makeRecordSplice
,然后传递给makeAdaptorAndInstance
(来自Opalaye),这也是一个TH函数。
{-# 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.
答案 0 :(得分:1)
您遇到的问题是makeRecordSplice
需要与实例化的模块不同。此Template-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
中,您只是不能在同一模块中依赖另一个接头。
希望这有帮助! : - )