2015-10-23 11 views
7

C'è un pezzo di codice sorgente che ha avuto origine in una risposta ad another one of my questions,Haskell - è una chiusura?

infFromPrefix :: Eq a => ([a] -> [a]) -> [a] -> [a] 
infFromPrefix rules prefix = inf where 
    inf = prefix ++ case stripPrefix prefix (rules inf) of 
     Just suffix -> suffix 
     Nothing  -> error "Substitution does not preserve prefix" 

dove sono abbastanza sicuro che inf deve essere una chiusura in quanto ha accesso alle variabili dal suo campo di applicazione racchiude nel senso che utilizza i parametri passati a infFromPrefix, ma non sono sicuro poiché essenzialmente infFromPrefix e inf è la stessa funzione, lo inf consente solo una definizione più breve di . Una definizione equivalente sarebbe

infFromPrefix rules prefix = prefix ++ case stripPrefix prefix (rules $ infFromPrefix rules prefix) of 
     Just suffix -> suffix 
     Nothing  -> error "Substitution does not preserve prefix" 

Ho ragione, è inf una chiusura?

+0

Direi "no" perché "inf" non è una funzione; è una lista. – melpomene

+5

@melpomene Penso che nei linguaggi desiderosi sia opportuno limitare le chiusure per contenere le funzioni; in lingue pigre non ne sono così sicuro. Per lo meno, sarei disposto a scommettere che GHC ha una struttura dati che chiama "chiusura" che è coinvolta nella rappresentazione di 'inf' a un certo livello. –

+0

@melpomene Hai ragione, altrimenti le regole non lo accetterebbero come input. Saluti. –

risposta

4

basata sull'articolo Wiki su Closures in programming, credo si possa dire che inf è davvero non una chiusura:

Nota soprattutto che le definizioni di funzioni annidate non sono essi stessi le chiusure: hanno un libero variabile, che non è ancora vincolata. Solo una volta che la funzione di inclusione viene valutata con un valore per il parametro, la variabile libera della funzione nidificata viene associata, creando una chiusura, che viene quindi restituita dalla funzione di inclusione.

+0

Sono d'accordo con te, dato che Haskell è pigro, tutto può essere visto come una chiusura, in quanto anche un valore può essere visto come una funzione senza argomento in attesa di essere valutata (e quindi catturare l'ambiente finché non viene valutato). – mb14

+2

"[A] s anche un valore può essere visto come una funzione senza argomento." Non proprio no. –

10

Sono d'accordo con Lennart e Daniel che la chiusura è un termine specifico per l'implementazione e non è qualcosa di ben definito in generale. Inoltre, non sento Haskellers parlare di chiusure molto al di fuori dei problemi di implementazione; quando i programmatori in altre lingue parlano casualmente di "chiusure", in genere intendono ciò che chiamiamo "lambda". (Come in "quella lingua ha chiusure?")

In ogni caso, parliamo di GHC.

GHC (o, più precisamente, STG) chiama una chiusura qualsiasi oggetto heap che non è un'applicazione di costruzione.

(Nel caso che questa sia una definizione ampia, confrontare questo con il STG lavoro originale in cui anche i costruttori sono stati chiamati chiusure.)

tuo inf è certamente una chiusura STG; è un thunk che verrà assegnato all'heap e restituito al chiamante.

+0

_ "restituito al chiamante" _ - il chiamante di quale funzione? 'inf' o' infFromPrefix'? Non sono sicuro di come mettere la tua risposta nel contesto di come [wikipedia definisce una chiusura] (https://en.m.wikipedia.org/wiki/Closure_ (computer_programming)). –

+0

'infFromPrefix' costruisce una chiusura/thunk nell'heap,' inf' e restituisce (il puntatore) al suo chiamante ('infFromPrefix'). Il chiamante inserirà quindi la chiusura per valutarla al grado necessario. –

+2

@ErikAllik Forse parte del problema è che le persone qui (e nell'articolo di Wikipedia) non stanno facendo attenzione alla differenza tra oggetti statici - frammenti di sintassi in una lingua - e oggetti dinamici - cose che vengono create e ispezionate in fase di esecuzione. Dire che 'inf' stesso non è una chiusura sembra tecnicamente corretto, poiché è un oggetto statico, e solo gli oggetti dinamici possono essere chiusure; ma per dire che in fase di esecuzione l'espressione 'inf' viene trasformata in una chiusura quando viene chiamato anche' infFromPrefix' sembra corretto. –