19

関数型プログラミング言語(Haskell/F#/ Caml)のパターンマッチング機能を使って同じ値に対して複数回一致させることができるかどうかは不思議でした。パターン一致の同じ値

ちょうど次の例を考える:機能(aに格納される)2つの類似の値で呼び出されたとき

plus a a = 2 * a 
plus a b = a + b 

最初の変異体と呼ばれるであろう。

より有用なアプリケーションはこれです(ASTを単純化する)。

simplify (Add a a) = Mult 2 a 

しかし、Haskellはこれらのコードを拒否し、aため矛盾の定義を私に警告し - 私はチェックがあれば、代わりに関数が同じ値を持っているかどうかを調べるために/明示的なケースを行う必要があります。一致したい変数が複数回現れることを示すためのトリックはありますか?

+0

FWIWでは、Mathematicaがこれをサポートしています。 –

答えて

39

非線形パターンと呼ばれます。これについて、haskell-cafeメーリングリストには、ずっと前からいくつかのスレッドがあります。ここでは2つです:

http://www.mail-archive.com/[email protected]/msg59617.html

http://www.mail-archive.com/[email protected]/msg62491.html

ボトムライン:それは実装することは不可能ではないが、簡略化のために反対を決めました。

ところで、これを回避するにはifまたはcaseは必要ありません。 (少し)クリーンな方法は、ガードを使用することです:

a `plus` b 
    | a == b = 2*a 
    | otherwise = a+b 
+0

リンクありがとう - ありがとう – Dario

13

あなたは、彼らが同じでなければならないことを示すために、同じ名前を持つ2つのパラメータを持つことはできませんが、このようなケースを区別するためにguardsを使用することができます。これは、それはまたのために働くので、より柔軟性のある

plus a b 
    | a == b = 2 * a 
    | otherwise = a + b 

単純な平等より複雑な条件。

+0

はい、私は警備員を知っていますが、私は手動による比較を避けようとしました。 – Dario

+0

これの略記:http:// stackoverflow。com/questions/480769/f-matching-with-two-values/501541#501541 – Dario

-1

ハスケルは統一しません。

+4

統一には両側に自由変数が必要です。 –

+1

これは単なる平等であり、統一ではありません。 'のように| a、a = a - > .. 'のとき。 –

0

私はトーマスの答えで与えられたメーリングリストのスレッドを見ていると、そのうちの一つで非常に最初の返信は良い理にかなって、なぜ、そのような説明します「パターン」は一般的に意味をなさないでしょう:aが何かの場合はですか? (一般的に2つの関数が等しいことを確認することは不可能です。)

+0

'a'を' Eq'に制限できませんでしたか? – gdejohn

+0

@ gdejohn、私はセマンティクスが正しくないと思う。 'fxx = x'という形式の定義を適用すると、2つの提出された引数が*同じ値*であり、いくつかのtypeclassの意味では" equal "ではないことを合理的に期待できる(そうでなければ、 「x」の2つの値のうちの「f」が戻るべきである)。 – Alexey

-1

私はHaskellで非線形パターンを扱うことができる新しい関数型プログラミング言語を実装しました。私の言語で

https://github.com/egison/egison

、次のように書かれた中で、あなたのplus機能。

(define $plus 
    (match-lambda [integer integer] 
    {[[$a ,a] (* a 2)] 
    [[$a $b] (+ a b)]})) 
関連する問題