Refactoring while-do into tail recursion with F# I have a while-do loop nested inside a while-do loop in my program, due to it needing to iterate in two dimensions through an array of arrays, and originally my loop looked like this:

while ( tHeightIndex &lt; tSearchHeight - 1 ) &amp;&amp; tContinue do
    while ( tWidthIndex &lt; tSearchWidth - 1 ) &amp;&amp; tContinue do
        let tCurrentValue = tLargeArray.[tHeightIndex].[tWidthIndex]
        if tCurrentValue = tFirstSmallPixel then
            tMatch &lt;- ArrayFunctions.SearchSubset tSmallArray tLargeArray ( tHeightIndex, tWidthIndex )
            if tMatch then tContinue &lt;- false
        if tMatch = false &amp;&amp; tContinue = true then
            tWidthIndex &lt;- tWidthIndex + 1
    if tMatch = false &amp;&amp; tContinue = true then
        tWidthIndex  &lt;- 0                       // Reset to search next row
        tHeightIndex &lt;- tHeightIndex + 1
tMatch, tWidthIndex, tHeightIndex


However, seeing as I'm doing this project entirely to learn better functional programming practices, I refactored that nested loop into two tail-recursive functions. This code passes my unit tests and appears to work correctly, so I would like advice about the style of the code and whether there's better ways I can make the code read clearly. 

The relevant part to the original while-do loop is located after the declaration of firstSmallPixel.

module ImageSearch = 
    open ImageFunctions

    let SearchBitmap (smallBitmap:Bitmap) (largeBitmap:Bitmap) = 
        let smallArray = Transform2D &lt;| LoadBitmapIntoArray smallBitmap 
        let largeArray = Transform2D &lt;| LoadBitmapIntoArray largeBitmap
        let searchWidth = largeBitmap.Width - smallBitmap.Width
        let searchHeight = largeBitmap.Height - smallBitmap.Height
        let firstSmallPixel = smallArray.[0].[0]

        let WidthLoop heightIndex =
            let rec WidthLoopRec heightIndex widthIndex =
                let ContinueLoop () = WidthLoopRec heightIndex (widthIndex + 1)
                let currentLargePixel = largeArray.[heightIndex].[widthIndex]
                match ( widthIndex &lt; searchWidth , currentLargePixel = firstSmallPixel ) with
                | ( true , true  ) -&gt;  let foundImage = ArrayFunctions.SearchSubset smallArray largeArray ( heightIndex, widthIndex )
                                       if foundImage then widthIndex , foundImage
                                       else ContinueLoop ()
                | ( true , false ) -&gt; ContinueLoop ()
                | ( false, _     ) -&gt; widthIndex , false
            WidthLoopRec heightIndex 0 

        let HeightLoop () =
            let rec HeightLoopRec heightIndex =
                let widthIndex, foundImage = WidthLoop heightIndex
                match ( foundImage, heightIndex &lt; searchHeight ) with
                | ( false , true  ) -&gt; HeightLoopRec ( heightIndex + 1 ) 
                | ( _     , _     ) -&gt; foundImage , widthIndex , heightIndex
            HeightLoopRec 0 

        HeightLoop ()
I think that learning functional programming should be about making your code more readable (and also better in other aspects), neither of your samples seems very readable to me.

I also think that when working with collections in functional programming, the most important concept is not recursion, it's higher-order functions.

If you use those in the form of a query expression, your code could look like this:

query {
    for row in 0..searchHeight do
    for col in 0..searchWidth do
    let pixel = largeArray.[row].[col]
    where (pixel = firstSmallPixel)
    select (row, col, pixel)
    head
}


The nice thing about this code is not only that it's more readable and shorter, it's that it emphasizes what you want to do, not how to do it.