2012-04-28 10 views
5

Sono curioso delle obiezioni a implicit parameters discusse nell'articolo Functional Pearl: Implicit Configurations di Kiselyov e Shan.I parametri impliciti sono una difficoltà per l'inlining in GHC?

Non è valido per il codice inline (β-reduce) in presenza di parametri impliciti.

Davvero? Mi aspetto che GHC debba essere inserito nello stesso scope del parametro implicito passato, no?

Credo di capire la loro obiezione che:

il comportamento di un termine può cambiare se si aggiunge la sua firma, rimosso o modificato.

documentazione per l'utente del GHC spiega che i programmatori devono fare attenzione intorno polymorphic recursion e monomorphism restriction. Questo è in qualche modo cosa intendono per problema di inlining?

Suppongo che questo esempio di ricorsione polimorfica copra cosa intendano per "generalizzazione sui parametri impliciti" pure? Qualunque altra cosa?

La classe di tipoda Data.Reflection è davvero una soluzione ragionevole a queste difficoltà? Apparentemente deserializza l'intera struttura implicita dei dati ogni volta che si accede, il che può sembrare disastroso per le prestazioni. Potremmo per esempio volere che le nostre informazioni implicite siano una tabella di Cayley o una tabella di caratteri che occupa un gig di ram e deve essere accessibile durante milioni di operazioni algebriche.

C'è forse una soluzione migliore che utilizza parametri impliciti, o un'altra tecnica che il compilatore può facilmente ottimizzare, dietro le quinte, garantendo ancora di più tramite il sistema di tipi utilizzando thread di stato o altro?

risposta

7

Sì, l'esempio del manuale di GHC mostra come l'aggiunta di una firma di tipo può modificare la semantica del codice con parametri impliciti e credo che questo sia ciò che intendono interrompere l'inlining; la creazione di un'applicazione di len_acc1 rispetto a un'applicazione di len_acc2 produce lo stesso codice, nonostante i due abbiano una semantica diversa.

Per quanto riguarda la generalizzazione sui parametri impliciti, significa che non è possibile scrivere una funzione che può operare su più parametri impliciti; non esiste alcun meccanismo per astrarre su di essi, poiché il parametro implicito utilizzato da una funzione è fissato dal suo tipo. Con la riflessione, è possibile scrivere facilmente una funzione come doSomethingWith :: (Reifies s a, Num a) => Proxy s -> a, che può funzionare su qualsiasi tipo che reifica un valore numerico.

Per quanto riguarda ReifiesStorable, si sta osservando una versione precedente del pacchetto di riflessione; il latest version ha un'implementazione molto efficiente in cui lo reify costa solo quanto una chiamata di funzione. Si noti che, anche con la vecchia implementazione, generalmente non si utilizza direttamente la classe ReifiesStorable, ma invece Reifies, che utilizza ReifiesStorable per reificare uno StablePtr, in modo che solo pochi byte vengano copiati, non l'intero oggetto. (Questo è ciò che fa anche l'implementazione originale nel documento.) Entrambe le implementazioni sono abbastanza veloci per l'uso pratico, con la vecchia implementazione "lenta" che richiede circa 100 ms per reificare e riflettere 100000 valori e la nuova implementazione sotto i 10 Signorina.

(Full disclosure: ho lavorato alla nuova implementazione.)

L'implementazione rapida dipende dai dettagli di implementazione Haskell. L'implementazione più vecchia e più lenta viene utilizzata automaticamente per le implementazioni Haskell con cui l'implementazione rapida non è stata ancora testata; finora, GHC e Hugs hanno dimostrato di funzionare con un'implementazione rapida. È possibile richiedere l'implementazione lenta con -fslow, ma è improbabile che smetta di funzionare a meno che GHC non modifichi in modo significativo la sua implementazione dei typeclass. (Anche se lo fosse, dovresti ricompilare i pacchetti che usano il reflection per farlo funzionare di nuovo.)

+0

Ahh dolce, quindi 'Data.Reflection' è tutto nero magico ora. :) C'è qualche codice o articoli che consigli di leggere? 'Data.Reflection' ha già più senso ora che noto la directory degli esempi. Dovrei leggere un'altra cosa su 'Data.Tagged' e' Data.Proxy' però. –

Problemi correlati