【问题标题】:Debugging F# code and functional style调试 F# 代码和函数样式
【发布时间】:2011-02-11 10:04:19
【问题描述】:

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

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

例如

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

而是这样做(我可能会走远?):

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

从功能的角度来看,这很好用,但它使调试变得更加困难。 如果 -> 的右侧做了一些奇怪的事情,我无法检查结果。

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

【问题讨论】:

    标签: debugging f# functional-programming


    【解决方案1】:

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

    把这段代码放在某个地方:

    [<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

    现在您应该可以进入管道操作员了。

    【讨论】:

    • 非常出色。现在,这是我们代码库的重要补充。
    【解决方案2】:

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

    未来的调试器还有很多可以改进的地方...

    另见

    Do some Functional programming constructs reduce Debuggability?

    【讨论】:

      【解决方案3】:

      任何一种方式都可以接受,因为您只是绑定到本地不可变变量。

      但有一个问题。如果您将其用作使用尾调用的递归循环的一部分,则使用 temp 变量将消除尾调用,因此您将增加堆栈空间。

      【讨论】:

      【解决方案4】:

      如果你使用 temp,我不会向你开枪,但我也不会因为我需要观看正在调试的东西而限制自己的风格。

      此外,使用 Visual Studio 2010 的可视化调试器调试这类事情要容易得多,因为您可以在每个可能的匹配表达式中使用断点。还有快速观看和其他很棒的功能。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-27
        • 2020-06-04
        • 2017-05-04
        • 1970-01-01
        • 1970-01-01
        • 2010-10-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多