2017-04-27 61 views
1

處理需要可變集的程序。當試圖把集閉包我得到一個錯誤:F#從可變更改爲參考

let mutable donefiles : Set<FileRecord> = Set.empty 
let filestodo = Set.difference parms.FileSpecs donefiles 
let errorFile (file: FileRecord) = 
    donefiles <- Set.add file donefiles 

Error 40 The mutable variable 'donefiles' is used in an invalid way. Mutable variables cannot be captured by closures. Consider eliminating this use of mutation or using a heap-allocated mutable reference cell via 'ref' and '!'.

試圖「donefiles」轉換爲參考,但似乎無法得到正確的語法。嘗試了明顯的(對我)第一次:

let donefiles : Set<FileRecord> = ref Set.empty 

但:

Error 40 This expression was expected to have type Set but here has type 'a ref

什麼是語法,我應該在這種情況下使用?

+5

取而代之的是可變引用的一個不可改變的集合,你可以使用一個可變的'HashSet '? – Lee

+0

看來HashSet沒有差異函數。 – user1443098

+2

您可以使用'.ExceptWith'從'HashSet '中移除一組物品。 – Lee

回答

4

首先,似乎你使用的是舊版本的F#。限制可變變量was lifted in F# 4.0

但如果你不能切換到新的版本,這裏的答案的實際問題:

功能ref需要一個值,並返回一個可變的細胞。這種單元格的類型是'a ref,其中'a是值的類型。

所以你的情況,該ref函數返回Set<FileRecord> ref,但你特別註釋donefiles有型Set<FileRecord>,所以有衝突(這是編譯器告訴你)。

簡單地調整你的類型的註釋,它會工作:

let donefiles : Set<FileRecord> ref = ref Set.empty 

變異一個引用單元格,使用:=操作:

donefiles := Set.add file !donefiles 
+0

它幾乎奏效!隨着你的改變(謝謝!)變量聲明工作,但閉包定義沒有:我得到錯誤「值不可變」。我試過'donefiles < - Set.add文件donefiles'。然後我嘗試了'!donefiles < - Set.add文件donefiles'並得到了「賦值左邊的無效表達式」。 – user1443098

+0

我已經更新了答案。 –

+0

'donefiles:= Set.add文件!donefiles'工作(不得不取消var) – user1443098