23

関数型プログラミング言語(Haskell / F#/ Caml)のパターンマッチング機能を使用して、同じ値を複数回照合できるかどうか疑問に思いました。

次の例を考えてみてください。

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

最初のバリアントは、関数が2つの類似した値(に格納される)で呼び出されたときに呼び出されますa

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

simplify (Add a a) = Mult 2 a

しかし、Haskellはこれらのコードを拒否し、定義の競合についてa警告します-関数が同じ値を取得したかどうかを確認する代わりに、明示的なcase/if-checksを実行する必要があります。照合したい変数が複数回発生することを示すトリックはありますか?

4

4 に答える 4

42

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

http://www.mail-archive.com/haskell-cafe@haskell.org/msg59617.html

http://www.mail-archive.com/haskell-cafe@haskell.org/msg62491.html

結論: 実装することは不可能ではありませんが、単純にするために反対することにしました。

ところで、これを回避する必要はありませifcase。(少し)きれいな方法は、ガードを使用することです:

a `plus` b
  | a == b = 2*a
  | otherwise = a+b
于 2009-07-24T18:36:49.760 に答える
14

等しい必要があることを示すために同じ名前の 2 つのパラメーターを使用することはできませんが、ガードを使用して次のようなケースを区別できます。

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

これは、単純な等式よりも複雑な条件でも機能するため、より柔軟です。

于 2009-07-24T17:34:06.503 に答える
-3

Haskell で非線形パターンを処理できる新しい関数型プログラミング言語を実装しました。

https://github.com/egison/egison

私の言語では、あなたのplus機能は次のように書かれています。

(define $plus
  (match-lambda [integer integer]
    {[[$a ,a] (* a 2)]
     [[$a $b] (+ a b)]}))
于 2014-12-25T02:22:55.197 に答える