2015-10-16 26 views
15

ho messo queste definizioni in un file:“Il rigore” di parentesi quadre

x = 'a' : 'b' : 'c' : [] 
y = ['a', 'b', 'c'] 

(E 'importante definire quelle di un file, non in GHCi, perché in quest'ultimo caso le cose diventano molto più strano, ma questa è un'altra questione)

Ora, caricare il file in GHCi e:.

λ> :sprint x 
x = _ 
λ> :sprint y 
y = _ 
λ> seq x() 
() 
λ> seq y() 
() 
λ> :sprint x 
x = 'a' : _ 
λ> :sprint y 
y = "abc" 

cosa sta succedendo qui? Capisco cosa succede nel caso di x, questo è esattamente quello che mi aspettavo. Ma che dire di ?

Quello che vedo sembra contraddire section 3.7 del Rapporto, che dice:

Traduzione: la seguente identità:

[e1, …, ek] = e1 : (e2 : (… (ek : []))) 

Inoltre:

y = [toUpper 'a', 'b', undefined] 
λ> seq y() 
() 
λ> :sprint y 
y = "Ab*** Exception: Prelude.undefined 
λ> :sprint y 
*** Exception: Prelude.undefined 

con liste di Char s anche la valutazione attuale è costretto, ma con altri tipi di cose sono ancora sconosciuto:

x = True : False : id False : [] 
y = [True, False, id False] 
λ> seq x() 
() 
λ> seq y() 
() 
λ> :sprint x 
x = True : _ 
λ> :sprint y 
y = [True,False,_] 
+7

': sprint' consente di guardare dietro le quinte delle strutture dati reali che rappresentano i dati. Non è necessario che le definizioni semanticamente equivalenti siano visualizzate allo stesso modo da ': sprint'. (In realtà l'intero punto di ': sprint' è quello di cambiare come un valore diventa più valutato, ma il valore stesso non cambia nel processo!) Quindi non c'è contraddizione con il rapporto. Ma non posso dire fuori mano perché ghci sembra costruire dati pre-costruiti per 'y' ma non' x'. –

+2

Detto questo, nell'esempio 'y =" Ab *** Exception: Prelude.undefined' sembra che ': sprint' si comporta male, non dovrebbe valutare gli elementi della stringa qui –

+0

@ReidBarton Sì, quello è un buon punto su ': sprint' e Haskell Report. E sembra che valuti elementi solo nel caso di' Char's (ho aggiunto un altro esempio alla domanda) – kirelagin

risposta

3

questo sembra essere solo limitato a sprint. Se si scrive un programma semplice come

import Control.Exception 

x, y :: String 
x = 'a' : 'b' : undefined : [] 
y = ['a', 'b', undefined] 

main :: IO() 
main = do 
    evaluate x 
    evaluate y 
    putStrLn "Done" 

poi evaluating sia per WHNF procede senza toccare undefined.

La mia ipotesi è che per qualche strana ragione GHCi decide di stampare x come una lista, ma y come una stringa, che è la cosa che costringe la valutazione di tutta la y, non i seq/evaluate chiamate.

+1

Beh, sembra che tu sia a metà destra. Questa cosa di valutazione avviene solo con gli elenchi di 'Char's, ma': sprint' con parentesi quadre si comporta ancora in modo strano. Aggiornerò la mia domanda tra un momento, mostrando questo. – kirelagin

Problemi correlati