Ключевая часть вашего кода имеет дело с .NET API, который не функционирует, поэтому нет способа сделать эту часть кода более идиоматичной или более приятной.Однако ключевая вещь в функциональном программировании - абстракция , так что вы можете скрыть этот (уродливый) код в какой-то идиоматической и многократно используемой функции.
Для представления коллекций данных в F # вы можете использовать стандартный тип списка F # (который подходит для функциональной обработки данных) или seq<'a>
(который является стандартным .NET IEnumerable<'a>
под обложкой), которыйпрекрасно работает при работе с другими библиотеками .NET.
В зависимости от того, как вы обращаетесь к базе данных в другом месте вашего кода, может работать следующее:
// Runs the specified query 'sql' and formats rows using function 'f'
let query sql f =
// Return a sequence of values formatted using function 'f'
seq { use cn = new OleDbConnection(cnstr) // will be disposed
let da = new OleDbDataAdapter(new OleDbCommand(sql, cn))
let ds = new DataSet()
cn.Open()
let i = da.Fill(ds)
// Iterate over rows and format each row
let rowCol = ds.Tables.[0].Rows
for i in 0 .. (rowCount - 1) do
yield f (rowCol.[i]) }
Теперь вы можете использовать функцию query
написать свой исходный код примерно так:
let names = query "SELECT * FROM People" (fun row -> row.["LastName"])
printfn "count = %d" (Seq.count names)
for name in names do printfn "%A" name
// Using 'Seq.iter' makes the code maybe nicer
// (but that's a personal preference):
names |> Seq.iter (printfn "%A")
Другой пример, который вы могли бы написать:
// Using records to store the data
type Person { LastName : string; FirstName : string }
let ppl = query "SELECT * FROM People" (fun row ->
{ FirstName = row.["FirstName"]; LastName = row.["LastName"]; })
let johns = ppl |> Seq.filter (fun p -> p.FirstName = "John")
Кстати: по поводу предложения Mau Я бы не стал• чрезмерно используйте функции высшего порядка, если есть более прямой способ написания кода с использованием языковых конструкций, таких как for
.Пример с iter
выше достаточно прост, и некоторые люди сочтут его более читабельным, но нет общего правила ...