решение, которое предлагает Брайан, определенно является лучшим вариантом (в F #). Выражения последовательности дают вам более простой способ выразить то, что вы имеете в виду, так почему бы не использовать их?
В любом случае, если вы делаете это просто как упражнение, то вы можете переписать вложенный цикл как одну рекурсивную функцию, а внешний цикл - как второй (как предлагает 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)
Я использую :: во вложенной функции для добавления элементов в начало и @ для объединения списков, генерируемых отдельными вызовами вложенных функций. Использование @ не очень эффективно, и код также не является рекурсивным, поэтому лучшая версия с использованием параметра аккумулятора будет выглядеть так:
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
Надеюсь, это поможет!