どのように私はこのOCamlのパターンマッチングコードを簡素化することができますか?
-
11-09-2019 - |
質問
私は、ファイルからで代数文を読みocamllex / ocamlyaccを使用してASTにそれを解析し、それを軽減し、それを印刷し、単純な小さなOCamlのプログラムを書いています。私は発現を減少させることだ部分が少し...醜いようです。私はそれを簡略化することができます任意の方法はありますか?
(* ocaml doesn't seem to be able to take arithmetic operators
as functions, so define these wrappers for them *)
let add x y =
x + y
let sub x y =
x - y
let mul x y =
x * y
let div x y =
x / y
(* Are term1 and term2 both ints? *)
let both_ints term1 term2 =
match (term1, term2) with
| (Term (Number x), Term (Number y)) -> true
| (_, _) -> false
(* We know that both terms are reducable to numbers, so combine
them *)
let combine_terms func x y =
match (x, y) with
(Term (Number t1), Term (Number t2)) ->
(Term (Number (func t1 t2)))
| (_, _) -> raise InvalidArg
(* Reduce the expression as much as possible *)
let rec reduce_expr expr =
match expr with
Plus (x, y) ->
let reduced_x = reduce_expr x
and reduced_y = reduce_expr y in
if both_ints reduced_x reduced_y then
(combine_terms add reduced_x reduced_y)
else
Plus (reduced_x, reduced_y)
| Minus (x, y) ->
let reduced_x = reduce_expr x
and reduced_y = reduce_expr y in
if both_ints reduced_x reduced_y then
(combine_terms sub reduced_x reduced_y)
else
Minus (reduced_x, reduced_y)
| Multiply (x, y) ->
let reduced_x = reduce_expr x
and reduced_y = reduce_expr y in
if both_ints reduced_x reduced_y then
(combine_terms mul reduced_x reduced_y)
else
Multiply (reduced_x, reduced_y)
| Divide (x, y) ->
let reduced_x = reduce_expr x
and reduced_y = reduce_expr y in
if both_ints reduced_x reduced_y then
(combine_terms div reduced_x reduced_y)
else
Divide (reduced_x, reduced_y)
| Term x -> Term x
解決
次のような、操作機能内both_ints
を含むタイプを照合することによって、combine_terms
、及びif
機能だけでなく、いくつかNumber
文を削除することができ
let div x y = match x,y with
| Number x, Number y -> Number (x / y)
| _ -> Divide (x,y)
...
let rec reduce_expr expr = match expr with
...
| Divide (x,y) -> div (reduce_expr x) (reduce_expr y)
...
所属していません StackOverflow