我有这样的导入:
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’
你知道为什么吗? 感谢
答案 0 :(得分:3)
使用(..)
导入数据类型的所有构造函数。
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
答案 1 :(得分:0)
假设我们需要一个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
模块中遇到编译错误的原因。
我希望这个例子可以帮助您理解此类错误的原因。