4

ファイルから代数ステートメントを読み取り、それを 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
4

1 に答える 1

6

次のように、操作関数内に含まれる型を一致させること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)
    ...
于 2009-12-02T16:22:45.520 に答える