Haskell 一个准足球运动员';使用';在调用的同一文件中定义的变量?

Haskell 一个准足球运动员';使用';在调用的同一文件中定义的变量?,haskell,template-haskell,Haskell,Template Haskell,所以,我开始用准旋转和haskell模板做实验 我想修改现有(大型)准旋转代码,同时使用在“调用”位置定义的变量的实际值。用一个简单的例子来说明: main.hs Exp02.hs 虽然这会编译并打印出“cde”,但这不是我想要的。我的理解是,拼接后main中的结果代码是:putStrLn x。我想要的是生成putStrLn cde(我知道这不是有效的haskell代码,但它只是代表我的观点) 因此,换一种方式来说,我不想“在主文件中创建变量x的引用”,我想在xptoquasikoter代码中实

所以,我开始用准旋转和haskell模板做实验

我想修改现有(大型)准旋转代码,同时使用在“调用”位置定义的变量的实际值。用一个简单的例子来说明:

main.hs

Exp02.hs

虽然这会编译并打印出“cde”,但这不是我想要的。我的理解是,拼接后main中的结果代码是:
putStrLn x
。我想要的是生成
putStrLn cde
(我知道这不是有效的haskell代码,但它只是代表我的观点)

因此,换一种方式来说,我不想“在主文件中创建变量
x
的引用”,我想在
xpto
quasikoter代码中实际使用它的值

我猜这可能是不可能的,因为这意味着
main.hs
Exp02.hs
之间存在循环引用,因此面临第TH阶段限制。这是正确的,还是有办法在
xpto
代码中使用x值


谢谢

不,您正在尝试的操作目前不可能。从:

如果函数是从另一个模块导入的,而该模块不是包含当前正在编译的模块的相互递归模块组的一部分,则只能在编译时运行该函数。此外,相互递归组的所有模块必须可以通过从要运行拼接的模块的非源导入访问

例如,在编译模块A时,如果B不导入A(直接或间接),则只能运行从B导入的模板Haskell函数。原因应该很清楚:要运行B,我们必须编译并运行A,但我们目前正在检查A的类型


您正试图在编译时在定义了
x
的同一模块中运行函数(或更严格地说是值)
x
,该模块已明确声明不允许运行。

否,您目前无法尝试执行此操作。从:

如果函数是从另一个模块导入的,而该模块不是包含当前正在编译的模块的相互递归模块组的一部分,则只能在编译时运行该函数。此外,相互递归组的所有模块必须可以通过从要运行拼接的模块的非源导入访问

例如,在编译模块A时,如果B不导入A(直接或间接),则只能运行从B导入的模板Haskell函数。原因应该很清楚:要运行B,我们必须编译并运行A,但我们目前正在检查A的类型

您正试图在编译时在定义了
x
的同一模块中运行函数(或更严格地说是值)
x
,该模块明确规定不允许

{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}

import Language.Haskell.TH
import Exp02

x = "cde"

main = do
  putStrLn [str|$x|]
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}

module Exp02 where

import Language.Haskell.TH
import Language.Haskell.TH.Syntax
import Language.Haskell.TH.Quote

xpto :: String -> ExpQ
xpto [] = stringE []
xpto ('$':rest) = varE (mkName rest)
xpto str = stringE str

str = QuasiQuoter
  { quoteExp = xpto
  , quotePat = fail $ "patterns"
  , quoteType= fail $ "types"
  , quoteDec = fail $ "declarations"
  }