2009-06-08 8 views
4

私は最近、Microsoft Solver Foundation Servicesを利用してF#で何かを書くことを試みましたが、その間に問題にぶつかりました.C TermでTermを指定する必要がありました。 t1> t2として表され、別のTermオブジェクトを返す。 F#では、代わりに、t1> t2を使用すると同じ結果を得るためにTerm.op_GreaterThanを呼び出す必要がありました。
今、私はF#がブール値を返す場合にのみop_GreaterThanを選んでいるのですか? TermがIComparableを実装していない間に、F1のt1> t2の解釈にはどんな意味がありますか?
私は、構造比較の概念に基づいて、平等と全体平等のようなことを行う理由を理解していることを覚えておいてください、私はそれがどのように「より大きい」/「より小さい」比較に拡張できるのか理解できません。F#とop_GreaterThan

+0

http://cs.hubfs.net/forums/thread/10860.aspxおよびhttp://stackoverflow.com/questions/967508/f-and-operator-overloads – Brian

答えて

4

教科書回答:

演算子のオーバーロードは、コンパイラの作家は無視するか、部分的にしか、彼らはのように感じる場合は、それをサポートするのは自由ですつまり、共通言語仕様の一部ではありません。図書館の作家は、あなたがそのクラスで働くための代替手段を提供する責任があります。

実用回答:

最初の場所で行うには愚かなことですので。 op_GreaterThanメソッドは、比較を行うために明示的に作成されました。それは、あなたは2つの用語をconcatinatingのようにそれで "面白い"ものをすることになっていません。 CLRは、C++のようなレガシー言語をサポートする必要があるため、あなたに悪用することができます。

ところで、特に2つのものを結合するための過負荷があります。これはop_Concatenateと呼ばれます。あなたは本当にそれをop_GreaterThanの代わりに使うことを検討すべきです。

EDIT

ほとんど良い答え:F#ので

私が言及した連結の演算子です^。

私はこれがC#でサポートされているかどうかわからないので、これはほとんど良い答えです。私はそれがVBとF#でのみ許されると思います。

EDIT#2

F#は、すべての後に^過負荷を尊重されていないようです。

EDIT#3

WTFはここで起こっていますか? F#は>演算子をまったく尊重しません。確かにそれをオーバーロードすることができ、op_GreaterThanメソッドを正しく発行しますが、無視します。これは、op_GreaterThanを使用しようとするのではなく、代わりにSystem.IComparableインターフェイスを探します。

さらに悪いことに、これはランタイムチェックです。クラスFooがIComparableを実装していないことを静的に判断することはできますが、それでもやはり先に進んでコードをコンパイルします。

+1

もちろん、Term.op_GreaterThanを明示的に呼び出す独自のF#演算子を定義することはできません。 –

+0

私は実際に連結を行っていませんが、あなたの答えはデザインの選択肢をかなりクリアします。私はまだTerm = Termの意味を持っていませんが、F#コンパイラがop_GreaterThanを使用せずに妥当な意味を与えることはできませんが、少なくとも私は言語設計の選択を受け取ります – em70

+0

@Joel?私の研究から、F#でオーバーロードすることはできますが、それを消費することはできません。それは単に過負荷をiqnoresし、代わりにIComparableを探します。 –

2

直観的には、>のような比較演算子は常にブール値を生成する必要があります。

質問a > bには、はいまたはいいえで答えることができますが、3またはnew Stopwatch()では答えられません。それはもはや意味をなさないだろう何か、

if a < b then 

のようなものを返すことができ

F#-objects(タプル、リストなど)は、多くの場合、IComparableまたはIStructuralComparableを実装しています。たとえば、タプルを辞書的に並べ替えることができます。

*注:

私見、それが最善の解決策ではありません任意のオブジェクトを比較して、実行時に例外をスローするために許可します。ハスケルはこれを型抜きでより良く解決しました。

greater :: (Ord a) => a -> a -> Bool 
greater a b = a < b 

コンパイル時に比較不能な型を比較す​​ると失敗します。

+0

私は事実を言語の観点から見ると、a> bにブール値を与えることは理にかなっていますが、.NETではop_GreaterThanを( 'a *' b) - > 'cとして定義できるため、interopの目的は、存在する? (特に、私が考えているのはMicrosoftのライブラリなので...) – em70

0

<と>演算子を使用する必要はありません。ソルバー基盤サービスモデルクラスにはより大きい方法と少ない方法があります。代わりにそれらを使用できるはずです。