How can this functional implementation of Kadane's algorithm be improved? Some time ago I posted on Stack Overflow an imperative C# implementation of Kadane's algorithm for finding a subarray with maximum sum. Then I considered implementing the same functionally in F# and came up with the following:

let kadanes (xs: int []) =
    xs
    |&gt; Array.mapi (fun i x -&gt; (x, i))
    |&gt; Array.fold (fun (partSum, partIdx, maxSum, startIdx, endIdx) (x, i) -&gt;
                        let newPartSum, newPartIdx =
                            if partSum + x &gt; x then (partSum + x, partIdx) else (x, i)
                        if newPartSum &gt; maxSum then
                            (newPartSum, newPartIdx, newPartSum, newPartIdx, i)
                        else (newPartSum, newPartIdx, maxSum, startIdx, endIdx))
                        (0,0,xs.[0],0,0)
    |&gt; fun (_, _, maxSum, startIdx, endIdx) -&gt; (maxSum, startIdx, endIdx)


While the implementation above is functional and correct I cannot consider it easily understandable; in particular, dragging tuple of 5 elements through the fold seems rather ugly.

What can be done for improving this F# code?

Thank you.
A recursive function often works well in place of fold.

let kadanes xs =
  let rec loop (partSum, partIdx, maxSum, startIdx, endIdx) i =
    if i &lt; Array.length xs then 
      let x = xs.[i]
      let newPartSum, newPartIdx =
        if partSum + x &gt; x then (partSum + x, partIdx) else (x, i)
      let maxSum, startIdx, endIdx =
        if newPartSum &gt; maxSum then (newPartSum, newPartIdx, i)
        else (maxSum, startIdx, endIdx)
      loop (newPartSum, newPartIdx, maxSum, startIdx, endIdx) (i + 1)
    else (maxSum, startIdx, endIdx)
  loop (0,0,xs.[0],0,0) 0