2013-11-22 6 views
10

Değerlerin önceden hesaplanıp hesaplanmadığına veya hatıra mı olduğuna bağlı olarak bir Haskell işlevi yazılabilir mi? Örneğin. lazyShow :: [Int] -> String normalde ? olarak thunks ve hesaplanan değerler gösteriyorsa, GHCi bizHaskell'de görmezlik gözlemlenmesi

Açıkça
> let nats = [0..] 

> lazyShow nats 
0 : ? 

> nats !! 5  
5 

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

cevap

15

, lazyShow Eğer devlet türü olamaz görecekti. Dize, geçerli değerlendirme durumuna bağlıysa, sonuç olarak IO String, umduğunuz en iyisidir.

Tüm ilgilendiğiniz hata ayıklama için kullanıyorsa, bu nedenle ghc-heap-view paketinin (ve potansiyel olarak ghc-vis gibi bir grafiksel ön öğenin) bu amaç için yararlı olduğunu düşünüyorum. Değerin GHC'nin yığınında nasıl göründüğüne ilişkin bir açıklamayı görüntülemek için kullanılabilecek bir GHCi komutu olan :printHeap'u tanımlar. Bu belki de amaçlanan olandan biraz daha düşük seviyeli, ama nasıl tembel değerlendirme ve paylaşım çalışmaları daha iyi anlamak için oldukça yararlı olabilir: önerildiği şekilde

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) 

açıkça System.Mem.performGC (aracılığıyla çöp toplayıcı arıyorum görünümü temizlemek için ghc-yığın görünümü) belgelerine.

5

Sen uygulanmasını kazma ilginizi çekebilir

> 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,_,_,_,_,_] 
: thunks bakarak yeteneğine sahiptir GHCi, içinde "sürat"