我正在嘗試使用任務並行庫來對樹進行求和,其中子任務僅在樹遍歷到特定深度之前產生,否則它將使用剩餘的子節點進行求和延續傳遞風格,避免堆棧溢出。如何在F中組合狀態單元和連續單元#
但是,代碼看起來非常難看 - 使用狀態monad來攜帶當前深度會很好,但狀態monad不是尾遞歸。或者,我將如何修改繼續monad以攜帶狀態?或者創建一個狀態和延續monads的組合?
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
這是一個奇怪的組合。你爲了性能而並行化,但是使用延續傳遞風格是非常低效的。 –