次のC#コードがあるとします。
var product = new List<int>();
for (int n1 = 100; n1 < 1000; n1++)
{
for (int n2 = 100; n2 < 1000; n2++)
{
product.Add(n1 * n2);
}
}
機能的なスタイルで記述された同等のF#コードは何でしょうか?
次のC#コードがあるとします。
var product = new List<int>();
for (int n1 = 100; n1 < 1000; n1++)
{
for (int n2 = 100; n2 < 1000; n2++)
{
product.Add(n1 * n2);
}
}
機能的なスタイルで記述された同等のF#コードは何でしょうか?
forループを使ってそのように書くだけです。Haskellプログラマーでさえ、おそらくリスト内包表記でこれを表現するでしょう。その場合、あなたは例えば
let productsList =
[for x in 2..4 do
for y in 2..4 do
yield x*y]
F#で。
ブライアンが提案するソリューションは間違いなく最良のオプションです(F#で)。シーケンス式を使用すると、意味を簡単に表現できるので、シーケンス式を使用してみませんか?
とにかく、これを演習として行う場合は、ネストされたループを単一の再帰関数として書き直し、外側のループを2番目として書き直すことができます(Imagistが示唆しているように)。
let product =
let rec outer(n1) =
let rec nested(n2) =
if n2 > 4 then [] else (n1 * n2)::(nested(n2 + 1))
if n1 > 4 then [] else nested(2) @ outer(n1 + 1)
outer(2)
ネストされた関数で::を使用して要素を先頭に追加し、@を使用して個々のネストされた関数呼び出しによって生成されたリストを連結しています。@の使用はあまり効率的ではなく、コードも末尾再帰ではないため、accumulatorパラメーターを使用するより良いバージョンは次のようになります。
let product =
let rec outer n1 acc =
let rec nested n2 acc =
if n2 > 4 then acc else nested (n2 + 1) ((n1 * n2)::acc)
if n1 > 4 then acc else outer (n1 + 1) (nested 2 acc)
outer 2 [] |> List.rev
お役に立てれば!