你好,我被告知了这个问题:
编写F#函数 toString:aexpr->字符串以格式化表达式 作为字符串,二进制运算符以inix格式编写。对于 例如,它可以将 Sub(Var“ x”,CstI 34)格式化为字符串“ x- 34“ 。为简单起见,请在所有子表达式中加上括号,即使是 当它们根据标准优先规则是多余的时 适用于算术运算符。使用预定义的函数字符串进行转换 字符串表示形式的整数值。
提示:toString具有与eval函数几乎相同的结构, 尽管它不需要环境参数,因为它使用变量 名称,而不是变量值。
是的,这是硬件问题。任何帮助将不胜感激与解释。下面我包括了一个评估函数
这些是我们一直在使用的数据类型:
type oper1 = Neg | Not
type oper2 = Add | Mul | Sub | Less | Eq | And
type aexpr =
| C of int
| V of string
| Op1 of oper1 * aexpr
| Op2 of oper2 * aexpr * aexpr
let rec eval e (env : (string * int) list) : int =
match e with
| CstI i -> i
| Var x -> lookup env x
| Prim("+", e1, e2) -> (eval e1 env) + (eval e2 env)
| Prim("*", e1, e2) -> (eval e1 env) * (eval e2 env)
| Prim("-", e1, e2) -> (eval e1 env) - (eval e2 env)
| Prim _ -> failwith "unknown primitive"
| Let(x, e1, e2) -> eval e2 ((x, eval e1 env) :: env)
所以对于给定的问题,我写了:
let rec toString e (env : (string * int) list) : string
match e with
| Prim("+", e1, e2) -> "e1 + e2"
| Prim("*", e1, e2) -> "e1 - e2"
| Prim("-", e1, e2) -> "e1 * e2"
这看起来很愚蠢,还是我走对了?对F#来说还很新
答案 0 :(得分:1)
问题指出:
[...]尽管不需要环境参数[...]
所以您的函数toString
应该看起来像这样:
let rec toString e =
match e with
| CstI i -> sprintf "%i" i // format number as string
| Var x -> x // already a string
| Prim("+", e1, e2) -> sprintf "(%s + %s)" (toString e1) (toString e2)
| Prim("*", e1, e2) -> sprintf "(%s * %s)" (toString e1) (toString e2)
| Prim("-", e1, e2) -> sprintf "(%s - %s)" (toString e1) (toString e2)
对于嵌套表达式,toString
首先在子表达式上被调用。然后将所得的字符串插入%s
中的sprintf
中。