2017-09-22 64 views
1

我是绝对的OCaml初学者。我想创建一个重复20次字符的函数。 这是功能,但由于错误而无法使用。在OCaml中重复字符串的递归函数

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

string20 "u";; 

我想这样

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

您应该首先考虑递归函数的停止条件。然后,你应该知道在ocaml中应用的语法来声明一个递归函数(这是ocaml课程级别)。 –

+2

你能否把你收到的错误放进去? – AlexKoren

+0

关闭主题,但'String.make 20'u''完成这项工作。 – camlspotter

回答

1

你的功能string20运行需要一个参数,但你有两个参数的递归调用它。

基本的想法在那里,但不是正确的形式。继续进行的一种方法是将2参数函数分离为单独的“帮助”函数。正如@PierreG指出的那样,您需要将辅助函数作为递归函数进行修改。 OCaml中

0
  1. 递归函数与let rec
  2. 定义为评论指出你定义你的函数取一个参数,但你想递归地两个人叫。

你可能要像

let rec stringn s n = 
    match n with 
    1 -> s 
| _ -> s^stringn s (n - 1) 
;; 
+0

命名'stringn'是相当多余的,因为Ocaml函数是curried的,你可以像'let stringN = stringN'stringN'foo'' – PieOhPah

+0

'''''''''''''''''''永远不会减少。 – PieOhPah

+0

@ PieOhPah。谢谢,我错过了(n - 1)。 –

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

let string20 = string 20 
0

这是一个功能分为“固定”部分和感性部分的通用模式。在这种情况下,我们需要一个嵌套帮助函数来在新范围内进行真正的递归工作,同时我们要将输入字符串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函数有两个参数intn和如上,部分应用到任何ns这样string类型的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 *) 

查看我的帖子Currying Exercise in JavaScript(尽管它在JavaScript中,但很容易遵循)和这个lambda calculus primer

+0

为了实际工作,你的尾递归“帮助器”应该更好地在基本情况下返回's2',并用''“'而不是's'来调用。另外,'s1'是多余的。你最后一个例子中的标签'〜n'从哪里来? –

+0

@AndreasRossberg是的,谢谢你的更正。为了更清晰,我还添加了标签参数版本。 – PieOhPah

+0

我相信对'helper'的调用仍然是错误的。你需要用空字符串来调用它,否则你就会关闭一个。 –