2014-05-09 10 views
9

Non sono del tutto chiaro su come seq funziona in Haskell.Scriveresti mai seq x x?

Sembra che ci sono un sacco di casi in cui sarebbe utile scrivere

seq x x 

e forse anche definire una funzione:

strict x = seq x x 

ma tale funzione non esiste già quindi immagino che questo approccio sia in qualche modo sbagliato. Qualcuno potrebbe dirmi se questo è significativo o utile?

+0

Hai letto [wiki] (http://www.haskell.org/haskellwiki/Seq) su di esso? Fa un buon lavoro di spiegare le sfumature di 'seq', dal momento che non è del tutto semplice. – bheklilr

+0

"In particolare, l'espressione' 'x' seq' x'' è completamente ridondante e ha sempre esattamente lo stesso effetto della sola scrittura di 'x'" –

+0

correlati: [questa risposta] (http://stackoverflow.com/ a/19805521/925978) e, cosa più importante, i commenti sottostanti. – crockeea

risposta

18

seq a b restituisce il valore di b, ma rende tale valore dipendente dalla valutazione di a. Pertanto, seq a a è esattamente la stessa cosa di a.

Penso che l'equivoco qui sia che seq non intraprende alcuna azione, perché le funzioni pure non intraprendono azioni, ma introduce solo una dipendenza.

C'è una funzionein Control.Exception che fa ciò che si desidera (si noti che è in IO). Lo mettono in eccezione perché è utile vedere se la valutazione di un'espressione verrebbe generata e, in tal caso, gestire l'eccezione.

5

seq x x sarebbe completamente, banalmente ridondante.

Ricorda, seq è non un comando. La presenza di un seq a b nel programma non impone la valutazione di a o b Ciò che fa, rende la valutazione del risultato dipendente artificialmente dalla valutazione di a, anche se il risultato stesso è b Se si stampa seq a b, a sarà valutato e il suo risultato scartato .. Dal momento che x dipende già da sé, seq x x è sciocco.

8

L'espressione x = seq a b significa che se x viene valutata, quindi verrà valutata a (ma x sarà pari a b).

Fa non significa "valuta a ora".

Si noti che se si sta valutando x, poiché x è uguale a b, verrà valutato anche .

E quindi, se scrivo x = seq a a, sto dicendo "se x viene valutato quindi valutare a". Ma se mi limitassi a fare x = a, ciò porterebbe a esattamente la stessa cosa.

+1

Credo che tu abbia inteso che anche 'a' sarà valutato, nella prima frase. –

5

Quando dici seq a b ciò che si sta dicendo il computer è,

Ogni volta che è necessario valutare b, valutare a anche per me, per favore.

Se sostituiamo sia a e b con x si può vedere perché è inutile scrivere seq x x:

Ogni volta che è necessario valutare x, valutare x anche per me, per favore.

Chiedere al computer per valutare x quando è necessario valutare x è solo una cosa inutile da fare - stava andando a valutare x comunque!

seq fa non valutare qualsiasi cosa - racconta semplicemente il computer che quando è necessario il secondo argomento, valutare anche il primo argomento. Capire questo è davvero molto importante, perché ti permette di capire il comportamento dei tuoi programmi molto meglio.

1

Chiudi! deepseq (che è il "più approfondita" seq - vedi la documentazione per una descrizione completa) ha il tipo NFData a => a -> b -> b, e force (con il tipo NFData a => a -> a) è definito semplicemente come

force :: (NFData a) => a -> a 
force x = x `deepseq` x