[英]F# Quality of Life Questions
大约2个月前我开始在F#编码。
我非常喜欢这种编程语言。 我来自C#背景,每次我需要恢复到C#时,它感觉如此繁琐和臃肿。
但是我认为在F#中仍有一些问题,这就是我的问题与之相关:
没有自动完成像VS有C#对吗? 例如,在一个带参数aParameter的函数中,如果我写aPara,则不会出现自动完成。 VS内部是否有可以解决此问题且我不知道的功能?
调试至少可以说是乏味的。 由于F#支持管道/链接或任何你想要的东西,我通常会尝试尽可能多地链接(当然,无论哪个地方都有意义)。 例:
correctedData |> List.filter (fun (_, r, _) -> r <= 3) |> Seq.ofList |> Seq.groupBy (fun (_, r, cti) -> (r,cti)) |> Seq.map (fun ((r,cti),xs) -> (r, cti, Seq.length xs)) |> Seq.toList
这只是我整个链接的四分之一。 每当我把这些链中的东西搞得一团糟时,我发现很难调试它出错的地方。
我这样做的链条错误(滥用它)? 从我的观点来看,这种链接的任何中介都没有理由以原子方式存在,因此没有理由拥有中间价值。 但是由于这种语义观点,我也失去了使用中间值来帮助我调试的能力。 那么我必须在代码中插入它们,调试,然后再次删除它们。 但这是一种浪费的努力。 有没有办法解决?
此外,调整链中的List.map匿名函数与例如for循环相比再次感觉尴尬和困难。
我确信我错过了一些东西,而且我目前的调试方式可能不是最佳的 - 不是长篇大论 - 所以欢迎任何建议。
1.对于C#,VS没有自动完成
F#有自动完成功能。 但是,当您开始输入时,它不会自动触发。 如果您在Visual Studio中并键入aPara
然后按Ctrl + Space ,则它应自动完成到aParameter
如果它在范围内)。 同样,您可以在顶级作用域中执行此操作以查看可用的类型和名称空间。 键入时自动完成也会自动触发.
至少可以说,调试很乏味
我同意这一点 - 调试管道(尤其是延迟序列)很棘手。 即使你在C#中,这也有点令人困惑,但C#在这一方面做得非常出色。 有两种方法可以解决这个问题:
更多使用F#Interactive。 我首先在F#Script文件中编写了大部分代码,您可以在其中运行部分完整的解决方案并立即查看结果。 对我来说,这几乎取代了调试,因为到我的代码完成时,我知道它有效。
您可以定义一个功能tap
,它实现管道中的数据,并让您查看管道中的数据。 我不太习惯这个,但我知道有些人喜欢它:
let tap data = let materialized = List.ofSeq data materialized
然后你可以在你的管道中使用它:
correctedData |> List.filter (fun (_, r, _) -> r <= 3) |> tap |> Seq.groupBy (fun (_, r, cti) -> (r,cti)) |> tap |> Seq.map (fun ((r,cti),xs) -> (r, cti, Seq.length xs)) |> Seq.toList
这会给管道增加一些噪音,但是一旦完成调试就可以再次删除它。
使用F#改善调试体验的问题涉及很多方面,因此值得一篇大文章。 所以我担心这个问题会被关闭。
不过,这里有两个我正在使用的巧妙技巧。 我必须指出,我也是管道方法的忠实粉丝,因此我面临着完全相同的问题。
了解你的类型。
通过一系列转换链接一个值可能很快导致难以在每一步记住确切的类型。 诀窍是:
value
|> transformation1
|> fun x -> x
|> transformation2
这可以让你:
x
的确切类型; 有条件地将值转储到控制台。
复杂的lambdas,断点可能没什么帮助。 这是另一个技巧,与@Tomas答案中描述的相关:编写一个小函数,如下所示:
let inline debug x =
#if DEBUG
if System.Console.CapsLock then
printfn "%A" x
// obviously, it must not be necessarily printf;
// it can be System.Diagnostics.Debug.WriteLine()
// or any other logger tool that exists in the project.
#endif
x
使用代码如下所示:
value
|> transformation1
|> fun x -> x
|> debug
|> transformation2
这个想法是:
debug
调用之前设置一个断点,就像上面描述的那样; 如果您有多个debug
调用位置,它们不会破坏输出。
在调试|>管道问题上 - 尝试使用个人编码标准,在这样的管道中,您没有超过三行或最多四行。 当它们比这更长时,重构。 这就是我所做的,它有很大帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.