2011-07-15 6 views
2

を使用して、以下のコードを考えてみましょう:'オプション<unit->ユニット>タイプと平等' のF#

let fnOption = Some (fun() ->()) 
fnOption = None 

それは次のエラーを与える:

init.fsx(2,1): error FS0001: The type '(unit -> unit)' does not support the 'equality' constraint because it is a function type

それはなぜですか?私は何か見落としましたか?

+0

ファンクションはFPのファーストクラスの値ですが、それらが渡されるパラメータに基づいて他の値を生成する意味で特別な型の値であるため、2つのファンクションを比較することは意味がありません。結果は関数のための等価演算子が定義されていません – Ankur

答えて

2

本当に等価性をチェックしたい(値を割り当てない)場合は、Option.isNone fnOptionを使用できます。あなたが本当に割り当てたいのであれば、kvbの答えを見てください。

+0

それは本当です。私はこの機能に気付かなかった。それで、F#が構造的平等を試みることを意味しますか?しかし、再びそれはすぐにいくつかのXXX <>なしを見ることができ、何が内部にあるかを確認する必要もなかった。 –

+3

エラーは実行時ではなくコンパイル時に発生します。 F#コンパイラ**はコードをコンパイルしようとしますが、 '型 '(ユニット - >ユニット)は'等価 '制約をサポートしていないため失敗します。動的言語(事前コンパイル・タイプ・チェックなし)では、構造上の等価性で機能していた可能性があります。 –

+0

今私は理解する。説明をありがとう –

2

あなたがしようとしていることは不明です。現状では、2行目はの同等性テストであり、の割り当てではありません。 、あなたが本当に平等をテストしようとしている場合は、あなたが見ているエラーが予想される結果である

let mutable fnOption = Some(fun() ->()) 
fnOption <- None 

ので:何をすることを意図することは、あなたがそれを可変にする必要があり、fnOptionに新しい値を代入した場合関数は比較できません。

+0

関数は比較できませんが、オプションは正しいですか?私はできます: 'let a = Some 4; a = None' –

+0

Some(fun() - >())の代わりにsome idを使用できますか? – Alex

+2

@Alex - いいえ、関数型の値は比較できないので、関数を含むオプションも(実際の値とは無関係に)どちらもありません。コンパイラがオプション値を "内部で"調べないので、 'None((unit - > unit)オプション)= None'もコンパイルされません。値を比較できるかどうかの判断は、そのタイプに基づいてのみ行われます。 – kvb

関連する問題