“类型同义词”不在范围内“当使用模板Haskell [英] Type synonyms "not in scope" when using Template Haskell
问题描述
这是我的Main.hs文件:
{ - #LANGUAGE TemplateHaskell# - }
模块Main其中
import控制.Lens
import Data.Aeson
import Data.Aeson.TH
type Foo = Bar
data Baz = Baz
$( deriveJSON defaultOptions''Baz)
- $(makeLenses''Baz)
data Bar = Bar
main :: IO()
main = printhello
尝试编译它时,出现以下错误:
test-0.1.0.0:configure
配置test-0.1.0.0 ...
test-0.1.0.0:构建
构建test-0.1.0.0 ...
为test-0.1.0.0预处理可执行文件'test'...
[编译Main(Main.hs,.stack)
Main.hs:9:12:
不在范围之内-work / dist / x86_64-linux / Cabal-1.22.2.0 / build / test / test-tmp / Main.o :类型构造函数或c lass'Bar'
- 使用以下命令构建软件包测试-0.1.0.0:
/ usr / bin / runhaskell -package = Cabal-1.22.2.0 -clear-package-db -global -package-db -package-db = / home / illabout / .stack / snapshots / x86_64-linux / nightly-2015-06-17 / 7.10.1 / pkgdb / /tmp/stack1699/Setup.hs --builddir =。 stack-work / dist / x86_64-linux / Cabal-1.22.2.0 / build
使用代码退出进程:ExitFailure 1
无论我使用 deriveJSON
还是 makeLenses
,都会发生此错误。
如果我将类型的Foo = Bar
向下移动过去,使用Template Haskell,文件编译就可以正常工作了。
导致这个错误的原因是什么?
这是一个 .cabal
文件, stack.yaml
文件来编译它:
test.cabal:
name:test
version:0.1.0.0
build-type:Simple
cabal-version:> = 1.10
可执行测试
main-is:Main.hs
build-depends:base> = 4.8&& < 4.9
,aeson> = 0.8&& < 0.9
,镜头> = 4&& < 5
default-language:Haskell2010
stack.yaml:
标记:{}
包裹:
- '。'
特别提示:[]
解析器:nightly-2015-06-17
这是使用ghc-7.10.1。
使用Template Haskell时,这是由声明组造成的。以下是 GHC手册的摘录:
顶级声明拼接将源文件拆分为定义
组。一个声明组是由一个
顶层声明拼接创建的一组声明,以及后面的那些声明,包括下一个顶层声明拼接,而不是
。模块中的第一个声明
组包含所有顶级定义,但不包括
,包括第一个顶级声明拼接。
每个声明组只是在组内相互递归。
声明组可以引用前几个组中的定义,
,但不会晚于一个。
在我的原始代码中,创建了两个声明组:
- 这是第一个宣言小组的开始。
type Foo = Bar
data Baz = Baz
$(deriveJSON defaultOptions''Baz)
- 这是开始第二个宣言小组。
data Bar = Bar
第一个声明组无法看到 Bar
,这会导致此错误。
I am getting a strange error about a data type being "not in scope" when using Template Haskell.
Here is my Main.hs file:
{-# LANGUAGE TemplateHaskell #-}
module Main where
import Control.Lens
import Data.Aeson
import Data.Aeson.TH
type Foo = Bar
data Baz = Baz
$(deriveJSON defaultOptions ''Baz)
-- $(makeLenses ''Baz)
data Bar = Bar
main :: IO ()
main = print "hello"
When trying to compile it, I get the following error:
test-0.1.0.0: configure
Configuring test-0.1.0.0...
test-0.1.0.0: build
Building test-0.1.0.0...
Preprocessing executable 'test' for test-0.1.0.0...
[1 of 1] Compiling Main ( Main.hs, .stack-work/dist/x86_64-linux/Cabal-1.22.2.0/build/test/test-tmp/Main.o )
Main.hs:9:12:
Not in scope: type constructor or class ‘Bar’
-- While building package test-0.1.0.0 using:
/usr/bin/runhaskell -package=Cabal-1.22.2.0 -clear-package-db -global-package-db -package-db=/home/illabout/.stack/snapshots/x86_64-linux/nightly-2015-06-17/7.10.1/pkgdb/ /tmp/stack1699/Setup.hs --builddir=.stack-work/dist/x86_64-linux/Cabal-1.22.2.0/ build
Process exited with code: ExitFailure 1
This error occurs whether I use deriveJSON
or makeLenses
.
If I move the type Foo = Bar
line down past the use of Template Haskell, the file compiles fine.
What's causing this error?
Here is a .cabal
file and stack.yaml
file to compile this:
test.cabal:
name: test
version: 0.1.0.0
build-type: Simple
cabal-version: >=1.10
executable test
main-is: Main.hs
build-depends: base >=4.8 && <4.9
, aeson >= 0.8 && < 0.9
, lens >= 4 && < 5
default-language: Haskell2010
stack.yaml:
flags: {}
packages:
- '.'
extra-deps: []
resolver: nightly-2015-06-17
This is using ghc-7.10.1.
This is caused by declaration groups when using Template Haskell. Here is an excerpt from the GHC Manual:
Top-level declaration splices break up a source file into delcaration groups. A declaration group is the group of declarations created by a top-level declaration splice, plus those following it, down to but not including the next top-level declaration splice. The first declaration group in a module includes all top-level definitions down to but not including the first top-level declaration splice.
Each declaration group is mutually recursive only within the group. Declaration groups can refer to definitions within previous groups, but not later ones.
In my original code, two declaration groups are created:
-- This is the start of the first declaration group.
type Foo = Bar
data Baz = Baz
$(deriveJSON defaultOptions ''Baz)
-- This is the start of the second declaration group.
data Bar = Bar
The first declaration group cannot see Bar
, which is causing this error.
这篇关于“类型同义词”不在范围内“当使用模板Haskell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!