使用Template Haskell时,键入同义词"not in scope"

ill*_*out 5 haskell ghc template-haskell type-synonyms

使用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"
Run Code Online (Sandbox Code Playgroud)

在尝试编译它时,我收到以下错误:

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
Run Code Online (Sandbox Code Playgroud)

无论我使用deriveJSON还是,都会发生此错误makeLenses.

如果我将该type Foo = Bar行向下移动超过使用Template 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
Run Code Online (Sandbox Code Playgroud)

stack.yaml:

flags: {}
packages:
- '.'
extra-deps: []
resolver: nightly-2015-06-17
Run Code Online (Sandbox Code Playgroud)

这是使用ghc-7.10.1.

ill*_*out 8

这是由使用Template Haskell时的声明组引起的.以下是GHC手册的摘录:

顶级声明拼接将源文件分解为退化组.声明组是由顶级声明拼接创建的声明组,以及它之后的声明组,直到但不包括下一个顶级声明拼接.模块中的第一个声明组包括所有顶级定义,但不包括第一个顶级声明拼接.

每个声明组仅在组内相互递归. 声明组可以引用先前组中的定义, 但不能在以后的组中引用.

在我的原始代码中,创建了两个声明组:

-- 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
Run Code Online (Sandbox Code Playgroud)

第一个声明组无法看到Bar,这是导致此错误的原因.