Sorting By Functions in F#

Our example demonstrates how to implement custom sorting in F#. We’ll sort strings by their length and custom objects by a specific field.

open System

// Define a Person record type
type Person = { Name: string; Age: int }

let main() =
    let fruits = ["peach"; "banana"; "kiwi"]

    // We implement a comparison function for string lengths
    let lenCmp (a: string) (b: string) = 
        compare a.Length b.Length

    // Now we can use List.sortWith with this custom comparison function
    // to sort fruits by name length
    let sortedFruits = List.sortWith lenCmp fruits
    printfn "%A" sortedFruits

    // We can use the same technique to sort a list of custom types
    let people = [
        { Name = "Jax"; Age = 37 }
        { Name = "TJ"; Age = 25 }
        { Name = "Alex"; Age = 72 }
    ]

    // Sort people by age using List.sortWith
    let sortedPeople = List.sortWith (fun a b -> compare a.Age b.Age) people
    printfn "%A" sortedPeople

main()

To run the program, save it as sorting_by_functions.fsx and use the F# interactive or compile and run it:

$ dotnet fsi sorting_by_functions.fsx
[|"kiwi"; "peach"; "banana"|]
[|{ Name = "TJ"; Age = 25 }; { Name = "Jax"; Age = 37 }; { Name = "Alex"; Age = 72 }|]

In this F# version:

  1. We define a Person record type to represent our custom object.

  2. The lenCmp function is defined to compare string lengths, similar to the Go version.

  3. We use List.sortWith instead of slices.SortFunc. This function takes a comparison function and a list, and returns a new sorted list.

  4. For sorting the list of Person records, we use an inline comparison function with List.sortWith.

  5. The printfn function is used for output, which is similar to fmt.Println in Go.

Note that F# lists are immutable, so List.sortWith returns a new sorted list rather than modifying the original list in place. This is a key difference from the Go version, which modifies the slice in place.

Also, F# has built-in support for records, which we use instead of Go’s struct type. This makes our Person type more idiomatic to F#.