2014-12-18 3 views
5

Ich bin ein Neuling in Haskell. Hier ist ein einfacher Code:Warum kann ghci nicht exportierte Typen und Konstruktoren anzeigen? Wie kann ich es reparieren?

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 

ich versteckt habe den Answer Typen und den Rectangle Konstruktor. Aber wenn ich die Src.hs Datei laden, sieht GHCI sie noch:

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> 

Warum ist das passiert und wie kann ich es beheben?

+0

Sie‘ Versteckte Dinge von Dingen, die das Modul importieren, aber Sie können eine Datei nicht vor sich selbst verstecken! –

Antwort

5

Ja, wenn Sie eine Datei in GHCi so laden, können Sie auf alle in dieser Datei definierten Dateien zugreifen, unabhängig davon, ob sie exportiert werden oder nicht. Auf diese Weise verhalten sich Ausdrücke, die Sie in GHCi schreiben, genauso wie in der geladenen Datei. So können Sie mit GHCi schnell einen Ausdruck testen, den Sie in der Datei verwenden möchten, oder eine in der Datei definierte Funktion schnell testen, selbst wenn sie privat ist.

Wenn Sie möchten, dass sich der Code wie aus einer anderen Datei importiert verhält, können Sie import anstelle von :l verwenden. Dann wird nur der Zugriff auf die exportierten Definitionen erlaubt.

+1

Kann ich den Befehl 'import' nur für das kompilierte Modul verwenden? Es isst nicht die hs-Quelldatei. Ich bekomme eine Ausnahme: * Modul 'Src 'konnte nicht gefunden werden. Es ist kein Modul im aktuellen Programm oder in einem bekannten Paket. * –

+2

@Bush Sie haben recht, es funktioniert nur für bereits kompilierte Module. Das ist also ein kleiner Nachteil. – sepp2k

1

Wenn Sie ein Modul mit :l importieren, haben Sie Zugriff auf alles erhalten, um den Export-Klausel ignoriert:

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

Wenn Sie stattdessen import Export, erhalten Sie nur die exportierten Bindungen:

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

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

Laden Sie die Quelldatei * .hs über den Befehl 'import'? Oder eine kompilierte Datei? –

+1

Oben habe ich nichts kompiliert, aber zuerst habe ich das Modul mit ': l' geladen, dann unimported es mit': m -Export' und habe schließlich 'import Export' ausgeführt. – chi

Verwandte Themen