Question

[<EntryPoint>]
let main argv = 
    let linshi1 = [|1,2|]
    let linshi2 = Array.append linshi1 [|2,3|]
    let map1 = Map.ofArray linshi2
    let mutable it = 1
    while it = 1 do 
        it <- it - 1
        let map2 = map1.Add(3,4)
        let map1 = map2
        printfn "!\n"
    printfn "done"
    0

this is my test code. I am trying to update the "map1" in the while loop but the result shows that I failed. So how can I achieve this function? I really need updating a map during reading a Excel file. Thanks in advance.

Was it helpful?

Solution

Firstly, you cannot "update" F# map as it is immutable data structure, i.e. adding to a map produces another map. It is not clear how you are going to align reading your Excel with updating a map, but you can always do something like

let mutable myMap = ...
......
myMap <- (x,y) ||> Map.add <| myMap

which creates a new map instance off the old one and then points the original reference to new contents discarding the previous one.

Secondly, when you use while expression it creates a new scope so your let map1=... shadows "original" map1 outside the while. This "internal" map1 in turn gets discarded when control is getting back outside of while. That's why your manipulations inside while do not anyhow affect your "original" map1. See FSharp Programming/Basic Concepts for details of scoping and shadowing.

Summing up, you do not need any while loop; just convert your snippet to something like the snippet below, where instead of making map1 mutable it is simply redefined. This is allowed inside functions, and main is a function, indeed:

[<EntryPoint>]
let main argv = 
    let linshi1 = [|1,2|]
    let linshi2 = Array.append linshi1 [|2,3|]
    let map1 = Map.ofArray linshi2
    let map1 = (3,4) ||> Map.add <| map1
    printfn "%A" map1
    0

which being executed will output map [(1, 2); (2, 3); (3, 4)] as expected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top