为什么ghci可以看到非导出类型和构造函数?我该如何解决?

时间:2014-12-18 13:46:07

标签: haskell ghci

我是Haskell的新手。这是一些简单的代码:

module Src
(   -- The 'Answer' type isn't exported
    Shape(Circle), -- i.e 'Rectangle' data constructor isn't exported
    Point(..),
    area,
    nudge
) where

data Answer = Yes | No deriving (Show)

data Point = Point Float Float deriving (Show)

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

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

nudge::Shape->Float->Float->Shape
nudge (Rectangle(Point x1 y1)(Point x2 y2)) dx dy = Rectangle 
    (Point (x1 + dx) (y1 + dy)) (Point (x2 + dx) (y2 + dy))
nudge (Circle (Point x y) r) dx dy  = Circle (Point(x + dx) (y + dy)) r

我已隐藏Answer类型和Rectangle构造函数。但是当我加载 Src.hs 文件时,ghci仍然可以看到它们:

ghci> :l src
[1 of 1] Compiling Src ( src.hs, interpreted )
Ok, modules loaded: Src.
ghci> let a = Yes
ghci> a
Yes
ghci> :t a
a :: Answer
ghci> let r = Rectangle (Point 0 0) (Point 100 100)
ghci> r
Rectangle (Point 0.0 0.0) (Point 100.0 100.0)
ghci> :t r
r :: Shape
ghci>

为什么会发生这种情况,我该如何解决?

2 个答案:

答案 0 :(得分:6)

是的,当您在GHCi中加载文件时,您可以访问该文件中定义的任何内容,无论它是否已导出。这样,您写入GHCi的表达式就像在加载的文件中一样。因此,您可以使用GHCi快速测试您在文件中使用的表达式,或者快速测试文件中定义的函数,即使它是私有的。

如果您希望代码的行为就像从其他文件导入,则可以使用import代替:l。然后它只允许访问支持的定义。

答案 1 :(得分:1)

如果您使用:l导入模块,则可以访问所有内容,忽略导出子句:

Prelude Export> :l Export
[1 of 1] Compiling Export           ( Export.hs, interpreted )
Ok, modules loaded: Export.
*Export> a
6
*Export> b
5

如果您改为import Export,则只获得导出的绑定:

Prelude> import Export
Prelude Export> a
6
Prelude Export> b

<interactive>:28:1: Not in scope: ‘b’