2017-04-27 12 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

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

が参照セルを変異させるために、:=演算子を使用します変更可能な 'HashSet '? – Lee

+0

HashSetには差分機能がないようです。 – user1443098

+2

'.ExceptWith'を使うと' HashSet 'からアイテムのコレクションを削除できます。 – Lee

答えて

4

まず第1にさん、あなたは古いバージョンのF#を使用しているようです。可変変数のこの制限はwas lifted in F# 4.0です。

しかし、あなたは新しいバージョンに切り替えることができない場合には、ここで実際の質問への答えです:値をとり、変更可能なセルを返しref

機能が。そのようなセルのタイプは'a refです。ここで、'aが値のタイプです。

だからあなたの場合には、ref機能はSet<FileRecord> refを返しますが、あなたは、具体的タイプSet<FileRecord>を持っているdonefilesを注釈付きなので、競合は(これは、コンパイラがあなたを語っているものである)があります。

単にあなたの型注釈を調整し、それが動作します:あなたが使用できる不変のセットに変更可能な参照の代わりに

donefiles := Set.add file !donefiles 
+0

それはほとんど働いた!あなたの変更(ありがとう!)では、変数宣言は機能しましたが、クロージャの定義はそうではありませんでした。私は "値は変更可能ではありません"というエラーを受け取ります。私は 'donefiles < - Set.add file donefiles'を試しました。私は '!donefiles < - Set.add file donefiles 'を試して、「割り当ての左に無効な式があります」を得ました。 – user1443098

+0

私は答えを更新しました。 –

+0

'donefiles:= Set.add file!donefiles'はうまく機能しました(varをderefする必要がありました) – user1443098

関連する問題