F# Program to Implement Merge Sort

F# Program to Implement Merge Sort

Sorting is one of the most common tasks in programming, and it becomes especially important when working with large amounts of data. When data is sorted, programs run faster, searches become easier, and results look cleaner. Merge Sort is a popular and powerful sorting algorithm because it is fast and reliable, even when the data grows very large.

Pluralsight Logo
Accelerate your tech career
with hands-on learning.
Whether you're a tech newbie or a total pro,
get the skills and confidence to land your next move.
Start 10-Day Free Trial

Merge Sort follows a simple idea. It breaks the data into smaller pieces, sorts those pieces, and then merges them back together in the correct order. This approach is known as divide and conquer. In this article, you will learn how to write an F# program to implement Merge Sort using different approaches. Each program is written in a beginner-friendly way so you can understand not just the code, but also the thinking behind it.

Program 1: Merge Sort Using Basic Recursion with Lists

This program shows the classic Merge Sort using recursion and lists. It is the most common way to explain Merge Sort and fits very well with the functional style of F#.

open System

let rec merge left right =

    match left, right with
    | [], r -> r
    | l, [] -> l
    | h1::t1, h2::t2 ->
        if h1 <= h2 then h1 :: merge t1 right
        else h2 :: merge left t2


let rec mergeSort list =

    match list with
    | [] -> []
    | [x] -> [x]
    | _ ->
        let mid = list.Length / 2
        let left = list |> List.take mid
        let right = list |> List.skip mid

        merge (mergeSort left) (mergeSort right)


[<EntryPoint>]
let main argv =

    let numbers = [38; 27; 43; 3; 9; 82; 10]
    let result = mergeSort numbers

    printfn "Sorted list:"
    result |> List.iter (printf "%d ")

    0

This program works by repeatedly splitting the list until only single values remain. Then it merges those values back together in sorted order. Beginners can understand this by thinking of it as breaking a big problem into small easy problems and solving them one by one.

Program 2: Merge Sort Using Arrays and Recursion

This program uses arrays instead of lists, which may feel more familiar to beginners coming from other languages.

open System

let merge (arr:int[]) left mid right =

    let n1 = mid - left + 1
    let n2 = right - mid
    let L = arr.[left .. mid]
    let R = arr.[mid + 1 .. right]

    let mutable i = 0
    let mutable j = 0
    let mutable k = left

    while i < n1 && j < n2 do

        if L.[i] <= R.[j] then
            arr.[k] <- L.[i]
            i <- i + 1
        else
            arr.[k] <- R.[j]
            j <- j + 1

        k <- k + 1


    while i < n1 do

        arr.[k] <- L.[i]
        i <- i + 1
        k <- k + 1


    while j < n2 do

        arr.[k] <- R.[j]
        j <- j + 1
        k <- k + 1


let rec mergeSort (arr:int[]) left right =

    if left < right then

        let mid = (left + right) / 2
        mergeSort arr left mid
        mergeSort arr (mid + 1) right
        merge arr left mid right


[<EntryPoint>]
let main argv =

    let numbers = [| 12; 11; 13; 5; 6; 7 |]
    mergeSort numbers 0 (numbers.Length - 1)

    printfn "Sorted array:"
    numbers |> Array.iter (printf "%d ")

    0

This version keeps the same Merge Sort logic but uses arrays and index values. It is useful for beginners who want to see how Merge Sort works in a more traditional style. It also helps in understanding how memory and indexes are managed.

Program 3: Merge Sort Using Tail Recursion Style

This program focuses on clean functional thinking by keeping the logic clear and readable.

open System

let rec merge left right =

    match left, right with
    | [], r -> r
    | l, [] -> l
    | x::xs, y::ys ->
        if x < y then x :: merge xs right
        else y :: merge left ys


let rec mergeSort list =

    if List.length list <= 1 then list
    else
        let left, right = List.splitAt (List.length list / 2) list
        merge (mergeSort left) (mergeSort right)


[<EntryPoint>]
let main argv =

    let numbers = [15; 5; 24; 8; 1; 3]
    let sorted = mergeSort numbers

    printfn "Sorted list:"
    sorted |> List.iter (printf "%d ")

    0

This approach is very beginner-friendly because the code reads almost like plain English. It clearly shows how data is split and merged. Beginners can focus on understanding the idea rather than worrying about complex details.

Program 4: Merge Sort with Helper Functions

This program separates responsibilities into small helper functions, making the logic easier to follow.

open System

let split list =

    let mid = List.length list / 2
    List.take mid list, List.skip mid list


let rec merge left right =

    match left, right with
    | [], r -> r
    | l, [] -> l
    | x::xs, y::ys ->
        if x <= y then x :: merge xs right
        else y :: merge left ys


let rec mergeSort list =

    match list with
    | [] | [_] -> list
    | _ ->
        let left, right = split list
        merge (mergeSort left) (mergeSort right)


[<EntryPoint>]
let main argv =

    let numbers = [19; 14; 7; 2; 11; 6]
    let result = mergeSort numbers

    printfn "Sorted list:"
    result |> List.iter (printf "%d ")

    0

This version is useful because each function has one clear job. Beginners can understand the full process by reading one small part at a time. This style also helps when writing larger programs.

Program 5: Generic Merge Sort in F

This program shows how Merge Sort can work with any comparable type, not just numbers.

open System

let rec mergeGeneric left right =

    match left, right with
    | [], r -> r
    | l, [] -> l
    | x::xs, y::ys ->
        if x <= y then x :: mergeGeneric xs right
        else y :: mergeGeneric left ys


let rec mergeSortGeneric list =

    match list with
    | [] | [_] -> list
    | _ ->
        let mid = List.length list / 2
        let left = list |> List.take mid
        let right = list |> List.skip mid

        mergeGeneric (mergeSortGeneric left) (mergeSortGeneric right)


[<EntryPoint>]
let main argv =

    let numbers = [42; 17; 8; 99; 23]
    let sorted = mergeSortGeneric numbers

    printfn "Sorted list:"
    sorted |> List.iter (printf "%d ")

    0

This program is powerful because it shows how one Merge Sort function can be reused. Beginners can see how F# supports flexible and clean code while keeping the algorithm simple.

Frequently Asked Questions (FAQ)

This section answers common beginner questions about Merge Sort in a simple and clear way.

Q1. Why is Merge Sort faster than simple sorts?
Merge Sort divides data into smaller parts, which makes sorting faster and more efficient, especially for large datasets.

Q2. Is Merge Sort used in real applications?
Yes, Merge Sort is widely used in real systems because it is reliable and performs well even with large data.

Q3. Is Merge Sort difficult for beginners?
The idea may feel new at first, but once you understand splitting and merging, it becomes very easy to follow.

Q4. Does Merge Sort always use recursion?
Most implementations use recursion, but the core idea can also be adapted to other styles.

Q5. Should beginners practice Merge Sort after simple sorts?
Yes, learning Merge Sort after simpler algorithms helps build strong problem-solving skills.

Conclusion

Merge Sort is an important sorting algorithm that every beginner should understand. In this article, we explored several F# programs that implement Merge Sort using lists, arrays, recursion, helper functions, and generic logic. Each example showed the same core idea in a slightly different way, making learning easier.

The best way to master Merge Sort is to practice the code, change the input values, and trace how the data moves. With regular practice, Merge Sort will feel natural, and it will prepare you for even more advanced algorithms in F#.

Scroll to Top