2013-10-09 13 views
5

La mia comprensione è che la sintassi tratteggiata dei moduli, in Haskell, rappresenta la struttura logica su disco. Quindi, se abbiamo una struttura come questa:Specifica dei moduli Haskell "Up The Tree"

Main.hs 
Foo/ 
    Bar.hs -- exports "Bar" 
    Quux.hs -- exports "Quux" 

... poi nel nostro Main.hs, possiamo fare:

import Foo.Bar 
import Foo.Quux 

(presumo che possiamo avere solo moduli a nodi foglia del filesystem Ad esempio, in precedenza, non è possibile avere un modulo Foo.)

In questo esempio, stiamo attraversando l'albero. Cosa succede se vogliamo salire?

lib/ 
    SomeModule.hs 
    XYZ.hs 
src/ 
    Main.hs 

Cioè, in Main.hs, come possiamo importare SomeModule o XYZ?

Forse questo non sarebbe un evento comune con Main, ma per quanto riguarda le dipendenze tra moduli? Potrebbero avere legittimamente bisogno di fare riferimento ai nodi "cugini".

+3

È molto comune disporre di moduli nelle "filiali", ad es. crea '' 'Foo.hs''' nella stessa directory di' '' Foo/'' 'dir – amindfv

+1

Inoltre, per essere precisi: la sintassi tratteggiata dei moduli rappresenta la struttura logica su disco * in GHC *. Il Report in sé non fornisce alcuna indicazione su come i moduli siano archiviati su disco, e un'implementazione rivale potrebbe scegliere di fare altre cose: avere un file manifest, usare un database, archiviare cose nel cloud ... –

risposta

7

Basta usare il nome completo del modulo e comunicare a GHC dove trovare la radice della gerarchia del modulo con l'opzione -i. Nel tuo esempio, questo significa che devi usare import XYZ in Main.hs per importare il modulo e il comando ghc -i../src --make Main.hs per compilare il tuo programma. Se è necessario compilare moduli reciprocamente ricorsivi, dare un'occhiata a this section del manuale GHC.

Se si utilizza Cabal per creare il pacchetto, è possibile raggruppare i moduli sotto lib in una libreria e quindi rendere tale libreria una dipendenza del file eseguibile. Si avrà la seguente struttura di directory:

some-package.cabal 
lib/ 
    XYZ.hs 
src/ 
    Main.hs 

Le parti rilevanti del file some-package.cabal sarà simile a questo:

Name: some-package 
Version: 1.0 
... 
Library 
    ... 
    Exposed-modules: XYZ 
    Hs-source-dirs: lib 
    ... 
Executable some-executable 
    ... 
    build-depends: some-package == 1.0 
    ... 
... 

Ciò è particolarmente utile se il pacchetto comprende un test o suite di benchmark, in quanto il i moduli sotto lib verranno compilati una sola volta.

Ecco la a real-life example di questa tecnica.