【问题标题】:Haskell "import qualified" and "Not in scope: data constructor"Haskell“导入合格”和“不在范围内:数据构造函数”
【发布时间】:2015-12-31 14:43:52
【问题描述】:

我有这样的导入:

import qualified Bioinformatics.DNA as DNA

来自另一个看起来像这样的文件:

data DNA = A | C | G | T
    deriving (Eq, Ord, Show)

并且在这个函数中的模块RNA里:

module Bioinformatics.RNA
  ( RNA
  , fromDna
  ) where

import qualified Bioinformatics.DNA as DNA

data RNA = A | C | G | U
    deriving (Eq, Ord, Show)

fromDna :: DNA.DNA -> RNA
fromDna DNA.A = A
fromDna DNA.C = C
fromDna DNA.G = G
fromDna DNA.T = U

我收到错误:

/home/thibaud/code/bioinformatics/src/Bioinformatics/RNA.hs:46:9:
    Not in scope: data constructor ‘DNA.A’

/home/thibaud/code/bioinformatics/src/Bioinformatics/RNA.hs:47:9:
    Not in scope: data constructor ‘DNA.C’

/home/thibaud/code/bioinformatics/src/Bioinformatics/RNA.hs:48:9:
    Not in scope: data constructor ‘DNA.G’

/home/thibaud/code/bioinformatics/src/Bioinformatics/RNA.hs:49:9:
    Not in scope: data constructor ‘DNA.T’

你知道为什么吗? 谢谢

【问题讨论】:

  • 您可能不需要data A ; ...; data T 类型定义。只要您按照以下答案中的说明导出和导入它们,值构造函数就足够了。

标签: haskell


【解决方案1】:

使用(..) 导入数据类型的所有构造函数。

import qualified Bioinformatics.DNA as DNA (DNA(..), A, C, G, T)

代码分解

编辑:让我们稍微分解一下您的代码,因为它不是很地道。

import qualified Bioinformatics.DNA as DNA (DNA(..), A, C, G, T)

这已经很奇怪了。通常,人们进口的东西是合格的或选择性的,而不是两者兼而有之。试试吧:

import qualified Bioinfomatics.DNA as DNA

所以让我们保持量化并删除明确的符号列表。

现在使用,你有:

fromDna :: DNA.DNA -> RNA
fromDna DNA.A = A
fromDna DNA.C = C
fromDna DNA.G = G
fromDna DNA.T = U

声称此功能可将 DNA 转化为 RNA。请注意,您的 questino 从未提供过 RNA 类型或构造函数——它们在您的代码中的某个地方吗?您发布的代码中的剩余错误与 RNA 相关,请考虑以下内容:

import qualified Bioinformatics.RNA as RNA

fromDna :: DNA.DNA -> RNA.RNA
fromDna DNA.A = RNA.A
fromDna DNA.C = RNA.C
fromDna DNA.G = RNA.G
fromDna DNA.T = RNA.U

【讨论】:

  • 它不适用于 DNA(..),我得到了同样的错误......
  • 你确定吗?您现在应该得到不同的错误,例如"Not in scope 'A' Perhaps you ment one of these: 'DNA.A' ..."。完成后,您可能会收到预期类型与实际类型 DNA/RNA 的类型错误。
  • 我更新了我的第一篇文章,修改了导入和 RNA 类型的定义。
  • OP 已经在从Bioinformatics.DNA 导入所有内容,所以一定是该模块的导出列表有问题。
  • @ReidBarton 对! @Thibaud 我看到你的 RNA 导出列表是 RNA 而不是 RNA(..),你在 DNA 中做同样的事情吗?您需要导出构造函数。此外,这个问题是一个案例研究,说明为什么应该粘贴完整的示例而不是片段。
【解决方案2】:

假设我们需要一个Geometry.Shape 模块来对形状进行操作。首先,我们将创建一个名为Geometry 的文件夹。注意大写G。在其中,我们将放置Shape.hs 文件。以下是文件将包含的内容:

module Geometry.Shape
  ( Shape(Circle,Rectangle)
  , Point
  ) where

data Point = Point Float Float deriving (Show)
data Shape = Circle Point Float | Rectangle Point Point deriving (Show)

请注意,在定义点时,我们为数据类型和值构造函数使用了相同的名称。

假设我们需要Geometry 模块来进行各种几何计算。我们将创建Geometry.hs 文件并将其放在与Geometry 目录相同的级别:

module Geometry (area) where

import qualified Geometry.Shape as Shape

area :: Shape.Shape -> Float
area (Shape.Circle _ r) = pi * r ^ 2
area (Shape.Rectangle (Shape.Point x1 y1) (Shape.Point x2 y2)) =
    (abs $ x2 - x1) * (abs $ y2 - y1)

文件结构现在应该如下所示:

.
├── Geometry
│   └── Shape.hs
└── Geometry.hs

好吧,让我们检查一下我们的area 函数。首先我们需要在Geometry.hs文件所在的目录下打开GHCi。

$ ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
Prelude>

然后让我们加载Geometry模块:

Prelude> :l Geometry.hs
[1 of 2] Compiling Geometry.Shape   ( Geometry/Shape.hs, interpreted )
[2 of 2] Compiling Geometry         ( Geometry.hs, interpreted )

Geometry.hs:7:24: Not in scope: data constructor ‘Shape.Point’

Geometry.hs:7:44: Not in scope: data constructor ‘Shape.Point’
Failed, modules loaded: Geometry.Shape.

哎呀!出问题了。可是等等!再看错误信息:

不在范围内:数据构造函数“Shape.Point”

嗯,简单来说就是类型构造函数不在可达范围内。因此,让我们通过更改Shape.hs 文件来修复它,如下所示:

module Geometry.Shape
  ( Shape(Circle,Rectangle)
  , Point(..)
  ) where

请注意,我们将 Point 更改为 Point(..)。重新加载模块如下:

Prelude> :r
[1 of 2] Compiling Geometry.Shape   ( Geometry/Shape.hs, interpreted )
[2 of 2] Compiling Geometry         ( Geometry.hs, interpreted )
Ok, modules loaded: Geometry, Geometry.Shape.

并测试它:

Prelude> area (Shape.Circle (Shape.Point 0 0) 24)
1809.5574

是的,它有效!我想提请您注意我们使用(..) 来导入Point 数据类型的所有构造函数。这与写Point (Point) 相同。同样,我们可以使用Shape(..) 而不是Shape(Circle,Rectangle)。更多内容见:https://www.haskell.org/tutorial/modules.html

不导出数据类型的值构造函数会使它们更加抽象,从而我们隐藏了它们的实现。此外,任何使用我们模块的人都无法对值构造函数进行模式匹配。这就是为什么之前我们在 Geometry 模块中遇到编译错误的原因。

我希望这个例子能帮助你理解这些错误的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多