Recursion 用于在OCaml中重复字符串的递归函数
我绝对是OCaml初学者。我想创建一个重复字符20次的函数。 这是函数,但由于错误而无法工作Recursion 用于在OCaml中重复字符串的递归函数,recursion,ocaml,Recursion,Ocaml,我绝对是OCaml初学者。我想创建一个重复字符20次的函数。 这是函数,但由于错误而无法工作 let string20 s = let n = 20 in s ^ string20 s (n - 1);; string20 "u";; 我想这样跑 # string20 "u" - : string = "uuuuuuuuuuuuuuuuuuuu" 函数string20接受一个参数,但使用两个参数递归调用 基本思想在那里,但形式不太正确。一种方法是将2参数函数作为单独的“助手”函数分
let string20 s =
let n = 20 in
s ^ string20 s (n - 1);;
string20 "u";;
我想这样跑
# string20 "u"
- : string = "uuuuuuuuuuuuuuuuuuuu"
函数
string20
接受一个参数,但使用两个参数递归调用
基本思想在那里,但形式不太正确。一种方法是将2参数函数作为单独的“助手”函数分离出来。正如@PierreG所指出的,您需要将helper函数作为递归函数进行delcare
let rec
将函数分为“固定”部分和归纳部分是一种常见的模式。在这种情况下,需要一个嵌套的helper函数来在新范围内执行真正的递归工作,同时我们要将输入字符串
s
固定为常量,以便我们可以使用它附加到s2
s2
是一个累加器,随着时间的推移形成串,而c
是一个朝着基本情况向下计数至1的电感器
let repeat s n =
let rec helper s1 n1 =
if n1 = 0 then s1 else helper (s1 ^ s) (n1 - 1)
in helper "" n
非尾部调用版本更简单,因为您根本不需要助手函数:
let rec repeat s n =
if n = 0 then "" else s ^ repeat s (n - 1)
另一方面,关于一种具有像Ocaml这样的一流函数的函数式语言,有一件非常有趣的事情就是curry(或部分应用程序)。在这种情况下,您可以创建一个名为repeat
的函数,该函数接受类型为int
的n
和类型为string
的s
两个参数,并将其部分应用于n
或s
,如下所示:
# (* top-level *)
# let repeat_foo = repeat "foo";;
# repeat_foo 5;;
- : bytes = "foofoofoofoofoo" (* top-level output *)
如果n
参数标记如下:
let rec repeat ?(n = 0) s =
if n = 0 then "" else s ^ repeat s (n - 1)
可以利用应用程序的顺序,使功能更加灵活:
# (* top-level *)
# let repeat_10 = repeat ~n:10;;
# repeat_10 "foo";;
- : bytes = "foofoofoofoofoofoofoofoofoofoo" (* top-level output *)
请参阅我的帖子(虽然它是用JavaScript编写的,但很容易理解)。您应该首先考虑递归函数的停止条件。然后,您应该知道在ocaml中声明递归函数时应用的语法(这是ocaml课程级别)。您能输入收到的错误吗?有点离题,但
String.make 20'u'
可以完成此任务。string20
接受单个参数s
,但是在第二次通话和之后提供了s
和n-1
。您将此问题编辑得面目全非,因此我将其回滚,因为原始问题有几个很好的答案。命名stringn
是非常多余的,由于Ocaml函数是curry函数,您可以执行类似于let stringN=string N in stringN“foo”
的操作,您上面的函数是一个无限递归,因为没有基本情况,而且N
永远不会减少。@PieOhPah。感谢我错过了(n-1)。要真正工作,您的尾部递归助手
应该最好在基本情况下返回s2
,并使用“
而不是s
调用。而且,s1
是冗余的。您上一个示例中的标签~n
来自哪里?@AndreasRossberg是的,谢谢您的更正。为了更清晰,我还添加了带标签的参数版本。我相信对helper
的调用仍然是错误的。您需要使用空字符串调用它,否则您将被取消1。
let rec repeat ?(n = 0) s =
if n = 0 then "" else s ^ repeat s (n - 1)
# (* top-level *)
# let repeat_10 = repeat ~n:10;;
# repeat_10 "foo";;
- : bytes = "foofoofoofoofoofoofoofoofoofoo" (* top-level output *)