gpt4 book ai didi

haskell - 模板 Haskell : GHC stage restriction and how to overcome

转载 作者:行者123 更新时间:2023-12-04 11:54:21 35 4
gpt4 key购买 nike

我在模块中有以下代码:

{-# LANGUAGE TemplateHaskell #-}

module Alpha where

import Language.Haskell.TH
import Data.List

data Alpha = Alpha { name :: String, value :: Int } deriving (Show)
findName n = find ((== n) . name)

findx obj = sequence [valD pat bod []]
where
nam = name obj
pat = varP (mkName $ "find" ++ nam)
bod = normalB [| findName nam |]

然后我在主文件中有以下内容:
{-# LANGUAGE TemplateHaskell #-}

import Alpha

one = Alpha "One" 1
two = Alpha "Two" 2
three = Alpha "Three" 3
xs = [one, two , three]

findOne = findName "One"
findTwo = findName "Two"

$(findx three) -- This Fails
$(findx (Alpha "Four" 4)) -- This Works

main = putStrLn "Done"

我想要 $(findx three)创建 findThree = findName "Three"为了我。但相反,我收到了这个错误:
GHC stage restriction: `three'
is used in a top-level splice or annotation,
and must be imported, not defined locally
In the first argument of `findx', namely `three'
In the expression: findx three

我该如何克服呢?我宁愿不必定义 one , two等在一个单独的文件中。

第二个问题是为什么 $(findx (Alpha "Four" 4))工作没有问题?

最佳答案

我自己对 Template Haskell 不是很了解,但根据我有限的理解,问题是当 GHC 尝试编译 three$(findx three) 在某种意义上“仍在定义中”,而 $(findx (Alpha "Four" 4)) 的所有组件都已经完全定义。

根本问题是同一个模块 中的所有定义都会影响彼此 的含义。这是由于类型推断和相互递归。 x = [] 的定义可能意味着很多不同的东西,具体取决于上下文;它可以将 x 绑定(bind)到 Int 列表或 IO () 列表或其他任何内容。 GHC 可能必须处理整个模块才能准确确定它的含义(或者它实际上是一个错误)。

该分析必须考虑 Template Haskell 发出到正在编译的模块中的代码。这意味着必须在 GHC 弄清楚模块中定义的含义之前运行 Template Haskell 代码,因此从逻辑上讲,您不能使用它们中的任何一个。

当 GHC 编译该模块时,已经完全检查了从其他模块 OTOH 导入的内容。通过编译此模块,无需了解更多关于它们的信息。所以这些可以在编译这个模块中的代码之前访问和使用。

另一种思考方式:也许 three 实际上不应该是 Alpha 类型。也许这是一个错字,构造函数应该是 Alphz 。通常,GHC 会通过编译模块中使用 three 的所有其他代码来发现这些错误,以查看这是否会引入不一致。但是,如果该代码使用或被仅由 $(findx three) 发出的东西使用怎么办?在我们运行之前,我们甚至都不知道会是什么代码,但是直到我们运行它之后,我们才能解决 three 是否正确输入的问题。

在某些情况下,当然可以稍微取消这个限制(我不知道这是否容易或实用)。也许我们可以让 GHC 将某些东西视为“早期定义”,如果它是导入的,或者它只使用“早期定义”的其他东西(并且可能具有显式类型签名)。也许它可以尝试在不运行 TH 代码的情况下编译模块,并且如果它在遇到任何错误之前设法对 three 进行完全类型检查,它可以将其输入到 TH 代码中,然后重新编译所有内容。不利的一面(除了所涉及的工作)将使说明您可以传递给 Template Haskell 的确切限制是什么变得更加复杂。

关于haskell - 模板 Haskell : GHC stage restriction and how to overcome,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16348183/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com