Zna*_*atz 12 constructor haskell system
我探索了System.Random.StdGen并在源代码中看到了这段代码.
data StdGen = StdGen Int32 Int32
Run Code Online (Sandbox Code Playgroud)
模块似乎也出口了StdGen.
module System.Random (
RandomGen(next, split, genRange)
, StdGen
...
Run Code Online (Sandbox Code Playgroud)
但是,为什么我不能在我的代码中这样做,比如说,
Prelude System.Random> StdGen 1 2
Not in scope: data constructor `System.Random.StdGen'**
Run Code Online (Sandbox Code Playgroud)
另一方面,我可以做到这一点,
module F (Foo) where
import GHC.Int
data Foo = Foo GHC.Int.Int32 GHC.Int.Int32 deriving (Show)
Run Code Online (Sandbox Code Playgroud)
和
Prelude> Foo 1 2
Foo 1 2
Run Code Online (Sandbox Code Playgroud)
请有人请告诉我这个数据构造函数实际上是如何隐藏的?
kos*_*kus 22
这里有两件事要理解.导出语法以及编译和解释值之间GHCi行为的差异.
使用此语法从模块导出
module System.Random (
-- ...
, StdGen
-- ...
Run Code Online (Sandbox Code Playgroud)
告诉GHC只导出数据类型,而不是构造函数(即使两者都有相同的名称).如果要导出构造函数,可以在数据类型名称后面的括号中明确列出,如下所示:
StdGen(StdGen)
Run Code Online (Sandbox Code Playgroud)
或者您可以导出一个数据类型及其所有构造函数,如下所示:
StdGen(..)
Run Code Online (Sandbox Code Playgroud)
此外,GHCi在加载解释模块时,总是允许您查看模块顶层可见的所有实体,即使它们被导出列表隐藏.这是为了便于开发和调试,这也是您Foo可见的原因.
"一切"可见的模式通过*在GHCi提示符下放置模块名称来反映.如果有*,那么一切都是可见的,如果没有,那么导出的实体是可见的.
使用:m命令在作用域中添加或删除模块时,可以选择是否要在*-form中添加模块.
但是对于已编译的模块(以及System.Random通常编译的库模块),- *form不可用,因此对于这些模块,您将始终处于遵循导出列表的情况.
有关GHCi的作用域行为的完整描述,请参阅文档.
如果你看一下这些来源,你会看到以下内容:
module System.Random
(
-- stuff...
, StdGen
-- even more stuff...
)
Run Code Online (Sandbox Code Playgroud)
此语法意味着仅导出类型,而不是其构造函数.如果你也想导出构造函数,你可以:
module System.Random
( StdGen(..)
-- ...
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1604 次 |
| 最近记录: |