F#将函数应用于它的结果n次

时间:2015-02-27 16:22:56

标签: f# functional-programming

我正在尝试为以下代码找到一种功能正确的方法:

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

我也可以使用带有计数器变量的递归,但这似乎很尴尬。我只是错过了一个简单的正确解决方案吗?

4 个答案:

答案 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)