5

F#では、等式演算子(=)は一般に、内包的ではなく外延的です。それは素晴らしいことです!残念ながら、F#はこれらの拡張比較をショートカットするためにポインターの同等性を使用していないように見えます。

たとえば、次のコードは次のとおりです。

タイプZ=MT | Z参照のNMT

// Zを作成します:
a =refMTとします
//それ自体を指すようにします:
a:= NMT a

//それがそれ自体と等しいかどうかを確認します:
printf "a = a:%A \ n"(a = a)

...'a'と'a'の両方が同じ参照に評価されるという事実にもかかわらず、私に大きな脂肪セグメンテーション違反[*]を与えます。それはそれほど素晴らしいことではありません。他の関数型言語(PLTスキームなど)は、ポインター比較を控えめに使用してこれを正しく行い、ポインター比較を使用して判別できる場合は「true」を返します。

つまり、F#の等式演算子がショートカットを使用しないという事実を受け入れます。内包的(ポインターベース)の同等性チェックを実行する方法はありますか?(==)演算子は私の型では定義されていません。誰かがそれが何らかの形で利用可能であると私に言うことができれば、私はそれが大好きです。

または、状況の分析が間違っていると言ってください。私もそれが大好きです...

[*]それはおそらくWindowsのスタックオーバーフローでしょう。モノについては、私があまり好きではないことがあります...

4

1 に答える 1

8

私が知っている2つのオプションがあります。標準の.NETアプローチは、を使用することSystem.Object.ReferenceEqualsです。F#での少し良いアプローチは、LanguagePrimitives.PhysicalEquality基本的に同一であるが、参照型(おそらくあなたの目的にとって正しい)でのみ機能し、両方の引数が同じ静的型を持つ必要があるを使用することです。より良い構文が必要な場合は、これらの関数のいずれかに関して、選択したカスタム演算子を定義することもできます。

余談ですが、.NETでは、コードを実行したときに無限ループが発生しますが、スタックオーバーフローは発生しません。これは、おそらく末尾呼び出しの最適化が原因です。

于 2010-04-21T20:21:09.180 に答える