首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell“导入限定”和“不在范围内:数据构造函数”

Haskell“导入限定”和“不在范围内:数据构造函数”
EN

Stack Overflow用户
提问于 2015-12-31 14:43:52
回答 2查看 2.8K关注 0票数 3

我有这样的进口:

代码语言:javascript
复制
import qualified Bioinformatics.DNA as DNA

另一个文件如下所示:

代码语言:javascript
复制
data DNA = A | C | G | T
    deriving (Eq, Ord, Show)

在这个函数中,RNA模块中:

代码语言:javascript
复制
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

我收到错误:

代码语言:javascript
复制
/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’

你知道为什么吗?谢谢

EN

回答 2

Stack Overflow用户

发布于 2015-12-31 14:56:15

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

代码语言:javascript
复制
import qualified Bioinformatics.DNA as DNA (DNA(..), A, C, G, T)

码分解

编辑:让我们分析一下您的代码,因为它并不完全是惯用的。

代码语言:javascript
复制
import qualified Bioinformatics.DNA as DNA (DNA(..), A, C, G, T)

已经很奇怪了。通常,人们有条件地或有选择地导入东西,而不是两者兼而有之。试着:

代码语言:javascript
复制
import qualified Bioinfomatics.DNA as DNA

因此,让我们保持量化,并删除显式的符号列表。

现在,为了便于使用,您可以:

代码语言:javascript
复制
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的,请考虑如下所示:

代码语言:javascript
复制
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
票数 3
EN

Stack Overflow用户

发布于 2019-01-25 11:20:04

让我们想象一下,对于形状的操作,我们需要一个Geometry.Shape模块。首先,我们将创建一个名为Geometry的文件夹。注意首都G。在其中,我们将放置Shape.hs文件。以下是文件将包含的内容:

代码语言:javascript
复制
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目录相同的级别上:

代码语言:javascript
复制
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)

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

代码语言:javascript
复制
.
├── Geometry
│   └── Shape.hs
└── Geometry.hs

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

代码语言:javascript
复制
$ ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
Prelude>

然后,让我们加载Geometry模块:

代码语言:javascript
复制
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文件来修复它:

代码语言:javascript
复制
module Geometry.Shape
  ( Shape(Circle,Rectangle)
  , Point(..)
  ) where

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

代码语言:javascript
复制
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.

并测试它:

代码语言:javascript
复制
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模块中得到编译错误的原因。

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34547937

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档