OCaml函数用于评估算术表达式

时间:2012-08-15 22:11:03

标签: recursion tree expression ocaml

我写了一部分数学计算器程序。我已经完成了该程序的解析器, 所以当用户输入数学表达式作为字符串时,我已经有了获得的方法 相应的以下类型的数据结构:

type expression =
| Term of int
| Addition of expression * expression
| Multiplication of expression * expression
| Subtraction of expression * expression

我现在需要的只是一种评估这类数据结构的方法。

  
      
  • (a)写出对应于数学陈述“3 *((1 + 4) - 5)的表达式。”
  •   
  • (b)扩展Ocaml数据类型以包含Factorial构造函数,以便它可以处理   表达式如“3 *((1 + 4)!-5)。”
  •   
  • (c)编写一个Ocaml函数eval,它采用数学表达式并返回它   (整数)值。例如,它应该从部分表达式返回0作为结果   (a)中。

         

    #let rec eval expr = ...    val eval:表达式 - > int =

  •   
     

你可能想要编写一个因子Ocaml函数来帮助解决新的Factorial问题   构造

我对第一部分感到困惑。这是let expression = 3*((1 + 4)- 5);;吗?

对于b部分,我应该遵循模式|Factorial of expression * expression吗?

3 个答案:

答案 0 :(得分:3)

a)的含义是您现在可以将数学表达式编写为提供的数据类型expression的值。例如,构造函数Addition表示加法运算符(通常写为(+))通过将两个较小的表达式作为操作数来形成表达式。因此,例如,数学表达式2 + 3可以由Caml值

表示
Addition (Term 2,Term 3)

现在,观察阶乘运算符只接受一个参数而不是两个参数,你应该能够使用b)中提到的阶乘的构造函数扩展数据类型expression

最后,在c)中,为这种表达式类型编写求值函数很简单:常量只映射到它们所携带的整数值,并且评估加法包括递归计算加法的操作数,然后将它们相加:

let rec eval = function
  | Term n -> n
  | Addition (l,r) -> eval e1 + eval e2
  | ...

其余的情况(对于其余的构造函数,包括你将为b添加的阶乘的构造函数),是类似的,你现在应该可以自己做。

祝你好运!

答案 1 :(得分:0)

b部分:问题的关键在于乘法将两个数字作为输入,但是factorial只需要一个数字作为输入。

答案 2 :(得分:0)

这里是我与我的教授一起解决的答案我认为我发布解决方案以防其他人突然解决这个问题。

(a)写出对应于数学陈述“3 _((1 + 4)?? 5)的表达式。”

# let expression = Multiplication((Term 3, Subtraction(Term 5, Addition (Term 1, Term 4))));;

(b)扩展Ocaml数据类型以包含Factorial构造函数,以便它可以处理 表达式如“3 _((1 + 4)!?? 5)。”

# type expression =
| Term of int
| Addition of expression * expression
| Multiplication of expression * expression
| Subtraction  of expression * expression
| Factorial of expression;;

# let expression = Multiplication((Term 3, Subtraction(Term 5, Factorial(Addition (Term 1, Term 4)))));;

(c)编写一个Ocaml函数eval,它采用数学表达式并返回它 (整数)值。例如,它应该从部分表达式返回0作为结果 (一个)。您可能希望编写一个因子Ocaml函数来帮助解决新的Factorial问题 构造

# let rec eval expression =
  match expression with
  |Term m -> m
  |Addition(m,n) -> add(eval(m), eval(n))
  |Subtraction(m,n) -> eval(m) - eval(n)
  |Multiplication(m,n) -> eval(m) * eval(n)
  |Factorial(m)->factorial(eval(m));;

# let add(m,n) = m+n;;

# let rec factorial n =
    if n=0 then 1 else n * factorial(n - 1);;