作为对Why can't generic function templates use fnx to ensure they are tail-recursive?的跟踪,在阅读了Compiler Friendly Tail Recursion + Tail Recursion Checking in ATS之后,我想看看我是否可以确保我的函数是否优化了尾调用或编译失败。这是功能:
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)
但是它不能编译,似乎不喜欢泛型类型参数。因此,我将定义放入第三个父函数中,该父函数具有泛型参数,并仅调用相互递归对。
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.
因此,标题中的问题。
答案 0 :(得分:1)
使用“ fnx”定义相互递归函数时,只有第一个定义的函数可用于后续使用。