调试F#代码和功能样式

时间:2010-04-23 07:33:25

标签: debugging f# functional-programming

我是功能编程的新手,对编码风格和调试有一些疑问。

我的印象是,应该避免在temp变量中存储函数的结果,然后返回该变量

e.g。

let someFunc foo =
    let result = match foo with
                 | x -> ...
                 | y -> ...
    result 

而是这样做(我可能会离开?):

let someFunc foo =
    match foo with
    | x -> ...
    | y -> ...

从功能全局的角度来看,它可以正常工作,但它使调试变得更加困难。 如果 - >的右边,我无法检查结果。做一些时髦的东西。

那么我应该如何处理这种情况?

4 个答案:

答案 0 :(得分:23)

要检查管道的中间部分,我建议采用以下解决方法:

将此代码放在某个地方:

[<AutoOpen>]
module AutoOpenModule

#if DEBUG
let (|>) value func =
  let result = func value
  result
#endif

启用“在托管代码中单步执行属性和操作符”:

https://msdn.microsoft.com/en-us/library/cc667388(v=vs.100).aspx

现在您应该能够进入管道运营商。

答案 1 :(得分:11)

这两种方式都是可以接受的,因为您只是绑定到本地不可变变量。

虽然有一个问题。如果你使用尾调用将它作为递归循环的一部分使用,那么使用temp变量的那个将消除尾调用,因此你的堆栈空间会增加。

答案 2 :(得分:5)

能够在VS中看到函数的返回值是一个长期存在的请求。其他中间表达值也是如此;例如,在F#中,您经常需要检查管道的中间部分,这很难做到。从某种意义上说,函数式编程意味着“较少的命名变量和局部变量”和“较大的表达式”,这确实会对当前一代调试器产生负面影响。 (另一方面,使用较少的可变性和较高的抽象性,希望您在调试器中花费的时间更少。)

未来的调试器仍有很多方法可以改进......

另见

Do some Functional programming constructs reduce Debuggability?

答案 3 :(得分:4)

如果你使用了临时工,我就不会开枪了,但是我也不会因为我需要在调试中看到一些东西而冒犯我的风格。

此外,使用Visual Studio 2010的可视化调试器可以更轻松地调试此类事情,因为您可以在每个可能的匹配表达式中使用断点。还有快速手表和其他很棒的功能。

有关Visual Studio调试器中的最新功能的列表: http://msdn.microsoft.com/en-us/library/01xdt7cs.aspx