私は現在、OCaml を使用した小さなプロジェクトに取り組んでいます。単純な数式の簡略化。式の中に特定のパターンを見つけて、それらを単純化して、式内の括弧の数を減らすことになっています。これまでのところ、再帰的なパターン マッチングの「フィルター」関数を作成することにした 2 つのルールを除いて、ほとんどのルールを実装できました。実装する必要がある 2 つのルールは次のとおりです。
- a - (b + c) または類似の形式のすべての表現を a - b - c に変換します。
- a / (b * c) または類似の形式のすべての式を a / b / c に変換します。
...これはかなり単純だと思います。1 つを実装できたら、もう 1 つを簡単に実装できます。しかし、再帰的なパターンマッチング機能に問題があります。私の型式はこれです:
type expr =
| Var of string (* variable *)
| Sum of expr * expr (* sum *)
| Diff of expr * expr (* difference *)
| Prod of expr * expr (* product *)
| Quot of expr * expr (* quotient *)
;;
そして、私が主に問題を抱えているのは、マッチ式にあります。たとえば、次のようなことを試みています。
let rec filter exp =
match exp with
| Var v -> Var v
| Sum(e1, e2) -> Sum(e1, e2)
| Prod(e1, e2) -> Prod(e1, e2)
| Diff(e1, e2) ->
match e2 with
| Sum(e3, e4) -> filter (diffRule e2)
| Diff(e3, e4) -> filter (diffRule e2)
| _ -> filter e2
| Quot(e1, e2) -> ***this line***
match e2 with
| Quot(e3, e4) -> filter (quotRule e2)
| Prod(e3, e4) -> filter (quotRule e2)
| _ -> filter e2
;;
ただし、マークされた行の一致式は、「プリンシパル一致」ではなく、以前の「内部一致」の一部として認識されているようで、すべての「Quot(...)」式が認識されることはありません。このような他の一致式の中に一致式を含めることさえ可能ですか? そして、他の可能性とのマッチングを続けることができるように、内側のマッチングを終了する正しい方法は何でしょうか?
ロジックは無視してください。これはほとんど私が最初に思いついたものです。再帰性またはロジックは大歓迎です。