La parte clave de sus ofertas de código con la API .NET que no es funcional, lo que no hay manera de hacer esta parte del código particular más idiomática o más agradable. Sin embargo, la clave en la programación funcional es abstracción, por lo que puede ocultar este código (feo) en alguna función idiomática y reutilizable.
Para representar colecciones de datos en F #, puede usar el tipo de lista F # estándar (que es bueno para el procesamiento de datos funcionales) o seq<'a>
(que es .NET IEnumerable<'a>
estándar bajo la cubierta), que funciona bien cuando se trabaja con otros Bibliotecas .NET.
Dependiendo de cómo se accede a la base de datos en otra parte de su código, la siguiente podría funcionar:
// 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]) }
Ahora puede utilizar la función de query
para escribir su código original más o menos así:
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")
Otro ejemplo que podría escribir es:
// 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")
BTW: En cuanto a la sugerencia por Mau No utilizaría excesivamente las funciones de orden superior si hay una forma más directa de escribir el código utilizando construcciones de lenguaje como for
. El ejemplo con iter
arriba es bastante simple y algunas personas lo encontrarán más legible, pero no hay una regla general ...
No estoy seguro Entiendo la pregunta. – BuddyJoe
Quiso decir que la tarea en cuestión (operaciones DB con bibliotecas .NET) necesariamente termina en un código imperativo, por lo que F # no brilla allí. Sin embargo, puede ser muy adecuado para procesar los datos una vez que lo saca de la base de datos. – Mau
@tyndall Mau es 100% correcto. tu código es 100% imperativo. puede convertirlo a C# utilizando FindReplace. Creo que F # podría no ser la mejor herramienta aquí. – Andrey