web-dev-qa-db-ja.com

カリー化を利用するためのパラメータの順序

flip\x -> foo bar x 42のようなハッキングが発生しているコードが多すぎたため、パラメーターの順序を変更するために最近2回コードをリファクタリングしました。

関数シグネチャを設計するとき、カリー化を最大限に活用するのに役立つ原則は何ですか?

92
John F. Miller

カリー化と部分適用を簡単にサポートする言語については、もともとクリス・オカサキからの説得力のある一連の議論があります。

  • データ構造を最後の引数として配置します

どうして?次に、 データに対する操作を作成する うまくできます。例えば。 insert 1 $ insert 2 $ insert 3 $ s。これは 状態の関数 にも役立ちます。

「コンテナ」などの標準ライブラリ この規則に従ってください

データ構造を最初に配置するために代替引数が指定されることがあるため、データ構造を閉じて、静的構造(ルックアップなど)でもう少し簡潔な関数を生成できます。ただし、特に括弧で囲まれたコードに向かっているため、これはあまり効果がないというのが大まかなコンセンサスのようです。

  • 最も変化の激しい引数を最後に置きます

再帰関数の場合、最も変化の少ない引数(アキュムレータなど)を最後の引数として配置し、最も変化の少ない引数(関数の引数など)を最初に配置するのが一般的です。これは、データ構造の最後のスタイルとうまく構成されます。


Okasakiビューの要約は、 彼のEdisonライブラリ (ここでも別のデータ構造ライブラリ)に示されています。

  • 部分適用:部分適用を容易にするために、通常、静的である可能性が高い引数が他の引数の前に表示されます。
  • コレクションは最後に表示されます:操作が単一のコレクションを照会するか、既存のコレクションを変更するすべての場合、コレクション引数は最後に表示されます。これはHaskellデータ構造ライブラリの事実上の標準のようなものであり、APIにある程度の一貫性を与えます。
  • 最も一般的な順序:演算が複数のデータ構造でよく知られている数学関数を表す場合、引数は次の最も一般的な引数の順序に一致するように選択されます。関数。
110
Don Stewart

再利用する可能性が最も高い引数を最初に配置します。関数の引数はこの良い例です。同じリストに多くの異なる関数をマップするよりも、2つの異なるリストにmap fする可能性がはるかに高くなります。

11
hammar

私はあなたがしたことをする傾向があり、良いと思われる注文を選び、別の注文の方が良いことが判明した場合はリファクタリングします。順序は、関数をどのように使用するかによって大きく異なります(当然)。

3
augustss