我目前正在尝试编写一个OCaml函数,该函数将计算表达式并返回布尔值。我尝试在网上做研究,我能找到的最接近的答案就是这个。但是,我仍然遇到麻烦,这导致我问了自己的问题。
以下是基本代码:
type equation =
| True
| False
| Equal of exp * exp
and exp =
| Val of int
| Add of exp * exp
| Sub of exp * exp
let rec eval : equation -> bool
= fun f ->
match f with
| True -> true
| False -> false
| Equal (x, y) -> match (x, y) with
| (Val a, Val b) -> if (x = y) then true else false
| ((Add (Val a, Val b), c) -> eval (Equal (Val (a + b), c))
该程序不完整,最后一行对eval
的递归调用是我卡住的地方。我想到的一个具体输入示例是:
eval (Equal (Add (Add (Val 1, Val 2), Val 3), Val 6))
这应该计算为true
,因为两个Add
加起来是6,Equal
Val 6
与Val 6
进行比较。我遇到的麻烦是如何递归调用函数来计算表达式内的第二个Add
,以便Add (Val 2, Val 2)
首先计算为Val 3
,然后第一个Add
用Val 3
添加Val 3
。我现在编写的程序只评估两个Add
中的一个。
有什么我应该考虑或记住的吗?欢迎任何反馈。谢谢。
正如@Amadan所提到的,定义一个函数更容易,该函数将首先计算 inteval_exp: exp -> int
的表达式。然后,您只需在元组Equal(e1, e2)
中计算这两个表达式并比较它们(eval: equation -> bool
(。
你也不需要类型equation
中的值 True 和 False,因为你可以只从函数返回布尔值而不进行模式匹配。请注意,如果出于某种原因再次传递了 True 和 False,则可能需要 True 和 False,以eval
函数。
type equation =
Equal of exp * exp
and exp =
| Val of int
| Add of exp * exp
| Sub of exp * exp
let rec eval (e: equation) : bool =
let rec eval_exp e =
match e with
| Val i -> i
| Add (e1, e2) -> (eval_exp e1) + (eval_exp e2)
| Sub (e1, e2) -> (eval_exp e1) - (eval_exp e2)
in
match e with
| Equal (e1, e2) ->
if (eval_exp e1) = (eval_exp e2)
then true
else false