如何获得此 ocaml 代码的正确结果?

问题描述 投票:0回答:2

代码:

let a=ref 0

type t = 
| Int of string
| Add of t * t

let rec makestring_t =function
|Int a->a
|Add (b,c)->
 incr a;
 "(Add"^string_of_int(!a)^" ("^makestring_t(b)^" "^makestring_t(c)^"))"

let ()=let a=Add(Int("1"),Add(Int("2"),Int("3"))) in 
 print_string(makestring_t a)

得到:

(Add2 (1 (Add2 (2 3))))

但我想得到答案:

(Add1 (1 (Add2 (2 3))))

那么如何得到正确答案呢?

ocaml
2个回答
1
投票

您错误地假设表达式的求值顺序是从左到右。要保证特定的求值顺序,请使用序列运算符

;
let ... in

let rec makestring_t = function
| Int a -> a
| Add (b, c) ->
  incr a;
  let n = !a in
  "(Add" ^ string_of_int n ^ " (" ^ makestring_t b ^" "^makestring_t c ^ "))"

0
投票

您还可以显式提供计数器变量作为函数参数(例如在元组中),然后它将打印可能感兴趣的递归级别。在这种情况下,您应该在第一次调用中提供基本级别,但您可以使用包装表达式从 1 开始。

type t = 
| Int of string
| Add of t * t

let rec makestringn_t =function
|(Int a, _)->a
|(Add (b,c), n)->
 "(Add"^string_of_int(n)^" ("^makestringn_t((b, n+1))^" "^makestringn_t((c, n+1))^"))"

let makestring_t a = makestringn_t (a, 1)

let ()=let a=Add(Int("1"),Add(Int("2"),Int("3"))) in 
 print_endline(makestring_t a)

let ()=let a=Add(Add(Int("1"), Int("2")), Add(Int("3"),Int("4"))) in 
 print_endline(makestring_t a)

结果:

(Add1 (1 (Add2 (2 3))))
(Add1 ((Add2 (1 2)) (Add2 (3 4))))

type t = Int of string | Add of t * t
val makestringn_t : t * int -> string = <fun>
val makestring_t : t -> string = <fun>
© www.soinside.com 2019 - 2024. All rights reserved.