3

では、なぜ F# で > 演算子と ^ 演算子をオーバーロードできるのに、使用できないのか説明してもらえますか?

+ (op_Addition): Works just fine.
^ (op_Concatenate): Compiler error in F#. Apparently only strings can be concatenated.
> (op_GreaterThan): Runtime Error – Failure during generic comparison: the type Program+OppTest4 does not implement the System.IComparable interface.

F# コードをライブラリとしてコンパイルし、VB からそれらの演算子を使用すると、それらはすべて機能します。C# からこれらの演算子を使用すると、op_Concatenate 以外はすべて機能します (期待どおり)。しかし、F# はそれらのいくつかを無視するだけでなく、静的型チェッカーはその計画をユーザーに通知することさえしません。

コードサンプルを編集

type OppTest4(value: int) =
   member this.value = value
   static member (^) (left : OppTest4, right : OppTest4) =
     OppTest4( Int32.Parse( left.value.ToString() ^ right.value.ToString()  ))
   static member (+) (left : OppTest4, right : OppTest4) =
     OppTest4(left.value + right.value )
   static member (>) (left : OppTest4, right : OppTest4) =
     left.value > right.value
   static member (<) (left : OppTest4, right : OppTest4) =
     left.value < right.value
4

2 に答える 2

4

F# には、F# にとって合理的なこれらの演算子記号の既定の意味があります。デフォルトを隠す独自の意味をいつでも定義できます。

let (>) x y = ...

たとえば、この演算子を「T.operator>(U)」を意味するように定義できます (x の型が T で、y の型が U であると仮定します)。

デフォルトの定義については、ソース配布の FSharp.Core の prim-types.fs を参照してください。(それらは自明ではありません!)

(1) CLR で型クラスのようなメカニズム (他の点では無関係な型のセット間で共通のセマンティクスを定義するため) がサポートされていないことと、(2) プリミティブ型 ('int' など) が頻繁に使用されるという事実の組み合わせを考えると、すべてのプログラミング言語の実装で特殊なケースにする必要があります (たとえば、System.Int32 は operator+ メソッドを定義しませんが、ほとんどのプログラミング言語はそのようなメソッドが存在するかのように動作することを選択します)、すべての言語で一般的に相互運用可能な演算子のものを想像するのは困難です。今日の .Net で。言語が何を選択するかによって、多くの設計上のトレードオフがあります (ここで要約するには、相互作用する問題が多すぎます)。いずれにせよ、F# から任意のメソッドを呼び出すことができる必要があります。また、既定の演算子の動作が望ましくない場合は、演算子を必要な動作に再定義 (シャドウ) できます。

編集

で詳細を追加しました

http://cs.hubfs.net/forums/thread/10869.aspx

于 2009-06-08T23:53:59.553 に答える
0

同意します。矛盾があります。演算子は定義できますが、使用できません。

F# の設計者が、演算子のオーバーロードではなく System.IComparable インターフェイスを使用した比較を実装することにした理由をお尋ねですか? 理由はわかりませんが、オブジェクト指向言語では、演算子のオーバーロードよりも IComparable の方が好きです。したがって、F# の開発者には、C# との互換性を壊し、"static member (>) (...)" 構文シュガーを禁止することをお勧めします。

これらのオーバーロードされた演算子を呼び出す方法を尋ねる場合は、非常に簡単です。op_Concatenate、op_GreaterThan、または op_LessThan 静的メンバーを使用します。(本当に、問題を説明するコンパイラ警告が表示されました。F# 1.9.6.16)

コンパイラの警告なしで System.IComparable にキャストするランタイム エラーは間違いなくバグです。fsbugs@microsoft.com に送信できます。

于 2009-06-09T15:56:40.813 に答える