2017-09-22 5 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'的調用仍然是錯誤的。你需要用空字符串來調用它,否則你就會關閉一個。 –