Я пытаюсь суммировать дерево, используя параллельную библиотеку задач, где дочерние задачи порождаются только до тех пор, пока дерево не пройдет до определенной глубины, и в противном случае оно суммирует оставшиеся дочерние узлы, используя стиль продолжения, чтобы избежать переполнения стека.Как объединить монады состояний и продолжения в F #
Однако код выглядит довольно уродливым - было бы неплохо использовать государственную монаду, чтобы нести текущую глубину, но государственная монада не является хвостовой рекурсивной. В качестве альтернативы, как мне изменить монаду продолжения, чтобы нести вокруг государства? Или создать комбинацию состояний и продолжения монад?
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
Это странное сочетание. Вы распараллеливаете производительность, но используете стиль продолжения прохождения, который очень неэффективен. –