在OCaml中重复字符串的递归函数

时间:2017-09-22 17:39:18

标签: recursion ocaml

我绝对是OCaml初学者。我想创建一个重复字符20次的函数。 这是函数,但由于错误而无效。

let string20 s =
  let n = 20 in
  s ^ string20 s (n - 1);;

string20 "u";;

我想像这样跑

# string20 "u"
- : string = "uuuuuuuuuuuuuuuuuuuu"

4 个答案:

答案 0 :(得分:1)

你的函数string20有一个参数,但是你用2个参数递归调用它。

基本的想法在那里,但不是很正确的形式。一种方法是将2参数函数分离为单独的"帮助"功能。正如@PierreG指出的那样,你需要将辅助函数作为递归函数进行delcare。

答案 1 :(得分:0)

  1. Ocaml中的递归函数使用let rec
  2. 定义
  3. 正如评论中所指出的,你已经定义了你的函数来获取一个参数,但是你试图用两个递归调用。
  4.   

    你可能想要像

    这样的东西
    let rec stringn s n =
      match n with
      1 -> s
    | _ -> s ^ stringn s (n - 1)
    ;;
    

答案 2 :(得分:0)

let rec string n s =
  if n = 0 then "" else s ^ string (n - 1) s

let string20 = string 20

答案 3 :(得分:0)

将函数分成" fixed"是一种常见的模式。部分和归纳部分。在这种情况下,需要一个嵌套的辅助函数来在新范围内进行真正的递归工作,同时我们想要将输入字符串s修复为常量,以便我们可以使用它来附加到s2s2是一个累加器,可以随着时间的推移建立一串字符串,而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等一流功能的函数式语言的一个非常有趣的事情是currying(或部分应用程序)。在这种情况下,您可以创建一个名为repeat的函数,该函数接受两个类型为n int的{​​{1}}和类型为s的{​​{1}},并将其部分应用于这样的stringn

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)

请参阅我的帖子Currying Exercise in JavaScript(虽然它在JavaScript中,但很容易理解)和lambda calculus primer