2014-05-02 6 views
8

Mi sono imbattuto in alcuni moduli che contengono importazioni particolarmente strane.Perché questi casi d'angolo nel lavoro di importazione di Haskell e come funzionano?

Prima di tutto, ho visto un modulo A che importa un altro modulo come se stesso. Ad esempio:

-- module A.hs 
module A where 
import B as A -- ??? 

f = id 

Cosa fa? Perché questo è consentito a tutti?

Tuttavia ciò che più guai me è che il codice è in realtà di questo tipo:

module A where 
import B as A -- Okay, assume this works... 
import C as A -- ??? A is already defined! 

f = id 

Perché può più di un modulo essere importati con lo stesso nome? Cosa ottiene? Ho pensato che questo tipo di import s non è stato permesso e anche A Gentle Introduction to Haskell afferma che:

è illegale importare due entità diverse che hanno lo stesso nome nello stesso ambito.

Tuttavia queste importazioni funzionano correttamente. Ancora un altra cosa strana che mi bug sta esportando il modulo stesso:

module A (module A) where 

In sintesi, data la seguente MWE:

-- A.hs 
module A (module A) where 
import B as A 
import C as A 

f = id 

-- B.hs 
module B where 

g = id 

-- C.hs 
module C where 

h = id 
  1. Sono le importazioni seguendo gli standard o si tratta di alcuni bug di GHC? Non sembra un bug, ma non riesco a trovare alcun riferimento che spieghi tutti questi casi angolari.
  2. Qual è il risultato esatto raggiunto? Voglio dire: quali nomi sono importati e/o esportati da A?
+1

Non ho mai visto esportare il modulo da solo; Interessante. Tutti gli altri casi, i nomi nelle diverse importazioni sono uniti. Per esempio. 1o esempio: A.somethingInB si riferisce alla versione di B, ma A.f si riferisce alla versione di A (a meno che B non definisca anche f, allora si tratta di un errore di ambiguità). Fortunatamente, questo è chiaramente comprensibile :-) – luqui

risposta

6

I qualificatori del nome non sono la stessa cosa dei nomi dei moduli. Un qualificatore di nomi è solo un ambito collettivo, puoi fare riferimento a un numero qualsiasi di moduli. Normalmente non ne aggiungerai più di uno, ma in un caso lo quasi sempre aggiungi molti moduli: nello spazio non qualificato. import Data.List potrebbe essere letto come qualcosa come import qualified Data.List as "": ordina che, ad esempio, sortBy venga trovato quando ci si riferisce ad esso con un "qualificatore vuoto", cioè con nessuno. Ma potremmo "rinomina" tale ambito:

module Main where 

import qualified Prelude as P 
import qualified Data.List as P 
import qualified Data.Ord as P 

main :: P.IO() 
main = do -- `do` is syntax, not a name! 
    P.print P.. P.map P.snd P.$ P.sortBy (P.comparing P.fst) 
    [(4,'o'),(6,' '),(0,'H'),(1,'e'),(3,'l'),(9,'r'),(7,'W'),(10,'l'),(8,'o'),(2,'l'),(5,','),(11,'d'),(12,'!')] 

Le uniche qualificazioni che sono fissi sono quelli relativi al modulo nel file stesso: questo è sempre sia in ambito non qualificata, e nel campo di applicazione automaticamente prende il nome del modulo . E per le definizioni , è necessario utilizzare il modulo non qualificato.

Per module A (module A), sembra piuttosto fasullo. Non penso che le esportazioni di moduli siano davvero ben pensate. Essi funzionano correttamente solo quando si fa riferimento ad un modulo vero e proprio, non solo un qualificatore nome, vale a dire

module PowerPrelude (module A) 
import qualified Prelude as A 
import qualified Data.List as A 
import qualified Data.Ord as A 

sarà non lavoro. Il che ti fa chiedere perché sia ​​permesso dichiarare una tale esportazione. Potrebbe davvero essere un bug qui.

+0

Può essere utile esportare esplicitamente l'intero modulo corrente, se ad esempio si desidera riesportare alcuni moduli e l'intero modulo corrente: 'modulo A (modulo A; modulo B; modulo C) dove ; importazione B; importazione C; ... 'Se non fosse possibile, dovresti specificare ogni singola dichiarazione in' A' nelle esportazioni. – user2407038

+0

Diritto. Anche se questo non spiega perché non è un errore esportare un ambito "modulo" che in realtà non è un nome di modulo - l'esempio 'PowerPrelude' compila, solo che non espone nulla! – leftaroundabout

+0

Nel tuo ultimo esempio hai aggiunto un 'qualificato' che non è presente nel mio caso. In effetti quei nomi * sono * esportati nel mio codice ... quello che non capisco è il caso d'uso. Per me sembra come 'modulo A (modulo A) dove l'importazione B come A' è perfettamente equivalente a' modulo A (modulo B) importazione B', o no? – Bakuriu

Problemi correlati