Detecting properly nested parenthesis using functional programming So I have this code that is my attempt at a coding test from Codility. While my code produces correct results according to the requirements, (which unfortunately are copyrighted so I don't think I can reproduce them here), but I feel like it could be better organized, and in some places use a more functional approach to solving the problem.

So the basic idea is that it tests if the string if its properly nested parenthesis, or can be split into 2 halves which are properly nested.

let rec isNested (s : System.String) = 
    let s = s.ToCharArray()
    let s = List.ofArray s
    match s with
    | [] -&gt; true //if its empty then its properly nested
    | _ -&gt; 
        match s.Length % 2 with
        //if its even split the list in to 2 halves and test them
        | 0 -&gt; //test form VW

            let len = s.Length
            let half = len / 2
            let mutable firsthalf = []
            let mutable secondhalf = []
            for i in 0..half - 1 do
                firsthalf &lt;- s.[i] :: firsthalf
            for i in half..len - 1 do
                secondhalf &lt;- s.[i] :: secondhalf
            firsthalf &lt;- List.rev firsthalf 
            secondhalf &lt;- List.rev secondhalf
            let VWtest = 
                isNested (new string(Array.ofList (firsthalf))) &amp;&amp; isNested (new string(Array.ofList (secondhalf)))
            match VWtest with
            | true -&gt; true
            | false -&gt; 
                match (s.[0], s.[s.Length - 1]) with
                | ('(', ')') -&gt; 
                  //remove the first and last elements  
                    let sublist = 
                        s.Tail
                        |&gt; List.rev
                        |&gt; List.tail
                        |&gt; List.rev 
                    isNested (new string(Array.ofList (sublist)))
                | _ -&gt; false
        | _ -&gt; false //not a string with an even number of chars therefore can't be properly nested

let test = isNested &gt;&gt; Console.WriteLine
//let expect (b : bool) = Console.WriteLine(" expected ", b)
test "()"     // expect true
test ")("     // expect false
test "(())"   // expect true
test "()()"   // expect true
test "()(()"  // expect false
test "(()())" // expect true
The algorithm is overly complicated, and incorrect: for example, it will fail on the input (())().


  I feel like it could ... use a more functional approach to solving the problem.


There is a more functional approach, maintaining a count of how many parentheses are open.

Let's start with the function signature

let rec isNested' (parens : char list) (openParens : int) : bool =


And fill in the cases. If there are no parentheses left to process, and no open parentheses, they are properly nested.

    match parens, openParens with
    | [], 0 -&gt; true


If we are processing a (, we increase the open parentheses count

    | '(' :: rest, _ -&gt; isNested' rest (openParens + 1)


I'll leave the other two cases up to you.

For convenience, we add a wrapper for this function

let isNested (parens : string) = isNested' (List.ofSeq parens) 0