Simon Marlow 书中严格评价的例子 "Parallel and Concurrent Programming in Haskell"
The example of strict evaluation from Simon Marlow's book "Parallel and Concurrent Programming in Haskell"
Simon Marlow 在他的书“Haskell 中的并行和并发编程”中写道:
The insert operation hadthis line:
putMVar m (Map.insert name number book)
This places in the MVar the unevaluated expression Map.insert name number book
.
If we were to do many insert operations consecutively, the MVar would build up a large chain of unevaluated expressions.
To get brief locking and no space leaks, we need to use
a trick:
let book' = Map.insert name number book
putMVar m book'
seq book' (return ())
With this sequence, we’re storing an unevaluated expression in the MVar, but it is evaluated immediately after the putMVar.
我不明白。 seq a b
运算以弱头范式计算 a
。所以会有unevaluated expression。如我所见,只会评估 Map 构造函数,而不会评估其所有内容。
As I can see only the Map
constructor will be evaluated and all of it contents will be unevaluated.
在内部,Map
类型是使用严格的树实现的。要么评估整个树脊,要么评估它的 none。这是库代码的片段:
data Map k a = Bin {-# UNPACK #-} !Size !k a !(Map k a) !(Map k a)
| Tip
严格性注释 (!
) 防止将未计算的值存储为子树。因此,如果我们将 Map k a
值评估为弱头部范式,我们实际上会完全评估树脊。
Map.insert
中的 Map
不是地图构造函数。它是一个模块名称。函数 insert :: Ord k => k -> a -> Map k a -> Map k a
is called here. Its result will get evaluated to WHNF before return ()
is calculated as the next computational step in the combined IO action, thanks to the call to seq
. You can consult the source of insert
了解详情。它会通过爆炸模式等进行大量强制操作。
Simon Marlow 在他的书“Haskell 中的并行和并发编程”中写道:
The insert operation hadthis line:
putMVar m (Map.insert name number book)
This places in the MVar the unevaluated expression
Map.insert name number book
. If we were to do many insert operations consecutively, the MVar would build up a large chain of unevaluated expressions. To get brief locking and no space leaks, we need to use a trick:let book' = Map.insert name number book putMVar m book' seq book' (return ())
With this sequence, we’re storing an unevaluated expression in the MVar, but it is evaluated immediately after the putMVar.
我不明白。 seq a b
运算以弱头范式计算 a
。所以会有unevaluated expression。如我所见,只会评估 Map 构造函数,而不会评估其所有内容。
As I can see only the
Map
constructor will be evaluated and all of it contents will be unevaluated.
在内部,Map
类型是使用严格的树实现的。要么评估整个树脊,要么评估它的 none。这是库代码的片段:
data Map k a = Bin {-# UNPACK #-} !Size !k a !(Map k a) !(Map k a)
| Tip
严格性注释 (!
) 防止将未计算的值存储为子树。因此,如果我们将 Map k a
值评估为弱头部范式,我们实际上会完全评估树脊。
Map.insert
中的 Map
不是地图构造函数。它是一个模块名称。函数 insert :: Ord k => k -> a -> Map k a -> Map k a
is called here. Its result will get evaluated to WHNF before return ()
is calculated as the next computational step in the combined IO action, thanks to the call to seq
. You can consult the source of insert
了解详情。它会通过爆炸模式等进行大量强制操作。