为什么我不能调用本地定义的相互递归函数的后半部分?
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'定义相互递归函数时,只有第一个定义的函数可供后续使用。
作为
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'定义相互递归函数时,只有第一个定义的函数可供后续使用。