【发布时间】:2012-06-29 08:09:09
【问题描述】:
我正在尝试使用任务并行库对树求和,其中子任务仅在树被遍历到一定深度之前生成,否则它使用连续传递样式对剩余的子节点求和,以避免堆栈溢出。
但是,代码看起来很丑 - 使用 state monad 来携带当前深度会很好,但 state monad 不是尾递归的。或者,我将如何修改延续单子以携带状态?或者创建状态和延续单子的组合?
let sumTreeParallelDepthCont tree cont =
let rec sumRec tree depth cont =
let newDepth = depth - 1
match tree with
| Leaf(num) -> cont num
| Branch(left, right) ->
if depth <= 0 then
sumTreeContMonad left (fun leftM ->
sumTreeContMonad right (fun rightM ->
cont (leftM + rightM )))
else
let leftTask = Task.Factory.StartNew(fun () ->
let leftResult = ref 0
sumRec left newDepth (fun leftM ->
leftResult := leftM)
!leftResult
)
let rightTask = Task.Factory.StartNew(fun () ->
let rightResult = ref 0
sumRec right newDepth (fun rightM ->
rightResult := rightM)
!rightResult
)
cont (leftTask.Result + rightTask.Result)
sumRec tree 4 cont // 4 levels deep
我在这篇博文中有更多详细信息:http://taumuon-jabuka.blogspot.co.uk/2012/06/more-playing-with-monads.html
【问题讨论】:
-
这是一个奇怪的组合。您正在并行化以提高性能,但使用效率非常低的延续传递样式。
标签: f# state monads monad-transformers continuation