F#伤害了我的大脑......任何人都可以帮助将C#翻译成F#吗?

use*_*250 3 c# f# c#-to-f#

我找到了一个快速的项目,我认为这对于学习F#是完美的.然而,由于某种原因,我无法将我的大脑包裹起来.经过几个小时的教程,甚至一些电影,我仍然只是......不明白.

所以我想使用Enterprise Manager"Generate Scripts"开始在工作中对我们的存储过程进行版本控制,并希望删除脚本日期.我放弃了,并在C#中做到了,但现在我真的很好奇,并希望有一些见解.

我不是空手而归,这是我的C#代码:

string path = @"C:\Subversion\CompanyName\SQL\DBName";
string fileSpec = "*.sql";
string pattern = @"Script Date: \d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}";
string replace = "Script Date: ";

foreach (var file in Directory.EnumerateFiles(path, fileSpec))
{
    string content = File.ReadAllText(file);

    content = Regex.Replace(content, pattern, replace);

    File.WriteAllText(file, content, Encoding.Unicode);
}
Run Code Online (Sandbox Code Playgroud)

我猜在F#中有一些很酷的2-3线解决方案...我很乐意看到它.

Thx的提示!我更新了它以匹配下面的内容,使视觉比较更具启发性.下面还有很棒的评论.

ild*_*arn 11

let path = @"C:\Subversion\CompanyName\SQL\DBName"
let fileSpec = "*.sql"
let pattern = @"Script Date: \d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}"
let replace = "Script Date: "

Directory.EnumerateFiles (path, fileSpec)
|> Seq.iter (fun file ->
    let content = Regex.Replace (File.ReadAllText file, pattern, replace)
    File.WriteAllText (file, content, Encoding.Unicode))
Run Code Online (Sandbox Code Playgroud)

请注意,您的C#代码(编辑:WAS)也远远超过必要的繁琐.

  • @Tomas:的确,但是一旦你厌倦了使用`for` /`while`,他们的弱点就会变得很明显,即缺少'continue`和`break`.也就是说,如果需要提前突破循环并且已经使用`for..in`编写循环,那么他们必须使用递归函数或高阶函数重写它; 但是如果一个人开始使用`Seq.iter`,那么切换到'Seq.tryPick`并将结果传递给`ignore`是没有痛苦的.至少这是我的理由.; - ] (3认同)
  • 你可以使用`for`代替`Seq.iter`来再保存一行.为什么在有内置语言构造时使用库函数? (2认同)

Tom*_*cek 6

几乎所有你需要做的就是用变量声明替换变量声明中的类型名称(你可以var在C#中写入)let,删除所有分号和花括号并替换foreach
for file in files do.您还使用了一些名称空间,因此在F#中,您需要以下内容:

open System.IO
open System.Text.RegularExpressions
Run Code Online (Sandbox Code Playgroud)

你正在使用一个可变变量(content),但你真的不需要改变它.您可以使用其他变量(例如newContent)来存储替换结果.所以,中间部分将是:

let content = File.ReadAllText(file)  // No need for a stream reader here!

let pattern = @"Script Date: \d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}"
let replace = "Script Date: "    
let newContent = Regex.Replace(content, pattern, replace)
Run Code Online (Sandbox Code Playgroud)

您也可以使用相同的变量名称,这意味着您将声明一个新的(不可变的)变量,该变量会隐藏范围其余部分中的前一个变量(有关详细信息,请参阅此SO答案)

即使发生异常,我也会改变最后一位(即使在C#中!)来关闭流.在C#中,你会使用using.要在F#中编写相同的内容,可以使用以下use关键字:

use fileStream = new FileStream(file, FileMode.Truncate, FileAccess.Write, FileShare.None)
use writer = new StreamWriter(fileStream, Encoding.Unicode)
writer.Write(content)
writer.Flush()
Run Code Online (Sandbox Code Playgroud)

use关键字保证了对象被设置(关闭),当它超出范围-即在的末端for循环迭代(在这种情况下).