简体   繁体   English

用于计算算术表达式的 OCaml 函数

[英]OCaml function to evaluate arithmetic expressions

I've written part of a mathematical calculator program.我写了一个数学计算器程序的一部分。 I've finished the parser of the program, so when a user types in a mathematical expression as a string, I already have a way to obtain a corresponding data structure of the following type:我已经完成了程序的解析器,所以当用户输入一个数学表达式作为字符串时,我已经有办法获得以下类型的相应数据结构:

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

All I need now is a way to evaluate these kinds of data structures.我现在需要的是一种评估这些数据结构的方法。

  • (a) Write the expression corresponding to the mathematical statement “3*((1 + 4)- 5).” (a) 写出与数学语句“3*((1 + 4)- 5)”相对应的表达式。
  • (b) Extend the Ocaml datatype to include a Factorial constructor, so that it can handle expressions like “3*((1 + 4)! -5).” (b) 扩展 Ocaml 数据类型以包含一个 Factorial 构造函数,以便它可以处理诸如“3*((1 + 4)! -5)”之类的表达式。
  • (c) Write an Ocaml function eval which takes a mathematical expression and returns its (integer) value. (c) 编写一个 Ocaml 函数 eval,它接受一个数学表达式并返回它的(整数)值。 For example, it should return 0 as the result from the expression in part (a).例如,它应该返回 0 作为部分 (a) 中表达式的结果。
 # let rec eval expr = ... val eval : expression -> int = <fun>

You may want to write a factorial Ocaml function to help out with the new Factorial constructor.您可能想要编写一个阶乘 Ocaml 函数来帮助使用新的 Factorial 构造函数。

I'm confused about part a.我对 a 部分感到困惑。 Does it mean let expression = 3*((1 + 4)- 5);这是否意味着let expression = 3*((1 + 4)- 5); ? ?

For part b, should I follow the pattern |Factorial of expression * expression ?对于 b 部分,我是否应该遵循|Factorial of expression * expression

What is meant in a) is that you can now write mathematical expressions as values of the provided datatype expression . a) 中的意思是您现在可以将数学表达式编写为提供的数据类型expression值。 For example, the constructor Addition expresses that the addition operator (normally written as (+)) forms an expression by taking two smaller expressions as operands.例如,构造函数Addition表示加法运算符(通常写为 (+))以两个较小的表达式作为操作数形成一个表达式。 So, for instance, the mathematical expression 2 + 3 can be represented by the Caml value因此,例如,数学表达式 2 + 3 可以用 Caml 值表示

Addition (Term 2,Term 3)

Now, observing that the factorial operator takes one argument rather than two arguments, you should be able to extend the datatype expression with a constructor for factorials as is asked in b).现在,观察到阶乘运算符采用一个参数而不是两个参数,您应该能够使用 b) 中要求的阶乘构造函数扩展数据类型expression

Finally, in c), writing an evaluation function for this kind of expression types is straightforward: constants just map to the integer value they are carrying and evaluating an addition involves recursively evaluating the operands of the addition and then adding them up:最后,在 c) 中,为这种表达式类型编写评估函数很简单:常量只映射到它们携带的整数值,评估加法涉及递归评估加法的操作数,然后将它们相加:

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

The remaining cases (for the remaining constructors, including the one for the constructor for factorials that you will add for b)) are analogous and you should be able to do that by yourself now.剩余的情况(对于剩余的构造函数,包括您将为 b 添加的阶乘构造函数的情况)是类似的,您现在应该能够自己完成。

Good luck!祝你好运!

b 部分:问题的重点是乘法需要两个数字作为输入,但阶乘只需要一个数字作为输入。

here is the answers i worked out with my profesor i thought i post the solution in case some one else cam across this problem. 这是我与我的教授得出的答案,我以为我发布了解决方案,以防其他人解决此问题。

(a) Write the expression corresponding to the mathematical statement “3 _ ((1 + 4) ?? 5).” (a)写下与数学表达式“ 3 _((1 + 4)?? 5)”相对应的表达式。

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

(b) Extend the Ocaml datatype to include a Factorial constructor, so that it can handle expressions like “3 _ ((1 + 4)! ?? 5).” (b)扩展Ocaml数据类型以包括一个阶乘构造函数,以便它可以处理类似“ 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) Write an Ocaml function eval which takes a mathematical expression and returns its (integer) value. (c)编写一个Ocaml函数eval,该eval使用数学表达式并返回其(整数)值。 For example, it should return 0 as the result from the expression in part (a). 例如,它应该返回(a)部分中表达式的结果为0。 You may want to write a factorial Ocaml function to help out with the new Factorial constructor. 您可能需要编写阶乘Ocaml函数来帮助使用新的阶乘构造函数。

# 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);;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM