[解決済み] OCaml/F#の関数はなぜデフォルトで再帰的でないのですか?
質問
F#やOCamlの関数が(おそらく他の言語も)デフォルトで再帰的でないのはなぜですか?
言い換えれば、なぜ言語設計者は、明示的にあなたが
rec
のような宣言で
let rec foo ... = ...
で、デフォルトで関数に再帰的な機能を与えないのですか? なぜ、明示的に
rec
を構成する必要があるのでしょうか?
どのように解決するのですか?
元のMLの子孫であるフランスやイギリスは異なる選択をし、その選択は何十年もかけて現代の変種に受け継がれています。ですから、これは単なるレガシーですが、これらの言語のイディオムに影響を及ぼしているのです。
フランスのCAML言語群(OCamlを含む)では、関数はデフォルトで再帰的ではありません。この選択により、関数(と変数)定義を
let
を使用した関数(および変数)の定義が容易になります。なぜなら、新しい定義の本文中で以前の定義を参照できるからです。F#はこの構文をOCamlから継承しています。
例えば、関数の上位にある
p
という関数に置き換えます。
let shannon fold p =
let p x = p x *. log(p x) /. log 2.0 in
let p t x = t +. p x in
-. fold p 0.0
引数
p
を高次の
shannon
関数は、その上位にある別の
p
が本文の最初の行にあり、さらに別の
p
を本文の2行目に記述します。
逆に、ML言語群のイギリスSML支部は、もう一方の選択肢を取り、SMLの
fun
-の関数は,デフォルトで再帰的です.ほとんどの関数定義が,関数名の以前のバインディングにアクセスする 必要がない場合,これはより単純なコードになります.しかし,継承された関数が異なる名前(
f1
,
f2
など) を使用すると、スコープが汚染され、誤って間違った関数の "バージョン" を呼び出してしまう可能性があります。また、暗黙的に再帰的な
fun
-結合関数と非再帰的な
val
-バウンド関数です。
Haskellは、定義が純粋であることを制限することによって、定義間の依存関係を推測することを可能にしています。これにより、おもちゃのサンプルはよりシンプルに見えますが、他の部分で重大な犠牲を払っているのです。
GaneshとEddieが出した答えは、赤毛であることに注意してください。彼らは、なぜ関数のグループが巨大な
let rec ... and ...
の中に置くことができないのは、型変数が汎化されるときに影響するからだと説明しました。これは
rec
がSMLではデフォルトであるがOCamlではデフォルトでないこととは無関係です。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン