2012-01-28 12 views
10

Normalmente sono fermamente convinto dell'uso di namespace (nomi di moduli qualificati) nella maggior parte delle lingue in cui programma, poiché è molto utile sapere a colpo d'occhio dove è venuto un determinato identificatore a partire dal. In Haskell c'è anche il vantaggio di evitare conflitti di nome comuni con le funzioni di Preludio.Come faccio a gestire i simboli infissi che appaiono brutti con nomi qualificati

Tuttavia, mi sento come dover mettere uno spazio dei nomi su un simbolo infisso (o altre brevi e identificatori DSL-y) sembra davvero strano, quindi sono tentato di riesportare i valori, in questo modo:

import qualified Data.Sequence as Seq 
(|>) = (Seq.|>) 
(<|) = (Seq.<|) 

Cosa mi sta insidiando ora è che

  • Rilevare manualmente i valori sembra una noiosa norma d'ordine.

  • manualmente riesportatrice valori va tutto il sistema modulare esistente e non sembra di lavorare con i costruttori di dati (e forse altre cose che non ho ancora incontrato)

    import qualified Data.Sequence as Seq 
    (:>) = (Seq.:>) --gives me a parse error: 
           --"Not in scope: data constructor `:>'" 
    

Come faccio conciliare i simboli infissi e il namespace? Dovrei semplicemente arrendermi e imparare tutto lo spazio dei nomi? Ci sono le migliori pratiche Haskell per quanto riguarda i nomi e i simboli?

risposta

19

Beh, una cosa che puoi fare è importare due volte:

import Data.Sequence ((|>), (<|), ViewR ((:>))) 
import qualified Data.Sequence as Seq 

Questo importerà solo :>, |> e <| senza riserve, lasciando tutto il resto qualificato. Da notare che dal momento che :> è un costruttore di dati, devi anche importare il suo tipo di dati (ViewR), ma devi fare non per importare il resto dei costruttori di ViewR.

Inoltre, se siete preoccupati per i conflitti, si dovrebbe nascondere l'operatore a seconda dei casi:

import Prelude hiding ((.)) 

Se stai usando una libreria sano, un conflitto con Preludio significa che la funzione di libreria è stato progettato per sostituire tale funzione di preludio (ad esempio Control.Category) in modo che si desidera lasciarlo sostituire il significato predefinito.

Per quanto riguarda le migliori pratiche, non ho mai visto nessuno utilizzare operatori qualificati a meno che non ci sia un conflitto o sono a GHCi. Tutto sommato, anche il factoring nel vantaggio di sapere da dove viene un operatore, rende il codice molto meno leggibile.

8

Io generalmente importare i nomi dei tipi, i costruttori e gli operatori non qualificati, e tutto il resto qualificata:

import Data.Sequence (Seq, ViewL(..), ViewR(..), (|>), (<|)) 
import qualified Data.Sequence as Seq 

Questo doppio-import, style-type-nome non qualificato è raccomandato dalla documentazione ad Data.Map e altri contenitori standard .

Eppure, non si può sempre importare gli operatori non qualificati - per esempio, se si sta utilizzando Array/Vector e Map nello stesso modulo, non è possibile importare la (!) da entrambi non qualificato. In tal caso, di solito lo userei solo qualificato. Sembra strano, ma è meglio delle altre opzioni (come trovare il tuo nome per uno di loro per evitare uno scontro). Naturalmente, forse questa è una buona cosa se impedisce alle persone di usare funzioni non sicure come (Data.Map.!) :)

+0

Quando provo questo, ottengo il seguente errore durante la compilazione: "L'importazione di" qualsiasi cosa "è ridondante. Lo capisci anche tu? È possibile sbarazzarsi dell'avvertimento? – VF1

Problemi correlati