2011-12-10 20 views
13

私は(私が知る限りは)大文字小文字の表現やガードを使用できる関数を作成しました。「ガード」を書くための好ましい方法はどれですか?

foo a b c = case a of 1 -> [...] 
         2 -> [...] 
         3 -> [...] 
         [...] 
         otherwise -> error "..." 

または

foo a b c | a == 1 = [...] 
      | a == 2 = [...] 
      | a == 3 = [...] 
      | [...] 
      | otherwise = error "..." 

だから、質問は:コーディング、「より良い」であるこれらの2(ケースやガード)のどれ?どちらも基本的に同じですか?

+10

最初の例では、そのような 'otherwise'を使うべきではありません。それがするのは、 'otherwise = a'という新しい変数を導入し、微妙なバグにつながる可能性があるということです。代わりに '_ - > error" ... "'を実行する必要があります。 – dflemstr

+0

@dflemstr情報と解説に感謝します。 – Nomics

+1

一般的なクロスランゲージのヒントとして、私は、次の行に常に同じ字下げレベルでコードのサブブロックを書き込む方が好きです。最初のものの長さが変わった場合(おそらくfooの名前が変更されたり、何かの行があるため)、残りの行を再インデントする必要から保護します – hugomg

答えて

13

最初のものは、2つの理由から、より良いスタイルと考えられます。

まず、==のすべてを入力する必要がないので、多くの人が見た目が良くなると言います。もちろん、これは非常に主観的な理由です。また、あなたは通常、でも新しいcaseステートメントを導入していないだろうが、ちょうどそうのような関数の引数リストで引数を一致:

foo 1 b c = ... -- etc 
... 
foo _ b c = ... -- for the "otherwise" part 

これは、多くの人が好きなコードにもよりコンパクトで読みやすいし、作ります。

第2に、実際には意味の違いがあります。あなたは、このようなデータ型を持っていることを想像:

data Cake = Apple | Cheese | Cream 

あなたが最初のメソッドを使用する場合は、あなたがcase..of式のコンストラクタにマッチ:あなたが警備を行うにしようとした場合、しかし、

case a of 
    Apple -> "fruit" 
    _  -> "not fruit" 

このようないくつかの並べ替えの発現、:

| a == Apple = "fruit" 
| otherwise = "not fruit" 

... CakeタイプはEqインスタンスを持っていないので、それは実際には、動作しません、したがって、==を使用して2つの値を比較することはできません。 Eqインスタンス(データ定義の後にderiving (Eq))が常に必要なわけではないので、この場合に行う必要はありません。

+0

意味的に異なる場合は、どのように他のものより優れていると言うことができますか? –

+1

@AdamWagner多くの状況では、(結果のマシンコードを比較することによって)まったく同じ結果を持つどちらかを使用するオプションがあるためです。 – dflemstr

+0

意味論的な問題は私には新しく!よく考えられた!! O_o – Nomics

9

いずれかのパラメータで(ガードレス)case-statementとしてガードを書き換えることができる場合は、実際には必要ありません。私。

これは次のように書くことができます。あなたが望む条件がパターンとして表現できないときは、ガードを使用します。また、パラメータの1つ以外に一致する必要がある場合は、case文を使用します。

+0

実際には、いくつかの基本的なケースがあります。 "if a == 1 && b> c then(...)"のように、コード作成の初心者です。だから、あなたの提案を適用すれば、私のコードを読みにくくすることができます。(?) – Nomics

+0

実際に(パート2)...私はあなたの提案をすることができますね...そしてそれは良いようですね! ^^ – Nomics

関連する問題