Ale*_*nov 10 haskell lazy-evaluation
是否可以编写一个Haskell函数,该函数取决于值是已经计算还是是thunk?例如,如果通常lazyShow :: [Int] -> String
显示thunks as ?
和计算值,我们会看到GHCi
> let nats = [0..]
> lazyShow nats
0 : ?
> nats !! 5
5
> lazyShow nats
0 : 1 : 2 : 3 : 4 : ?
Run Code Online (Sandbox Code Playgroud)
kos*_*kus 15
显然,lazyShow
不能有你说的类型.如果字符串应该取决于当前的评估状态,那么IO String
结果是您可以期望的最佳状态.
如果您感兴趣的是使用它进行调试,那么我认为ghc-heap-view包(以及可能的图形前端,如ghc-vis)对此有用.它定义了一个GHCi命令:printHeap
,可用于显示值在GHC堆中的显示方式.它可能比你想要的更低级别,但是更好地理解懒惰的评估和共享工作是非常有用的:
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)
Run Code Online (Sandbox Code Playgroud)
我明确地调用垃圾收集器System.Mem.performGC
(如ghc-heap-view文档中的建议)来清理视图.
您可能有兴趣在GHCi中挖掘":sprint"的实现,它具有查看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,_,_,_,_,_]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
230 次 |
最近记录: |