F # вредит моему мозгу ... кто-нибудь может помочь с переводом C # в F #? - PullRequest
3 голосов
/ 26 октября 2011

Я нашел быстрый проект, который, как мне показалось, идеально подойдет для изучения 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);
}

Я предполагаю, что в F # есть какое-то классное решение на 2-3 строки ... Я хотел бы увидеть его.

Спасибо за советы!Я обновил его, чтобы он соответствовал тому, что делается ниже, чтобы сделать визуальное сравнение потенциально более информативным.Также отличные комментарии ниже.

Ответы [ 3 ]

11 голосов
/ 26 октября 2011
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))

Обратите внимание, что ваш код C # равен ( РЕДАКТИРОВАТЬ : был) также гораздо более многословен, чем необходимо.

6 голосов
/ 26 октября 2011

Практически все, что вам нужно сделать, это заменить имя типа в объявлениях переменных (где вы могли бы написать var в C #) на ключевое слово let, удалить все точки с запятой и фигурные скобки и заменить foreach на
for file in files do.Вы также используете некоторые пространства имен, поэтому в F # вам нужно что-то вроде:

open System.IO
open System.Text.RegularExpressions

Вы используете одну изменяемую переменную (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)

Вы также можете использовать то же имя переменной, что означает, что вы объявляете новую (неизменяемую) переменную, которая скрывает предыдущую в остальной части области видимости.(см. этот ответ 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()

Ключевое слово use гарантирует, что объект удаляется (закрывается), когда он выходит из области видимости, то естьв конце итерации цикла for (в данном случае).

1 голос
/ 26 октября 2011

Trivial. Компиляция. Открыть в отражателе. Выберите язык декомпилятора F #.

...