2014-12-18 6 views
5

Sono un principiante in Haskell. Ecco alcune semplici righe di codice:Perché ghci può vedere tipi e costruttori non esportati? Come posso ripararlo?

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 

ho nascosto il tipo Answer e il costruttore Rectangle. Ma quando carico il Src.hs di file, ghci li vede ancora:

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> 

Perché questo è accaduto e come posso risolvere il problema?

+0

You' Hai cose nascoste da cose che importano il modulo, ma non puoi nascondere un file da solo! –

risposta

5

Sì, quando si carica un file in GHCi in questo modo, è possibile accedere a qualsiasi cosa definita in tale file indipendentemente dal fatto che venga esportata o meno. In questo modo le espressioni scritte in GHCi si comportano esattamente come nel file caricato. In questo modo è possibile utilizzare GHCi per testare rapidamente un'espressione che si intende utilizzare all'interno del file o per testare velocemente una funzione definita nel file anche se è privata.

Se si desidera che il codice si comporti come importato da un altro file, è possibile utilizzare import anziché :l. Quindi consentirà l'accesso solo a definizioni estrapolate.

+1

Posso usare solo il comando 'import' per il modulo compilato? Non mangia il file hs-source. Ottengo un'eccezione: * Impossibile trovare il modulo 'Src '. Non è un modulo nel programma corrente o in qualsiasi pacchetto noto. * –

+2

@Bush Hai ragione, funziona solo per moduli già compilati. Quindi questo è un po 'un aspetto negativo. – sepp2k

1

Se si importa un modulo con :l, si ottiene l'accesso a tutto, ignorando la clausola di esportazione:

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

Se invece import Export, si ottiene solo le associazioni esportate:

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

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

Caricate il file sorgente * .hs tramite il comando 'importa'? O file compilato? –

+1

Sopra non ho compilato nulla, ma prima ho caricato il modulo con ': l', quindi non importato con': m -Export', e infine ho eseguito 'import Export'. – chi