11

ブール式を単純化する関数を書いています。たとえば、Nand(A, A) == Not(A). 次のように、パターン マッチングを使用してこの特定のルールを実装しようとしました。

-- Operands equivalent - simplify!
simplify (Nand q q) = Not (simplify q)
-- Operands must be different, so recurse.
simplify (Nand q q') = Nand (simplify q) (simplify q')

コンパイルすると、次のエラーが表示されます。

Conflicting definitions for `q'
Bound at: boolean.hs:73:21
          boolean:73:29
In an equation for `simplify'

何が起こっているのか理解していると思いますし、それを回避しましたが、知りたいのは次のとおりです。

  1. このようなパターン マッチングができないのはなぜですか。
  2. 慣用的な回避策はありますか?

完全な開示: これは宿題に関連していますが、コースの目的は Haskell を学ぶことではなく、とにかく私自身の方法で解決しました。

4

3 に答える 3

15

私が見つけた解決策は、ガードを使用してサブ構造の同等性をチェックすることです。

simplify (Nand q q')
    -- Operands equivalent - simplify!
    | q == q' = Not (simplify q)
    -- Operands different - recurse.
    | otherwise = Nand (simplify q) (simplify q')
于 2012-08-23T04:08:11.643 に答える
2

元のスタイルに固執することができます:

-- Operands equivalent - simplify!
simplify (Nand q q') | q == q' = Not (simplify q)
-- Operands must be different, so recurse.
simplify (Nand q q') = Nand (simplify q) (simplify q')

また、等価テストの後ではなく、前に単純化する必要があると思います。

simplify (Nand q q') = if qs == qs' then Not qs else Nand qs qs' where
    qs = simplify q
    qs' = simplify q'
于 2012-08-29T21:38:05.333 に答える
1

「答え」は、パターンで同じ変数を 2 回言及することは許可されていないということです。とにかく、Haskellにはありません。これを解決する最善の方法は、すでに発見されているように見える方法です。パターン ガードを使用して、等しいかどうかをテストします。

于 2012-08-23T10:20:06.820 に答える