为什么匹配模式中的嵌套递归调用不起作用?

Why is this nested recursive call in a match pattern not working?

我写了一个简单的函数来复制每个 列表中的元素指定次数。

    let rec replicate l n = 
        let rec f l n acc = 
            match l with 
            |[]->acc
            |x::xs->f xs n (let rec h e n acc = if n = 0 then acc else h e (n-1) (e::acc) in h x n acc) 
        in List.rev (f l n [])

这是我调用 f 并将其累加器设置为辅助方法 h

的结果时的工作方式

但是为什么下面的方法不行呢?

let rec replicate l n = 
    let rec f l n acc = 
        match l with 
        |[]->acc
        |x::xs->(let rec h e n acc = if n = 0 
        then f xs n acc else h e (n-1) (e::acc) 
        in h x n acc) 
    in f l n [];;

在这里我调用外部函数f以防n=0.

以下是使用这两个函数进行相同调用的结果:

  1. 复制[“a”; “乙”; "c"] 3;;
  1. 复制[“a”; “乙”; "c"] 3;;

第二行

let rec h e n acc = 
  if n = 0 then f xs n acc
  else h e (n-1) (e::acc) 
in h x n acc

您正在用 n=0 调用 f xs n acc 而不是 n 的初始值。

作为一般建议,最好不要嵌套递归函数定义。实际上,这限制了函数控制流的复杂性。 例如,

let rec repeated_append n x l =
  if n = 0 then l
  else repeated_append (n-1) x (x::l)

let replicate n l = 
  let rec replicate_aux n acc l = 
    match l with 
    | [] -> List.rev acc
    | x::xs-> replicate_aux n (repeated_append n x acc) xs
  in
  replicate_aux n [] l

我保证递归函数repeated_appendreplicate_append只会在它们的函数体中调用它们自己。特别是,不可能 h 调用 replicatef 这使得函数更易于阅读。