関数型プログラミング言語でコードを書くときに従うことができる既知の原則、ベストプラクティス、および設計パターンはありますか?
7 に答える
折りたたみ、展開、マップなどがあります。
彼らの行動について推論するのは非常に簡単で、関数の目的を伝えることが多いので、私は彼らのベストプラクティスを使用することを検討します (たとえば、有名なHaskell プログラマーの進化を見て、新入生と上級生を対比してください。そして教授と)。
設計パターン:型でコーディングをガイドします。
返そうとしている型を把握します。
特定の型コンストラクターには特定の構文が付属していることを知り、それを利用して目的の型を小さくします。以下に 2 つの例を示します。
関数型を返そうとしている場合
T1 -> T2
は、常に安全に記述できます\ x -> ...
body で、より小さな型である type の値を生成しようとしています。さらに、 type
T2
の余分な値を取得しているため、作業が容易になる可能性があります。x
T1
ラムダが不要であることが判明した場合は、後でいつでも eta-reduce を実行できます。
type のペアを生成しようとしている場合は
(T1, T2)
、いつでも type の値とtypex
の値を生成してから、ペアを形成することができます。繰り返しますが、問題をより小さな型の問題に減らしました。T1
y
T2
(x, y)
型が可能な限り小さくなったら、スコープ内のすべての let バインド変数とラムダ バインド変数の型を見て、必要な型の値をどのように生成できるかを確認します。通常、すべての関数に対してすべての引数を使用することを期待します。そうでない場合は、その理由を説明できることを確認してください。
多くの状況で、特にポリモーフィック関数を記述する場合、この設計手法により、複雑な関数の構築を 1 つまたは 2 つの選択肢に減らすことができます。型はプログラムの構築を導くので、正しい型の関数を書く方法はほとんどなく、通常は明らかに間違っていない 1 つの方法しかありません。
ベストプラクティス:代数的データ型を使用し、パターン一致コンパイラーからの網羅性チェックを利用します。特に、
_
トップレベルでワイルドカードパターンを一致させないでください。パターン一致で欠落しているケースが警告ではなくエラーになるように、コンパイラオプションを設定します。
原則に従うのではなく、鼻に従ってください。関数は短くしてください。コードの複雑さを軽減する方法を探してください。これは、多くの場合、必ずしもコードが最も簡潔であることを意味するわけではありません。組み込みの高階関数の使用方法を学びます。
関数を記述した直後に、関数のコード サイズをリファクタリングして削減します。これにより、明日はまだ問題と解決策が頭に浮かんでいないため、時間を節約できます。
設計パターン:コンパイラに関数の型を推測させ、それらの型が期待どおりに正確に一般的であることを確認します。型のポリモーフィック性が高いか、ポリモーフィック性が低い場合は、その理由を突き止めてください。
たとえば、Haskell でソート関数を作成している場合は、
Ord a => [a] -> [a]
あなたのタイプが
Num a => [a] -> [a]
また
[a] -> b
それから何かがひどく間違っています。
ベスト プラクティス: 型が期待どおりであることをコンパイラで確認したら、すべての最上位関数に明示的な型署名を付けます。(または、ML または Caml を使用している場合は、明示的なインターフェイスを記述します。) コンパイラ オプションを設定して、署名のない値がエラーをトリガーするようにします。
私はおそらく少し漠然とした原則で答えます:あなたのコードを最も重要な側面として美しくするよう努めてください。デビッドゲランターを引用するには:
ソフトウェアは非常に複雑であるため、コンピューティングでは、テクノロジーのどこよりも美しさが重要です。美しさは複雑さに対する究極の防御です。
とブライアン・カーニハン:
複雑さを制御することは、コンピュータープログラミングの本質です。
この目標を追求すると、読みやすく理解しやすいコード(これは非常に重要です)、明確に定義された目的を持つ小さくコンパクトな部分に分割されたコードを作成することになります。それはあなたが特定の言語で最良の方法であなたの考えを表現する方法を学ぶようにあなたを導きます。
(これはすべて関数型言語だけに当てはまるわけではありませんが、美しいコードを書くのはとても簡単です。)
John Hughesによる関数型プログラミングが重要である理由は、怠惰と高階(ファーストクラス)関数が、機能の少ない言語に欠けているものの多くを提供し、デザインパターンを補足する理由に良い動機を与えます。
Haskellの文脈では、Real World Haskellの本には、イディオムや抽象化、型クラスなどについて、実用的なアドバイスがあると思いました。Typeclassopediaも常に役立ちます。コアの非常に抽象的な型クラスは、コンパイラー/型システムと言語の一部(使用方法を学んだ場合)によって強制されることを除いて、デザインパターンと見なすことができます。
Lispの文脈で、Paul GrahamはOnLisp(オンラインで入手可能)と呼ばれる本を書きました。そこでは、関数型言語がカスタムプログラミング言語を作成し、その中でプログラムを書くのに理想的であることを示しています。したがって、組み込みドメイン固有言語自体は一種のデザインパターンです。