Search code examples
f#functional-programmingmutation

Avoid mutation in this example in F#


Coming from an OO background, I am having trouble wrapping my head around how to solve simple issues with FP when trying to avoid mutation.

let mutable run = true
let player1List = ["he"; "ho"; "ha"]

let addValue lst value =
    value :: lst

while run do
    let input = Console.ReadLine()
    addValue player1List input |> printfn "%A"
    if player1List.Length > 5 then 
        run <- false
        printfn "all done" // daz never gunna happen

I know it is ok to use mutation in certain cases, but I am trying to train myself to avoid mutation as the default. With that said, can someone please show me an example of the above w/o using mutation in F#?

The final result should be that player1List continues to grow until the length of items are 6, then exit and print 'all done'


Solution

  • The easiest way is to use recursion

    open System
    let rec makelist l = 
        match l |> List.length with
        |6  -> printfn "all done"; l
        | _ -> makelist ((Console.ReadLine())::l)
    
    makelist []
    

    I also removed some the addValue function as it is far more idiomatic to just use :: in typical F# code.

    Your original code also has a common problem for new F# coders that you use run = false when you wanted run <- false. In F#, = is always for comparison. The compiler does actually warn about this.