我收到一个奇怪的错误,关于数据类型是"不在范围"使用Template Haskell时。
这是我的Main.hs文件:
{-# 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"
尝试编译时,我收到以下错误:
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
无论是使用deriveJSON
还是makeLenses
,都会出现此错误。
如果我将type Foo = Bar
行移到模板Haskell的使用之后,则文件编译正常。
造成此错误的原因是什么?
这是一个.cabal
文件和stack.yaml
文件来编译它:
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
这是使用ghc-7.10.1。
答案 0 :(得分:8)
这是由使用Template Haskell时的声明组引起的。以下是GHC Manual:
的摘录顶级声明拼接将源文件分解为逐行扫描 组。声明组是由a创建的声明组 顶级声明拼接,以及跟随它的那些拼接,但不是 包括下一个顶级声明拼接。第一个宣言 模块中的组包括所有顶级定义,但不包括 包括第一个顶级声明拼接。
每个声明组仅在组内相互递归。 声明组可以参考以前组中的定义, 但不是后来 s。
在我的原始代码中,创建了两个声明组:
-- 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
第一个声明组看不到导致此错误的Bar
。
答案 1 :(得分:4)
在模板Haskell之前移动data Bar = ...
声明,它将起作用:
type Foo = Bar
data Baz = Baz
data Bar = Bar
$(deriveJSON defaultOptions ''Baz)
$(makeLenses ''Baz)