まれではありませんが<=>
、製品データ型、つまり複数のフィールドを持つクラス(すべて(私たちはすでに<=>
実装されていることを願っています))に(比較または「宇宙船」)演算子を実装して、特定のフィールドを比較したいと考えています。注文。
def <=>(o)
f1 < o.f1 && (return -1)
f1 > o.f1 && (return 1)
f2 < o.f2 && (return -1)
f2 > o.f2 && (return 1)
return 0
end
これは、特に多くのフィールドで、面倒でエラーが発生しやすくなります。エラーが発生しやすいので、その関数を単体テストする必要があると頻繁に感じます。これにより、面倒で冗長性が増します。
Haskellはこれを行うための特に優れた方法を提供します:
Data.Monoidのインポート(mappend) Data.Ordのインポート(比較) -標準ライブラリから: --データの順序付け=LT| EQ | GT data D = D {f3 :: Int、f2 :: Double、f1::Char}派生ショー compareD ::D->D->注文 compareD = foldl1 mappend [f1の比較、f2の比較、f3の比較]
(に精通していない人のためfold
に、上記はに拡張されます
comparing f1 `mappend` comparing f2 `mappend` comparing f3
D
これは、2つのsに適用できる関数を生成し、を生成しOrdering
ます。)
の定義compareD
は非常に単純なので明らかに正しいので、静的な型チェックがなくても単体テストの必要性を感じることはありません。
実際、この質問はこれよりも少し興味深いかもしれません。標準の<=>
演算子だけを使用するのではなく、さまざまな時間にさまざまな方法で並べ替えるからです。たとえば、次のようになります。
sortByOrderings ::[a->a->注文]->[a]->[a] sortByOrderings=sortBy。foldl1 mappend sortByF3F1 = sortByOrderings [f3の比較、f1の比較] sortByF2F3 = sortByOrderings [f2の比較、f3の比較]
だから、質問:
- この種のものをRubyで実装する典型的な方法は何ですか?
- 標準ライブラリで定義されているものだけを使用してそれを行う最も良い方法は何ですか?
- 上記のHaskellコードにどれだけ近づくことができ、それと比較してどれほど信頼できるでしょうか?
<=>
必要に応じて、フィールドにor<
と>
演算子が適切に実装されていることをどのように確認できますか?
ちなみに、これはRubyの質問ですが、このサイトの長老たちが同意すれば、トピックに関するHaskellの手法についての議論を検討できてうれしいです。それが適切かどうかについてコメントしてください。適切な場合は、この投稿にも「haskell」のタグを付けてください。