解释一个功能

时间:2012-03-06 02:23:44

标签: f# f#-interactive

我必须提出一个函数来评估抽象语法树并返回其评估结果。

评估将具有类型Exp - > int选项

  

评价(Prod(Num 5,Diff(Num 6,Num 1)));;    val it:int option =约25

@John Palmer 我该怎么做呢?我可以使用模式匹配吗?如果是这样,我该如何做才能确定需要完成的操作。

以下是我的想法?我仍然不明白每个说法的代码。

let rec evaluate = function
 | Num n -> Some n
 | Neg e -> match evaluate e with
 |Sum (a,b) -> evaluate(a) + evaluate(b)
 |Diff(a,b) -> evaluate(a) - evaluate(b)
 | Prod (a,b) -> evaluate(a) * evaluate (b) 
 |Quot (a,b) -> evaluate(a) / evaluate(b) 

3 个答案:

答案 0 :(得分:4)

以下是一些入门提示

let rec evaluate AST =
   match AST with
   |Prod(a,b) -> evaluate(a) * evaluate(b)
   |Num(a) -> a
   ....

修改

所以我假设您的数据类型看起来像

type AST =
|Num of int
|Neg of AST
|Prod of AST * AST
|Diff of AST * AST
|Quot of AST * AST
|Sum of AST * AST

所以你设置你的AST(可能是你从某个地方解析这个 - 这是另一个问题),比如

let ast = Prod(Num 5, Diff(Num 6, Num 1))

然后您可以将评估定义为

let rec evaluate arg =
    match arg with
    |Num n -> n
    |Neg tree -> - (evaluate tree)
    |Sum (a,b) -> (evaluate a) + (evaluate b)
    |Prod(a,b) -> (evaluate a) * (evaluate b)
    |Quot(a,b) -> (evaluate a) * (evaluate b)
    |Diff(a,b) -> (evaluate a) - (evaluate b)

然后调用它并用

打印结果
printfn "%i" (evaluate ast)

请注意,evaluate必须包含AST -> int类型,否则您需要处理选项案例 - 例如2 * None2 + None

我不确定你的意思

  

我应该如何在较小的输入上调用递归方法。

但希望这能解释一切

答案 1 :(得分:2)

首先查看语法,词法分析器和解析器,为您生成AST。一旦你拥有了它,就可以轻松地走树并进行评估。

这是F#的链接:

http://www.quanttec.com/fparsec/

答案 2 :(得分:2)

我发布了一个用OCaml编写的一个小翻译,用于一个很小的函数式语言here。请特别注意eval功能。您的问题更简单,因为您没有变量,所以您不需要我的vars字典,而且您总是返回int结果,因此您不需要value工会类型。

要评估整数表达式,您只需评估子表达式并使用它们执行简单的操作。这是最优雅的模式匹配:

type Expr =
  | Int of int
  | Neg of Expr
  | Add of Expr * Expr
  | Mul of Expr * Expr

let rec eval = function
  | Int n -> n
  | Neg f -> -eval f
  | Add(f, g) -> eval f + eval g
  | Mul(f, g) -> eval f * eval g

例如:

Mul(Int 2, Neg(Int 3)) |> eval

模式匹配的优点是您可以根据数据结构的内容和形状添加更复杂的操作。例如:

| Add(f, Neg g) -> eval f - eval g

在你知道之前,你正在做computer algebra