引数

2012-01-05 12 views
22

の数が異なる式で関数を定義する私は、このような定義引数

が不可能であることを今日気づきました。私はちょうどこれの背後にある(良い)理由が不思議です。結局のところ、ハスケルです。)

注:上記のコードの代替実装についての提案はありません。これは、私の要点を示す簡単な例です。

+4

「安全」と呼んでいますか? 'Maybe'や何かを返すか、あるいは何らかの既知の例外を投げたり、' newtype'でそれを使用しましょう。それはあなただけのメンバーとして扱う非縮退関数専用です。 L2ヒルベルト空間(すなわち、規定されたモジュロヌル集合のみ)。それは安全だろう。すべての 'Fractional'インスタンスに対して' x/0 = x' _ad hoc_を定義するだけでは恐ろしく非標準的です! - まあ、おそらく例として意味されていただけです。 – leftaroundabout

+0

+1うわー、ハスケルを何年も使っていて、そのような定義が許されていないことに気付かなかった! – is7s

+0

@leftaroundabout 'safeDivide x 0 = Nothing; safeDivide = Just :(/) 'より良い? :) –

答えて

25

私は主に一貫性のために、すべての節を同じように読むことができると思います。すなわち、すべてのRHSは、機能のタイプにおいて同じ位置にある。私はあなたがこれを許せば、かなりのばかげたエラーを隠すでしょう。

コンパイラには、他の節と同じ数のパターンを持つように、そのような節を埋め込んだとすると、やや意味が分かります。すなわち、あなたの例では、2番目の行ではなくsafeDivide = undefinedされていた場合は今考える

safeDivide x 0 = x 
safeDivide x y = (/) x y 

なります。前の句がない場合、safeDivideとなりますが、ここで実行されたη拡張のおかげで\x y -> if y == 0 then x else ⊥ - safeDivide = undefinedは実際にsafeDivideと定義していません!これは、そのような条項を禁止することを正当化するのに十分混乱しているようです。

+0

技術的に深い理由はありませんか? – aelguindy

+1

@aelguindy:実際、はい!私は私の答えを更新しました:) – ehird

+0

コードを編集していただきありがとうございました:)、これからはやります。なぜそれがconst(const \ bot)であるかを知るにはしばらく時間がかかりましたが、今すぐ取得します。 – aelguindy

11

複数の節を持つ関数の意味は、ラムダとcaseステートメントに翻訳を経由してHaskellの標準(section 4.4.3.1)によって定義されます。

fn pat1a pat1b = r1 
fn pat2a pat2b = r2 

はこれがそうである

fn = \a b -> case (a,b) of 
    (pat1a, pat1b) -> r1 
    (pat2a, pat2b) -> r2 

になると、その関数の定義/ case文のやり方は素晴らしく一貫しており、それぞれの意味は重複して紛らわしく指定されていません。

この変換は、各節が同じ数の引数を持つ場合にのみ実際に意味があります。もちろん、それを修正するための特別なルールがあるかもしれませんが、あなたは読者のために、とにかくそのようなものを定義したくないかもしれないので、少しの利益のために翻訳を複雑にします。

4

前者(LMLやミランダのような)がしたので、ハスケルはこのようにします。このような技術的理由はありません。議論の数が少ない方程式を拡張することができます。しかし、異なる方程式に対して異なる数の議論をすることは、意図的ではなくタイプミスである可能性があります。この場合、一般的なケースではより良いエラー報告を得るために賢明なものを禁止します。&