Debugging 如何诊断F#interactive中的故障源

Debugging 如何诊断F#interactive中的故障源,debugging,f#,f#-interactive,Debugging,F#,F# Interactive,我正在通过Euler项目学习F#的诀窍,并多次遇到以下问题。我编写一个函数,在F#交互式窗口中运行,程序挂在那里。我怀疑这个函数失败了,但我没有收到任何重要的错误消息,这将帮助我找出哪里出了问题。有没有办法调试在F#interactive中运行的程序? 作为说明,这里有一个问题12的例子。FindFirstTriangle(0,0100)运行良好,但当除数在150左右时,情况就会停滞。 注意:这不是关于这段代码的错误,而是关于如何找出哪里出了问题 let NumberOfDivisors n =

我正在通过Euler项目学习F#的诀窍,并多次遇到以下问题。我编写一个函数,在F#交互式窗口中运行,程序挂在那里。我怀疑这个函数失败了,但我没有收到任何重要的错误消息,这将帮助我找出哪里出了问题。有没有办法调试在F#interactive中运行的程序?
作为说明,这里有一个问题12的例子。FindFirstTriangle(0,0100)运行良好,但当除数在150左右时,情况就会停滞。
注意:这不是关于这段代码的错误,而是关于如何找出哪里出了问题

let NumberOfDivisors n =
  [1 .. n] |> List.filter (fun i -> n % i = 0) |> List.length;;

let HasMoreThanDDivisors n d =
  if NumberOfDivisors n >= d then
    true
  else
    false

let rec FindFirstTriangle (index, number, divisors) =
  if HasMoreThanDDivisors number divisors then
    number
  else
    let nextIndex = index + 1
    let nextNumber = number + index
    FindFirstTriangle (nextIndex, nextNumber, divisors);;

如果您运行了例如“windows任务管理器”,您将看到挂起该设备时,您的CPU已耗尽。你只是创造了太多的工作;你需要一个更有效的算法。按F#interactive中的“中断”键(在Visual Studio的FSI窗口中按Ctrl-)停止处理

如果大OH不清楚,你可以考虑添加一些指纹来显示正在做多少工作。例如

let NumberOfDivisors n = 
  printf "%d" n // added
  seq {1 .. n} |> Seq.filter (fun i -> n % i = 0) |> Seq.length;; 

let HasMoreThanDDivisors n d = 
  if NumberOfDivisors n >= d then 
    true 
  else 
    false 

let rec FindFirstTriangle (index, number, divisors) = 
  printfn "" // added
  if HasMoreThanDDivisors number divisors then 
    number 
  else 
    let nextIndex = index + 1 
    let nextNumber = number + index 
    FindFirstTriangle (nextIndex, nextNumber, divisors);;

然后用越来越大的数字运行FindFirstTriangle,以了解发生了什么。

程序挂起通常有两个原因:

  • 死环

  • 无效代码

  • 在FP语言(如F#)中,很少会编写一个永远运行的死循环

    这是我在执行Euler时的调试偏差:

  • 使用小测试用例测试每个功能。编写函数后,请对其进行测试。算法不太可能适用于1-100并且在101时失败,特别是当您使用像F#这样的“安全”语言时

  • 估计算法的运行时间。如果是O(n^2),那么n=10000可能是算法的上限。在这个问题中,答案是超过70M,一个暴力O(n^2)算法永远运行。而F#interactive提供了
    #time
    来分析程序的运行行为,比如运行时间和垃圾收集数量

  • 正如Brain所说,您需要一个更高效的
    numberofdivisions
    实现:

    谢谢你,布莱恩。Big-O很清楚,我知道我的算法效率很低,但我不确定问题是性能差,还是发生了异常。我认为应该归咎于性能:)是的,如果出现异常,你会得到反馈-尝试一下(在某个地方添加一个“raise(newexception(“boom”)”),看看互动效果如何。另外,从你的回答中,我认为在Interactive中运行时没有办法使用断点或监视?我认为将代码放入项目并调试项目更容易调试。感谢ToClient函数的链接,非常有趣。