调试F#代码和功能样式

Rog*_*son 24 debugging f# functional-programming

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

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

例如

let someFunc foo =
    let result = match foo with
                 | x -> ...
                 | y -> ...
    result 
Run Code Online (Sandbox Code Playgroud)

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

let someFunc foo =
    match foo with
    | x -> ...
    | y -> ...
Run Code Online (Sandbox Code Playgroud)

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

那我该怎么处理这种情况呢?

Old*_*vec 24

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

将此代码放在某个地方:

[<AutoOpen>]
module AutoOpenModule

#if DEBUG
let (|>) value func =
  let result = func value
  result
#endif
Run Code Online (Sandbox Code Playgroud)

启用"进入托管代码中的属性和操作符":

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

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


lep*_*pie 11

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

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


Bri*_*ian 6

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

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

也可以看看

一些函数式编程构造是否会降低可调性?