2

このコードが一連の型のメンバー変数を変更しない理由が完全にわかりません。

for p in prescrs do
    p.ATC <- "A"
    for c in p.Drug.Components do
        for s in c.Substances do
                s.DoseTotal.Adjust <- adjustKg
                s.DoseTotal.Time <- "DAY"
                s.DoseTotal.Unit <- s.DrugConcentration.Unit
                s.DoseRate.Adjust <- adjustKg
                s.DoseRate.Time <- "DAY"
                s.DoseRate.Unit <- s.DrugConcentration.Unit

prescrs は、メンバー値を持つタイプとして定義された非常に単純な「POCO」である処方のシーケンスです。これがうまくいかない理由がわかりません。

次のような簡単なテストケースを試しました:

type IterTest () =
    member val Name = "" with get, set
    member val IterTests = [] |> List.toSeq : IterTest seq with get, set

let iterseq = 
    [
        new IterTest(Name = "Test1")
        new IterTest(Name = "Test2")
    ] 
    |> List.toSeq

iterseq |> Seq.iter(fun x -> x.IterTests <- iterseq)
iterseq |> Seq.iter(fun x -> 
    x.IterTests
    |> Seq.iter(fun x' -> x'.Name <- "itered"))

しかし、ここでの結果は予想どおりです。それで、私の問題を完全に再現することさえできませんか???

解決策を見つけました(上記の問題を本当に理解していません)。最初に prescrs シーケンスを次のようなリストに変換すると:

let prescrs = prescrs |> Seq.toList

次に、命令型ループを実行すると、プロパティが変更されます。

4

1 に答える 1

4

このサンプルを試してください:

type Mutable() = 
    member val Iterated = false with get, set

let muts = Seq.init 5 (fun _ -> printfn "init"; Mutable())

let muts2 = muts // try again with let muts2 = muts |> List.ofSeq

printfn "Before iter"

for a in muts2 do
    printfn "iter"    
    a.Iterated <- true 

printfn "After iter" 

muts2 |> List.ofSeq

iterinitがどのようにインターリーブされているかを確認します。

Seqs遅延していますが、一度計算されるとキャッシュされません。したがって、prescrsシーケンス内のいくつかの要素を強制的に変更しようとしても、もう一度引っ張るとすべて消えてしまいますprescrs。突然変異を行う前に list のような具体的なコレクション型に変更prescrsすると、同じ問題は発生しなくなります。seq 内の seq 内に seq がある場合、事態はさらに複雑になる可能性があることに注意してください。

ただし、最初から突然変異を避けるのが最善の考えです。

于 2014-12-02T01:14:24.983 に答える