次のコードを検討してください。
let mutable a = 0.
let b = ref 0.
a <- // works
printfn "%A" a
4. + 8.
b := // does not work
printfn "%A" a
4. + 8.
b := ( // works
printfn "%A" a
4. + 8. )
ref 代入演算子 (:=) が可変代入演算子 (<-) と異なる動作をするのはなぜですか?
次のコードを検討してください。
let mutable a = 0.
let b = ref 0.
a <- // works
printfn "%A" a
4. + 8.
b := // does not work
printfn "%A" a
4. + 8.
b := ( // works
printfn "%A" a
4. + 8. )
ref 代入演算子 (:=) が可変代入演算子 (<-) と異なる動作をするのはなぜですか?
部分的な回答しかできません。
:=<-FSharp.Core\prim-types.fs で次のように定義されています。
let (:=) x y = x.contents <- y
あなたの例では
b := // does not work
printfn "%A" a
4. + 8.
printfn "%A" ayint ref セル (間違った型) に割り当てることができないとして解釈されるようです。式全体を でグループ化することにより( ... )、yも含まれるようになり4. + 8.ました。2 つの演算子の動作が異なる<-可能性があります。これは、組み込み演算子 (つまり、ライブラリではなく言語の一部) のように思われるためです。
他の答えに基づいて...
最終的な式がいくつかの許可された形式の1つである限り、より複雑な式が割り当て内で許可されます。仕様のセクション6.4.9を参照してください。これにより、次のような複雑な割り当てが可能になります。
let x =
let rec gcd a = function
| 0 -> a
| b -> gcd b (a % b)
gcd 10 25
コンパイラーはgcdプライベートメンバーに移動しますが、割り当て内にネストすると、より厳密なスコープが可能になります。一方、関数の引数はより制限されています。それらは(私が知っている)新しいスコープを作成せず、たとえば式の一部として関数を定義することはできません。
:=タイプを持つ関数(FSIではtry(:=);;)です:'a ref -> 'a -> unit
そう
b := // does not work
printfn "%A" a
4. + 8.
は、中置呼び出しの解析規則により、次のように解析されています。
(:=) b (printfn "%A" a)
4. + 8.
(:=) 関数タイプとしては無効です。その他の例:
let c = 10 +
11
12
ここで c は 12 になります
これらの演算子に特に関係するものではなく、インデントに敏感なパーサーの不一致のように見えます。