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

And*_*man 5 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
Run Code Online (Sandbox Code Playgroud)

我隐藏了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>
Run Code Online (Sandbox Code Playgroud)

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

sep*_*p2k 7

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

如果您希望代码的行为就像从另一个文件导入,则可以使用import而不是:l.然后它只允许访问支持的定义.

  • @Bush你是对的,它适用于已编译的模块.所以这有点不利. (2认同)