为什么我不能调用本地定义的相互递归函数的后半部分?

Why can't I call the second half of a mutually recursive function that's defined locally?

作为 , and after reading 的后续,我想看看我是否可以确保我的函数得到 tail-call 优化,或者无法编译。这是函数:

fun {a:t@ype} repeat {n:nat} .<n>.
( x: a
, t: int n
, f: a -> a
) : a =
  if t = 0 then x
  else repeat (f x, t - 1, f)

所以首先我把它变成了一个简单的相互递归函数,像这样:

fnx {a:t@ype} repeat1 {n:nat} .<n>.
( x: a
, t: int n
, f: a -> a
) : a =
  if t = 0 then x
  else repeat1 (f x, t - 1, f)
and {a:t@ype} repeat2 {n:nat} .<>.
( x: a
, t: int n
, f: a -> a
) : a = repeat1 (x, t, f)

但这并不能编译,似乎它不喜欢泛型类型参数。所以我将定义放在第三个 parent 函数中,该函数具有通用参数并且只调用相互递归对。

fun {a:t@ype} repeat {n:nat} .<n>.
( x: a
, t: int n
, f: a -> a
) : a =
let
  fnx repeat1 {n:nat} .<n>.
  ( x: a
  , t: int n
  , f: a -> a
  ) : a =
    if t = 0 then x
    else repeat1 (f x, t - 1, f)
  and repeat2 {n:nat} .<>.
  ( x: a
  , t: int n
  , f: a -> a
  ) : a = repeat1 (x, t, f)
in
  repeat1 (x, t, f)
end

中提琴,编译成功!但是后来我尝试在最后一行调用 repeat2 而不是 repeat1,如下所示:

fun {a:t@ype} repeat {n:nat} .<n>.
  //snip...
in
  repeat2 (x, t, f)
end

编译失败,错误:

the dynamic identifier [repeat2] is unrecognized.

因此,标题中的问题。

当您使用'fnx'定义相互递归函数时,只有第一个定义的函数可供后续使用。