У меня проблемы с запуском следующей рекурсивной функции на нашем веб-сервере разработки. Это вызывает переполнение стека. Он работает нормально локально в режиме отладки. Вот что я пробовал:
- Убедитесь, что в параметрах сборки включен параметр «Генерировать вызовы».
- Я запустил дизассемблер и выполнил следующие инструкции: http://blogs.msdn.com/b/fsharpteam/archive/2011/07/08/tail-calls-in-fsharp.aspx, и он не не выглядит как для использования хвостовой рекурсии.
- Я пытался переписать его без использования рекурсии, но мои навыки F # не самые лучшие.
Так что мои вопросы будут:
- Эта функция будет в состоянии использовать хвостовые рекурсии?
- Почему он работает локально в режиме отладки через VS, а не на веб-сервере dev?
Спасибо!
let rec SimulationLoop (rowNum : int) (h : double) (time : double) (v : double) (s : double) (p : double) (newV' : double) (newS' : double) (newP' : double) (designParameters : DesignParameters) (inputs : ISimulationInputProvider) = seq {
//let timer = System.Diagnostics.Stopwatch.StartNew()
let finalTime = (6.0 * inputs.ShockAbsorber.Stroke / designParameters.VelocityAfterImpact)
let startH = StartH h time finalTime
let slopes = Slopes v s p newV' newS' newP' startH designParameters inputs
let vSlope, sSlope, pSlope = slopes
let betaList = [ for j in 0 .. 5 -> beta.[j].[4] ]
let newV' = CalcPrime v startH vSlope betaList
let newS' = CalcPrime s startH sSlope betaList
let newP' = CalcPrime p startH pSlope betaList
let delta = Delta h slopes
let tau = Tau v s p
let rowResult, rowNum, time, newV, newS, newP = if delta < tau then RecordResults rowNum time startH v s p slopes designParameters inputs else None, (rowNum + 1), time, v, s, p
let loop = newS < inputs.ShockAbsorber.Stroke - 0.01 && newV >= 0.0 && rowNum <= 8000 && (time < finalTime && time + h > time)
let stepLength = StrokeStepLength inputs.ShockAbsorber.Stroke designParameters.HoleSize
let endH = EndH delta startH tau stepLength newV
//timer.Stop()
//System.Diagnostics.Debug.WriteLine("Row: " + rowNum.ToString() + " = " + timer.ElapsedMilliseconds.ToString())
match (rowResult, loop) with
| Row(r), true ->
yield r
yield! SimulationLoop rowNum endH time newV newS newP newV' newS' newP' designParameters inputs
| Row(r), false ->
yield r
| None, true ->
yield! SimulationLoop rowNum endH time newV newS newP newV' newS' newP' designParameters inputs
| None, false -> ()
}