2013-12-15 38 views
1
[<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 

這是我的測試代碼。我試圖更新while循環中的「map1」,但結果表明我失敗了。那我該如何實現這個功能呢?我真的需要在閱讀Excel文件時更新地圖。提前致謝。在while循環中更新FSharpMap

回答

4

首先,您不能「更新」F# map,因爲它是不可變的數據結構,即添加到地圖會生成另一個地圖。目前尚不清楚你將如何對齊與更新地圖閱讀您的Excel,但你總是可以做這樣的事情

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

這將創建一個新的地圖實例掉舊的,然後指向原始引用新內容丟棄前一個。

其次,當你使用while表達它創建了一個新的範圍,使您的let map1=...陰影「原始」 map1while之外。當控制回到while之外時,該「內部」map1反過來被丟棄。這就是爲什麼您在while中的操作不會影響您的「原始」map1。有關範圍和陰影的詳細信息,請參見FSharp Programming/Basic Concepts

總結一下,你不需要任何while循環;只需將您的代碼片段轉換爲下面的代碼片段即可,而不是使map1可變,而是簡單地重新定義。這是允許的內部的功能,以及main是一個函數,確實:

其中正在執行將輸出 map [(1, 2); (2, 3); (3, 4)]如預期
[<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 

+0

+1這個答案是絕對正確的。只是一個小點 - 你並不需要改變'map1.Add'到類似'(3,4)||> Map.add <| map1' - I通過說'map1 < - map1.Add(3,4)'來改變地圖是完全正確的(我絕對會喜歡使用奇特的操作符來迷惑敵人:-)) –

+0

@TomasPetricek:感謝您提醒您有時使用類型實例方法可能更喜歡鍵入模塊函數。 –