我们如何在模板haskell中使用类型级别字符串?

时间:2016-11-06 08:09:30

标签: haskell template-haskell type-level-computation

我在ghci上使用symbolVal和模板haskell,如下所示。

>>> :set -XTemplateHaskell -XQuasiQuotes -XDataKinds
>>> import Language.Haskell.TH
>>> import Data.Proxy
>>> import GHC.TypeLits
>>> $([| symbolVal (Proxy :: Proxy "foo") |]) -- Code (1)
"foo"

>>> runQ [| symbolVal (Proxy :: Proxy "foo") |]
AppE (VarE GHC.TypeLits.symbolVal) (SigE (ConE Data.Proxy.Proxy) (AppT (ConT Data.Proxy.Proxy) (LitT (StrTyLit "foo"))))

>>> $(appE (varE 'symbolVal) (sigE (conE ''Proxy) (appT (conT ''Proxy) (litT (strTyLit "foo")))))

<interactive>:9:3: error:
    • Type constructor ‘Proxy’ used where a value identifier was expected
    • In the first argument of ‘symbolVal’, namely
        ‘Proxy :: Proxy "foo"’
      In the expression: (symbolVal (Proxy :: Proxy "foo"))
      In an equation for ‘it’: it = (symbolVal (Proxy :: Proxy "foo"))

为什么Code (1)运行良好时会出现此错误? 我们如何在模板haskell中使用类型级别字符串?

1 个答案:

答案 0 :(得分:0)

为了完整性和将来参考,我想我会添加正确答案以供参考。

λ> :set -XTemplateHaskell -XQuasiQuotes -XDataKinds
λ> import Language.Haskell.TH
λ> import Data.Proxy
λ> import GHC.TypeLits

λ> $([| symbolVal (Proxy :: Proxy "foo") |])
"foo"

λ> runQ [| symbolVal (Proxy :: 'Proxy "foo") |]
AppE (VarE GHC.TypeLits.symbolVal) (SigE (ConE Data.Proxy.Proxy) (AppT (PromotedT Data.Proxy.Proxy) (LitT (StrTyLit "foo"))))

λ> runQ [| symbolVal (Proxy :: Proxy "foo") |]
AppE (VarE GHC.TypeLits.symbolVal) (SigE (ConE Data.Proxy.Proxy) (AppT (ConT Data.Proxy.Proxy) (LitT (StrTyLit "foo"))))

λ> $(appE (varE 'symbolVal) (sigE (conE 'Proxy) (appT (conT ''Proxy) (litT (strTyLit "foo")))))
"foo"