In quali altri luoghi oltre a flussi infiniti e liste infinite viene memorizzata la lazyness utile?

0

Haskell è una delle poche lingue non rigide in circolazione.

Nel suo articolo Perché argomenti di programmazione funzionale , John Hughes utilizza (memoized) valutazione pigra (così come le funzioni di ordine superiore) per implementare un paio di algoritmi piacevoli dove è in grado di separare:

  • come vengono generati i dati.
  • come potrebbero essere manipolati questi dati.
  • in che modo i dati risultanti potrebbero essere consumati.

Mostra due esempi:

  1. Uso di un flusso infinito per generare approssimazioni sempre crescenti di valori numerici interessanti (come una radice quadrata, una derivata o un integrale)
  2. Utilizzo di un albero a più vie infinito per esplorare possibili posizioni future di una bacheca di gioco.

Nel mio lavoro in una vasta gamma di lingue, a volte ho visto anche l'uso della pigrizia, ma quasi sempre è stato in uno di questi due contesti: o un flusso lineare (finito o infinito) o un multi- way tree.

Ci sono altre strutture dati il cui consumo è vantaggioso se fatto in modo pigro?

    
posta Qqwy 10.09.2018 - 16:48
fonte

1 risposta

2

Alcune altre situazioni che ti vengono in mente:

  • Processi iterativi che devono utilizzare i risultati di alcuni valori precedenti ma non di altri (che fornisce semplici modi per implementare efficientemente processi come la sequenza di Fibonacci o la congettura di Collatz)
  • Restituzione di più risultati da una funzione (ad esempio in una tupla o un record) in cui il chiamante può richiedere solo uno dei valori calcolati senza spreco di energie nel calcolare gli altri
  • Fornire un modo semplice per implementare I / O di streaming, ad es. restituire un elenco pigro di righe da un file, come % co_de di Haskell % (si noti che a causa del modo in cui è implementato Haskell, questo può causare problemi dove i file non vengono mai chiusi, quindi in Haskell dovrebbe essere usato con cautela, ma in linea di principio il metodo è estremamente utile 1 .
  • Implementazione di processi che producono e consumano flussi di dati in modo incrementale - questo non ha bisogno di alcun supporto complesso, a differenza di linguaggi come Java dove gli stream richiedono molta infrastruttura, o Python dove hanno bisogno di una funzione linguistica speciale (funzioni del generatore): una funzione può semplicemente restituire una lista e può essere consumata direttamente 1 .
  • Uno di un progetto a cui sto lavorando sporadicamente: elaborazione degli stati di una macchina a stati finiti solo quando vengono utilizzati (un requisito chiave per l'implementazione efficiente di ALL(*) Algoritmo di parsing ) 2 .

1. mentre questi sono casi in cui vengono utilizzati i flussi, penso che siano abbastanza diversi dall'esempio nella domanda che dovrebbe essere considerato un uso separato della struttura.

2. questo produce un DAG, che è un po 'come un albero, ma ancora una volta ritengo che l'applicazione sia sufficientemente rimossa da farne menzione.

    
risposta data 11.09.2018 - 19:22
fonte