如何简化这个 ocaml 模式匹配代码?
我正在编写一个简单的小 ocaml 程序,它从文件中读取代数语句,使用 ocamllex/ocamlyacc 将其解析为 AST,减少它,然后打印它。我减少表情的部分似乎有点……丑陋。我有什么办法可以简化它吗?
(* 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
I'm writing a simple little ocaml program that reads an algebraic statement in from a file, parses it into an AST using ocamllex/ocamlyacc, reduces it, and then prints it. The part where I'm reducing the expression seems a bit... ugly. Is there any way I can simplify it?
(* 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以通过匹配包含
Number
的类型来删除both_ints
和combine_terms
函数以及一些if
语句在操作功能内,例如:You can remove the
both_ints
, andcombine_terms
functions as well as someif
statements, by matching the type containingNumber
within the operation functions, such as: