2016-05-01 24 views
0

私は少しだけ異なっている複数の条件を持っている場合は、(考えると巣ガード不能)関数を記述するための最良の方法は何である:ハスケルと複数の条件

f | a && b && c = 1 
    | a && b && d = 2 
    | a && b && e = 3 
    | a && g && e = 4 

など

もっと多くの条件があると想像してください。理想的には、次にbをチェックし、それ以外の場合は入れ子にしたいと思いますが、ハスケルではこれができないと言われています。

また、この例では、最初の行が下降した場合、where句で定義されていない場合、条件aとbが再度チェックされますか?

+3

ハスケルでネストされた 'if'はあなたに間違っていると言った人はいますか?このような構成は完全に可能です: 'もしあれば、もしあれば、A else else c、その後、B else C else D'。これだけは、しばしば、まあまあであるとみなされます。主な懸念事項、可読性、保守性、または効率性は何ですか? – ach

+0

@AndreyChernyakhovskiy最終的にその効率は他の2つをあまりにも犠牲にすることはありません。私が上に書いたことは、非常に効率的ではないように見えます。私が学んでいるので、私は自分のコードをできるだけ "ハスケリー"にしたいと思っています:P – matthias

+0

効率はベンチマークでしか測定できません。 "haskelliness"に関して、いくつかのよくあるパターンのパターンに従うことは、教義ではありません。結局のところ、あなた自身の判断です。あなたのプログラムが 'if'sのツリーとしてレイアウトされているときに最も明確に読んでいると思うなら、そうするのが最善です。 – ach

答えて

1

私はcaseを使用したい:

f x y z = 
    case (a, b, c, d, e, f, g) of 
    (True, True, True, _, _, _, _) -> 1 
    (True, True, _, True, _, _, _) -> 2 
    (True, True, _, _, True, _, _) -> 3 
    (True, _, _, _, True, _, True) -> 4 
    where 
    a = ... 
    b = ... 
    c = ... 

これらの例は排他的ではありませんので、ご注文及び/またはカバレッジは、あなたの期待答えを得るようなものであることを確認する必要があると思います。

2

この場合のif文の問題は、入れ子にすることができないということではなく、常にelseコンポーネントを持つ必要があります。この場合、フォールバックを含める必要があるため、非常に扱いにくくなります。すべての声明の中でif文のあなたの例は、次のようになります。

f = if a then 
    if b then 
     if c then 1 
     else if d then 2 
     else if c 
      then 3 
      else 5 
    else 5 
    else if g then 
    if e 
     then 4 
     else 5 
    else 5 

その他のオプションについては、状況によって異なります。 a,bなど。 fへの引数であれば、関数に対してパターンマッチングを行うことができます。

f True True True False False False False = 1 
f True True False True False False False = 2 
f True True False False True False False = 3 
f True False False False True False True = 4 
f _ _ _  _  _ _  _  = 5 

変数はグローバル、またはwhere句で定義されている場合は、あなたはcaseステートメントを使用する必要があります。

f = 
    case (a, b, c, d, e, f, g) of 
    (True, True, True, _, _, _, _) -> 1 
    (True, True, _, True, _, _, _) -> 2 
    (True, True, _, _, True, _, _) -> 3 
    (True, _, _, _, True, _, True) -> 4 
    _        -> 5 

は現実的に、しかし、限り、あなたの変数名があまりにも途方もなく長くないので、あなたのソリューションは、おそらく読みやすさと簡潔さのベストミックスです。効率に関しては、非常に集中的なアルゴリズムでは、この関数がタイトなループに含まれていない限り、ブール演算は非常に安いので、これらのオプションの間の速度の違いを見ることはできません。