私は絶対OCaml初心者です。私は文字を20回繰り返す関数を作りたいと思っています。 これは機能ですが、エラーのために機能しません。OCamlで文字列を繰り返す再帰関数
let string20 s =
let n = 20 in
s^string20 s (n - 1);;
string20 "u";;
私はこの
# string20 "u"
- : string = "uuuuuuuuuuuuuuuuuuuu"
私は絶対OCaml初心者です。私は文字を20回繰り返す関数を作りたいと思っています。 これは機能ですが、エラーのために機能しません。OCamlで文字列を繰り返す再帰関数
let string20 s =
let n = 20 in
s^string20 s (n - 1);;
string20 "u";;
私はこの
# string20 "u"
- : string = "uuuuuuuuuuuuuuuuuuuu"
あなたの関数のように実行したいstring20
、1つのパラメータを取りますが、あなたは、2つのパラメータで再帰的にそれを呼び出しています。
基本的な考え方はそこにありますが、正しい形式ではありません。続行する1つの方法は、2パラメータ関数を別の "ヘルパー"関数として分離することです。 @PierreGが指摘するように、ヘルパー関数を再帰関数としてdelcareする必要があります。あなたは一つのパラメータを取るためにあなたの関数を定義したが、あなたは再帰的に2で呼び出すようにしようとしているコメントで指摘したようにOCamlでは
let rec
あなたは、おそらく「固定」部分および誘導部分に機能を分離するための一般的なパターンです
let rec stringn s n =
match n with
1 -> s
| _ -> s^stringn s (n - 1)
;;
let rec string n s =
if n = 0 then "" else s^string (n - 1) s
let string20 = string 20
ような何かをしたいです。この場合、入力文字列s
を定数として修正したいので、新しい範囲で実際の再帰的な作業を行うにはネストされたヘルパー関数が必要です。したがって、s2
に追加するために使用できます。 s2
は、時間の経過とともに列列を構築するアキュムレータですが、c
は、ベースケースに向かって1までカウントダウンするインダクタです。サイドノートでは
let rec repeat s n =
if n = 0 then "" else s^repeat s (n - 1)
、最初と関数型言語についての1つの非常に楽しい事:あなたがすべてでヘルパー機能を必要としないので
let repeat s n =
let rec helper s1 n1 =
if n1 = 0 then s1 else helper (s1^s) (n1 - 1)
in helper "" n
非末尾呼び出しのバージョンは、より簡単ですOcamlのような-class関数はcurrying(または部分的なアプリケーション)です。 n
引数が標識された場合
# (* top-level *)
# let repeat_foo = repeat "foo";;
# repeat_foo 5;;
- : bytes = "foofoofoofoofoo" (* top-level output *)
:この場合、あなたは次のようにn
またはs
のいずれかにそれを適用する上で、一部のようにタイプint
とタイプstring
のs
の二つの引数n
を取るrepeat
という名前の関数を作成することができます以下のように:
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を参照してください。
実際に動作させるためには、あなたのtail-recursive 'helper'は基底の' s2'をより良く返し、 's'の代わりに' '' 'で呼び出すべきです。また、 's1'は冗長です。あなたの最後の例では '〜n'というラベルはどこから来ますか? –
@AndreasRossbergはい訂正ありがとうございます。私はまた、分かりやすくするために、ラベル付き引数バージョンを追加しました。 – PieOhPah
私は「ヘルパー」への呼び出しがまだ間違っていると信じています。空の文字列で呼び出す必要があります。 –
まず、再帰関数の停止条件について考える必要があります。次に、再帰関数を宣言するためにocamlに適用する構文を知っておく必要があります(これはコースのレベルです)。 –
受け取っているエラーを入れてください。 – AlexKoren
話題をはずしましたが、 'String.make 20 'は仕事をします。 – camlspotter