我正在尝试为以下代码找到一种功能正确的方法:
let mutable u = initialize cities pms
for i in 0 .. 10 do
u <- randomIteration u pms distances
randomIteration是一个简单的函数,它接受一个带有2个参数的数组并返回一个修改过的数组。这个过程必须重复n次(此处为10)。
我提出了一个使用折叠的解决方案,但我正在创建一个“虚拟”序列,只是为了能够折叠它,这似乎不正确。
let result = Seq.init 10 (fun i -> i) |> Seq.fold (fun uNext i -> randomIteration uNext pms distances) u
我也可以使用带有计数器变量的递归,但这似乎很尴尬。我只是错过了一个简单的正确解决方案吗?
答案 0 :(得分:5)
我也可以使用带有计数器变量的递归,但这似乎很尴尬。
这对我来说似乎很自然:允许一个调用的结果传递给下一个没有可变状态的调用。类似的东西:
let interateSelf func initial count =
let inner intermediate n =
if n = 1 then
func intermediate
else
inner (func intermediate) (n - 1)
inner initial count
答案 1 :(得分:3)
只是想在这里开箱即思考,但不是每次都用不同的参数折叠randomIteration
,你可以创建一个N randomIteration
次调用链并调用此链一次:
let repeat n =
Seq.init n (fun _ u -> randomIteration u pms distances)
|> Seq.reduce (>>)
initialize cities pms
|> repeat 10
|> printfn "Result: %A"
答案 2 :(得分:2)
一个简单的改变就是使用序列表达而不是Seq.init
。
let result = {1..10}
|> Seq.fold (fun uNext i -> randomIteration uNext pms distances) u
如果你真的想保留Seq.init
,可以用这样的内置函数替换识别函数:
let result = Seq.init 10 id
|> Seq.fold (fun uNext i -> randomIteration uNext pms distances) u
另一种方法是创建一个这样的递归函数:
let result = let rec loop x i =
match i with
| 0 -> x
| i -> loop (randomIteration x pms) (i-1)
loop u 10
答案 3 :(得分:0)
这只是Nikon-the-Third回答的一个细微变化。可以创建一个更通用的函数,该函数重复应用另一种函数:
let repeat n fn = List.init n (fun _ -> fn) |> List.reduce (>>)
然后可以使用它创建一个重复前10次的命名函数:
let getNext10Times = repeat 10 (fun u -> randomIteration u pms distances)
getNext10Times u
或者可以匿名使用:
u |> repeat 10 (fun u -> randomIteration u pms distances)