Я исследовал использование F# для разработки и нашел (для моих ситуаций), создание сценариев, чтобы помочь мне упростить некоторые сложные задачи состоит в том, где я могу получить значение от него (в данный момент).
Моя наиболее распространенная сложная задача связывает файлы для многих задач (главным образом связанный SQL).
Я делаю это часто и каждый раз, когда я пытаюсь изменить к лучшему свой сценарий F#, чтобы сделать это.
Это - мои максимальные усилия до сих пор:
open System.IO
let path = "C:\\FSharp\\"
let pattern = "*.txt"
let out_path = path + "concat.out"
File.Delete(out_path)
Directory.GetFiles(path, pattern)
|> Array.collect (fun file -> File.ReadAllLines(file))
|> (fun content -> File.WriteAllLines(out_path, content) )
Я уверен, что у других есть сценарии, который делает их иногда сложные/скучные задачи легче. Какие сценарии F# Вы раньше делали это или что другие цели для сценариев F# Вы нашли полезными?
Я нашел, что лучший способ для меня для улучшения моего F# состоял в том, чтобы просмотреть другие сценарии для надевания идей, как заняться определенными ситуациями. Надо надеяться, этот вопрос поможет мне и другим в будущем.:)
Я нашел статью о генерации сценариев F#, которые могут представлять интерес: http://blogs.msdn.com/chrsmith/archive/2008/09/12/scripting-in-f.aspx
Я использую F# аналогичным образом, когда мне нужно быстро обработать некоторые данные или преобразовать их между различными форматами. Преимущество F# в том, что вы можете создавать функции более высокого порядка для выполнения всевозможных подобных задач.
Например, мне нужно было загрузить некоторые данные из базы данных SQL и сгенерировать файлы сценариев Matlab, которые загружают эти данные. Мне нужно было сделать это для нескольких различных SQL-запросов, поэтому я написал эти две функции:
// Runs the specified query 'str' and reads results using 'f'
let query str f = seq {
let conn = new SqlConnection("<conn.str>");
let cmd = new SqlCommand(str, conn)
conn.Open()
use rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
while rdr.Read() do yield f(rdr) }
// Simple function to save all data to the specified file
let save file data =
File.WriteAllLines(@"C:\...\" + file, data |> Array.ofSeq)
Теперь я мог легко написать конкретные вызовы для чтения нужных мне данных, преобразования их в типы данных F#, предварительной обработки (при необходимости) и печати результатов в файл. Например, для обработки компаний у меня было что-то вроде:
let comps =
query "SELECT [ID], [Name] FROM [Companies] ORDER BY [ID]"
(fun rdr -> rdr.GetString(1) )
let cdata =
seq { yield "function res = companies()"
yield " res = {"
for name in comps do yield sprintf " %s" name
yield " };"
yield "end" }
save "companies.m" cdata
Генерация вывода в виде последовательности строк - это тоже довольно аккуратно, хотя вы, вероятно, могли бы написать более эффективный построитель вычислений, используя StringBuilder
.
Еще один пример использования F# в интерактивном режиме описан в моей книге по функциональному программированию в главе 13 (вы можете получить исходный код здесь). Он подключается к базе данных Всемирного банка (которая содержит много информации о различных странах), извлекает некоторые данные, исследует структуру данных, преобразует их в типы данных F# и вычисляет некоторые результаты (и визуализирует их). Я думаю, что это (один из многих) видов задач, которые могут быть очень хорошо выполнены на F#.
Иногда, если мне нужно краткое описание структуры XML (или иметь рекурсивный список для использования в других формах, например как поиск), я могу распечатать список узлов в XML с вкладками, используя следующий сценарий:
open System
open System.Xml
let path = "C:\\XML\\"
let xml_file = path + "Test.xml"
let print_element level (node:XmlNode) = [ for tabs in 1..level -> " " ] @ [node.Name]
|> (String.concat "" >> printfn "%s")
let rec print_tree level (element:XmlNode) =
element
|> print_element level
|> (fun _ -> [ for child in element.ChildNodes -> print_tree (level+1) child ])
|> ignore
new XmlDocument()
|> (fun doc -> doc.Load(xml_file); doc)
|> (fun doc -> print_tree 0 doc.DocumentElement)
Я уверен, что его можно оптимизировать / сократить, и я буду поощрять другие улучшения этого кода. :)
Предположим, что вам нужны сеансы на основе базы данных (Django также предлагает сеансы на основе файлов и на основе кэша):
MIDDLEWARE _ CLASSES
. Добавьте в список 'django.contrib.sessions.middleware.SessionMiddleware'
. INSTALLED _ APPS
в том же файле и добавьте туда 'django.contrib.sessions'
. manage.py syncdb
из командной строки. После начальной настройки можно использовать request.session
в своих представлениях для хранения информации между запросами.
Например, здесь хранится информация:
request.session['name'] = 'Ludwik'
, которую можно легко получить:
print request.session['name']
или
if request.session['name'] == 'Ludwik':
print 'you are awesome!'
. Для получения других сведений об объекте request.session
см. документацию .
Если диапазон индекса разбивается на неперекрывающиеся диапазоны, то при условии, что массив создается в общей памяти (т.е. не каждым потоком), блокировки не требуются.
-121--4746196-(Альтернативный фрагмент см. в ответе ниже.) Этот фрагмент преобразует XML с помощью XSLT. Я не был уверен в лучшем способе использования объектов XslCompiledTransform и StartDocument в F #, но он работал. Я уверен, что есть лучшие способы и был бы рад услышать о них.
(* Transforms an XML document given an XSLT. *)
open System.IO
open System.Text
open System.Xml
open System.Xml.Xsl
let path = "C:\\XSL\\"
let file_xml = path + "test.xml"
let file_xsl = path + "xml-to-xhtml.xsl"
(* Compile XSL file to allow transforms *)
let compile_xsl (xsl_file:string) = new XslCompiledTransform() |> (fun compiled -> compiled.Load(xsl_file); compiled)
let load_xml (xml_file:string) = new XmlDocument() |> (fun doc -> doc.Load(xml_file); doc)
(* Transform an Xml document given an XSL (compiled *)
let transform (xsl_file:string) (xml_file:string) =
new MemoryStream()
|> (fun mem -> (compile_xsl xsl_file).Transform((load_xml xml_file), new XmlTextWriter(mem, Encoding.UTF8)); mem)
|> (fun mem -> mem.Position <- (int64)0; mem.ToArray())
(* Return an Xml fo document that has been transformed *)
transform file_xsl file_xml
|> (fun bytes -> File.WriteAllBytes(path + "out.html", bytes))
После разъяснения подходов к написанию кода F # с существующими классами .net появился следующий полезный код для преобразования документов xml в документы xsl. Эта функция также позволяет вам создать пользовательскую функцию для преобразования xml-документов с помощью определенного xsl-документа (см. Пример):
let transform =
(fun xsl ->
let xsl_doc = new XslCompiledTransform()
xsl_doc.Load(string xsl)
(fun xml ->
let doc = new XmlDocument()
doc.Load(string xml)
let mem = new MemoryStream()
xsl_doc.Transform(doc.CreateNavigator(), null, mem)
mem
)
)
Это позволяет вам преобразовывать документы следующим образом:
let result = transform "report.xml" "report.xsl"
или вы можете создать другую функцию, которую можно использовать несколько раз. раз:
let transform_report "report.xsl"
let reports = [| "report1.xml"; "report2.xml" |]
let results = [ for report in reports do transform_report report ]