2012-09-29 10 views
17

In Haskell, scrivo import Fruit o import Fruit (apple) e può accedere a apple o Fruit.apple.Importazione della funzione con un alias in Haskell

In Python, posso scrivere from Fruit import apple per apple o import Fruit per Fruit.apple.

Penso che possa anche scrivere import Fruit.apple as banana in Python per fare riferimento alla stessa funzione di banana.

Come, in Haskell posso fare questo? import Fruit as Vegetable in entrambe le lingue è possibile rinominare Frutta, ma voglio rinominare la mela.

+0

Per vostra informazione, io sono in particolare in questo momento cercando di importare Data.List.genericLength la lunghezza per ottenere liberarsi di Int senza refactoring. –

+0

Mi chiedo quanto sarebbe facile o difficile applicare a GHC una patch per accettare la seguente sintassi: 'import Fruit (apple as banana)'. – Wizek

risposta

17

Questa è una bella proprietà che Python ha perché i suoi "dizionari fino in fondo", per così dire. Haskell consente di assegnare alias ai moduli, ma non esiste alcun modo per le funzioni alias dall'istruzione import (per quanto ne so). Il meglio che si sarebbe in grado di fare è

import qualified Fruit as F (apple) 
banana = F.apple 

Si potrebbe mettere questo nel proprio modulo ed esportare i valori desiderati, nascondendo i dettagli di tutto questo, ma che sembra un sacco di lavoro per qualcosa di così semplice .

Come commentato di seguito da hammar, la limitazione del monomorfismo potrebbe causare problemi con il tipo dedotto di banana. Per essere sicuri, si dovrebbe annotare sia banana con il suo tipo desiderato (probabilmente quello di apple), o disabilitare la restrizione monomorfismo come

{-# LANGUAGE NoMonomorphismRestriction #-} 
import qualified Fruit as F (apple) 
banana = F.apple 

In caso contrario, il tipo dedotto di banana potrebbe essere meno polimorfico di quanto desiderato.

La limitazione del monomorfismo tenta di assegnare un'istanza concreta di una classe di tipo per ogni funzione di livello superiore (ciò avviene per motivi di prestazioni). Si consideri,

example = return() 

Questa funzione dovrebbe avere tipo Monad m => m(), ma a causa della restrizione monomorfismo, non ci sono abbastanza informazioni su quali dovrebbe essere utilizzata esempio Monade, in modo da ottenere il seguente messaggio

Ambiguous type variable `m0' in the constraint: 
    (Monad m0) arising from a use of `return' 
Possible cause: the monomorphism restriction applied to the following: 
    example :: m0() (bound at Test.hs:44:1) 
Probable fix: give these definition(s) an explicit type signature 
       or use -XNoMonomorphismRestriction 
In the expression: return() 
In an equation for `example': example = return() 

Ora , se si forniscono informazioni sufficienti per GHC di dedurre quale istanza di Monade che si sta utilizzando, come ad esempio

example = return() 

main :: IO() 
main = example 

poi GHC darà la Follo ala tipo

*Main> :t example 
example :: IO() 

dal momento che si è detto che example avrà lo stesso tipo di main

+2

Non è 'banana = F.apple'? – Artyom

+0

@ArtyomKazak Sì, lo è! – sabauma

+8

Prestare attenzione alla limitazione del monomorfismo quando si esegue questa operazione, tuttavia, o "banana" può risultare più restrittivo di "mela". – hammar

7

Non c'è sintassi per che, direttamente. Presumibilmente si vuole evitare uno scontro con un localmente definito apple, quindi mi piacerebbe andare con

import qualified Fruit (apple) 
banana = Fruit.apple