“类型同义词”不在范围内“当使用模板Haskell [英] Type synonyms "not in scope" when using Template Haskell

查看:143
本文介绍了“类型同义词”不在范围内“当使用模板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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆