2013-11-22 13 views
10

È possibile scrivere una funzione Haskell che dipende dal fatto che i valori siano già calcolati o siano thunk? Per esempio. se lazyShow :: [Int] -> String mostra thunks come ? ei valori calcolati normalmente, in GHCi vedremmoOsservare la pigrizia in Haskell

> let nats = [0..] 

> lazyShow nats 
0 : ? 

> nats !! 5  
5 

> lazyShow nats 
0 : 1 : 2 : 3 : 4 : ? 

risposta

15

Chiaramente, lazyShow non può avere il tipo dichiarate. Se la stringa deve dipendere dallo stato attuale della valutazione, allora il IO String è il meglio che si possa sperare.

Se tutto ciò che ti interessa è utilizzare questo per il debug, allora penso che il pacchetto ghc-heap-view (e potenzialmente un frontend grafico come ghc-vis) sia utile per questo scopo. Definisce un comando GHCi :printHeap che può essere utilizzato per visualizzare una descrizione di come il valore appare nell'heap di GHC. E 'forse un più basso livello di bit di quello che intendeva, ma può essere molto utile per capire meglio come pigri valutazione e condivisione del lavoro:

Prelude> let nats = [0..] 
Prelude> :printHeap nats 
(_bco (D:Enum _fun _fun _fun _fun _fun _fun _fun _fun) _fun)() 
Prelude> null nats 
False 
Prelude> System.Mem.performGC 
Prelude> :printHeap nats 
let x1 = S# 0 
in x1 : _thunk x1 (S# 1) 
Prelude> nats !! 5 
5 
Prelude> System.Mem.performGC 
Prelude> :printHeap nats 
let x1 = S# 5 
in S# 0 : S# 1 : S# 2 : S# 3 : S# 4 : x1 : _thunk x1 (S# 1) 

sto esplicitamente chiamando il garbage collector tramite System.Mem.performGC (come raccomandato in la documentazione di ghc-heap-view) per ripulire un po 'la vista.

5

Potreste essere interessati a scavare la realizzazione del ": sprint" in GHCi, che ha la capacità di guardare in thunk:

> let a = map (+1) [1..10] 
> :sprint a 
a = _ 

> length a 
10 

> :sprint a 
a = [_,_,_,_,_,_,_,_,_,_] 

> take 5 a 
[2,3,4,5,6] 

> :sprint a 
a = [2,3,4,5,6,_,_,_,_,_] 
Problemi correlati