I am choosing to learn F# for my own enjoyment. I am getting to the point where concepts of F# seem to be pretty easy, but understanding some of the whys and whens is a bit harder.Before I get into the code and the explanation, let me put my question up front. I am asking where can I find better advice on formatting F# code for readability? Or can someone give me a few guiding tips based off of the example given below?So what are the best practices for code format and file layout?Now to the explanation of the code.I have started practicing coding Kata's in F# just to allow me to flex the language a little.  The following program is an implementation of a natural sort. This was my first attempt to solving the problem in a TDD fashion in F#, as such I chose to forgo any framework as I did not want to deal with figuring out how to use any of them and not break the functional paradigm.So the code below carries a light weight unit test framework.Here is the code for the natural sort:namespace Katas    open System.Linq    module NaturalSortKata =        exception InvalidException of string        type Comparison =        | Equal        | Lesser        | Greater            static member Compare x y =                if x = y then                    Equal                elif x > y then                    Greater                else                    Lesser        type ChunckType =        | NumberType        | StringType        | Unknown            static member GetType (c : char) =                if System.Char.IsDigit(c) then                    NumberType                else                    StringType            member this.Compare other =                 match other with                | ty when ty = this -> Equal                | Unknown -> Lesser                | NumberType when this = Unknown -> Greater                | NumberType -> Lesser                | StringType -> Greater        let natualCompare (left : string) (right : string) =             if left = right then                Equal            else                let fix str =                    new System.String( str |> List.rev |> List.toArray )                let gatherChunck str =                     let rec gather str acc =                        match str with                        | [] ->                            let (ty, l) = acc                            (ty, fix(l))                        | fistLetter::rest ->                            match acc with                            | (ty, _) when ty = Unknown ->                                let t = ChunckType.GetType(fistLetter)                                gather rest (t, fistLetter :: [])                            | (ty, l) when ty = ChunckType.GetType(fistLetter) ->                                gather rest (ty, fistLetter::l)                            | (ty, l) -> (ty, fix(l))                    gather str (Unknown, [])                let rec compare (left : string) (right : string) =                    if (not (left.Any())) || (not (right.Any())) then                        match left.Length, right.Length with                        | llen, rlen when llen = rlen -> Equal                        | llen, rlen when llen > rlen -> Greater                        | llen, rlen when llen < rlen -> Lesser                        | _ -> raise (InvalidException Bad Data)                    else                        let lt, lChunk = left |> Seq.toList |> gatherChunck                         let rt, rChunk = right |> Seq.toList |> gatherChunck                        match lt.Compare rt with                        | Equal ->                            if lChunk = rChunk then                                let lVal = left.Replace(lChunk, )                                let rVal = right.Replace(rChunk, )                                compare lVal rVal                            else                                match lt with                                | NumberType ->                                    Comparison.Compare (System.Int64.Parse(lChunk)) (System.Int64.Parse(rChunk))                                | _ ->                                    Comparison.Compare lChunk rChunk                        | _ ->                            lt.Compare(rt)                compare left rightHere is the code for the tests:namespace Katas.Testing    open Katas.NaturalSortKata    module Tests =        let test left right expected title=            let testRun x =                  let result = right |> natualCompare left                if result = expected then                    x |> printfn %d good                    true                else                    title +  fails |> printfn %d %s x                    result                     |> sprintf %d            Actual: %A x                     |> sprintf %d            Expected: %A\r\n%s x expected                    |> printfn %s                    false            testRun        let testRunner tests=            let rec runner x result tests =                match tests with                | [] -> result                | head::tests ->                     let current = (head x) && result                    tests |> runner (x + 1) current            tests |> runner 1 true        let test01 = Simple Equality                           |> test one               one               Equal        let test02 = left < right                              |> test left              right             Lesser        let test03 = beta > alpha                              |> test beta              alpha             Greater        let test04 = \9\ < \10\                            |> test 9                 10                Lesser        let test05 = \alpha9\ < \alpha10\                  |> test alpha9            alpha10           Lesser        let test06 = \alpha9Centary9\ < \alpha9Centary10\  |> test alpha9Centary9    alpha9Centary10   Lesser        let test07 = \10\ > \9\                            |> test 10                 9                Greater        let test08 = \alpha10\ > \alpha9\                  |> test alpha10            alpha9           Greater        let test09 = \alpha9Centary9\ < \alpha9Centary10\  |> test alpha9Centary10    alpha9Centary9   Greater        let tests = test01 :: test02 :: test03 :: test04 :: test05 :: test06 :: test07 :: test08 :: test09 ::[]        let runTests =                    tests |> testRunner |> printfn %bHere is the code that runs it all:open Katas.NaturalSortKataopen Katas.Testing.Tests[<EntryPoint>]let main argv =     //Katas.Lockers.showLockerResults 300    runTests    let _ = System.Console.ReadKey(true)    1
Kata: Natural Sort
unit testing;f#
Your code formatting is very readable. The minor issue is that you don't have to indent after namespace declaration. I would choose to open module directly to save a level of indentation (see attached code later).So what are the best practices for code format and file layout?I think F# code formatting guidelines have very concrete suggestions on these issues.There are a few small problems with your code:In naturalCompare, you should move local functions to the top so the logic of the function is clear.In compare, if you remove when in the last clause, you don't have to superficially throw an exception.Value tests is more readable in the form of normal list declaration.let tests = [ test01; test02; test03; test04; test05; test06; test07; test08; test09; ]Here is reformatted version of Katas.NaturalSortKata module. You could do the same for Katas.Testing.Tests.// 0) Declare module to save a level of indentationmodule Katas.NaturalSortKataopen System.Linqtype Comparison =| Equal| Lesser| Greater    static member Compare x y =        if x = y then            Equal        elif x > y then            Greater        else            Lessertype ChunckType =| NumberType| StringType| Unknown    static member GetType (c : char) =        if System.Char.IsDigit(c) then            NumberType        else            StringType    member this.Compare other =         match other with        | ty when ty = this -> Equal        | Unknown -> Lesser        | NumberType when this = Unknown -> Greater        | NumberType -> Lesser        | StringType -> Greaterlet naturalCompare (left : string) (right : string) =     // 1) Move local functions on top    let fix str =        new System.String( str |> List.rev |> List.toArray )    let gatherChunck str =         let rec gather str acc =            match str with            | [] ->                let (ty, l) = acc                (ty, fix(l))            | fistLetter::rest ->                match acc with                | (ty, _) when ty = Unknown ->                    let t = ChunckType.GetType(fistLetter)                    gather rest (t, fistLetter :: [])                | (ty, l) when ty = ChunckType.GetType(fistLetter) ->                    gather rest (ty, fistLetter::l)                | (ty, l) -> (ty, fix(l))        gather str (Unknown, [])    let rec compare (left : string) (right : string) =        if (not (left.Any())) || (not (right.Any())) then            match left.Length, right.Length with            | llen, rlen when llen = rlen -> Equal            | llen, rlen when llen > rlen -> Greater            | llen, rlen -> Lesser // 2) Remove superficial when guard        else            let lt, lChunk = left |> Seq.toList |> gatherChunck             let rt, rChunk = right |> Seq.toList |> gatherChunck            match lt.Compare rt with            | Equal ->                if lChunk = rChunk then                    let lVal = left.Replace(lChunk, )                    let rVal = right.Replace(rChunk, )                    compare lVal rVal                else                    match lt with                    | NumberType ->                        Comparison.Compare (System.Int64.Parse(lChunk)) (System.Int64.Parse(rChunk))                    | _ ->                        Comparison.Compare lChunk rChunk            | _ ->                lt.Compare(rt)    if left = right then        Equal    else        compare left rightUPDATE:After answering your question, I started developing a source code formatter for F#. More information can be found on Gihub.Results from the tool or its companion formatting guideline can give you some hints for good formatting.  