Buscar..


Programación basada en datos en F #

Gracias a la inferencia de tipos y la aplicación parcial en la programación basada en datos de F# es breve y legible.

Imaginemos que estamos vendiendo seguros de automóviles. Antes de que intentemos venderlo a un cliente, tratamos de determinar si el cliente es un cliente potencial válido para nuestra empresa verificando el sexo y la edad del cliente.

Un simple modelo de cliente:

type Sex =
  | Male
  | Female

type Customer =
  {
    Name    : string
    Born    : System.DateTime
    Sex     : Sex
  }

A continuación, queremos definir una lista de exclusión (tabla) para que si un cliente coincide con cualquier fila de la lista de exclusión, el cliente no pueda comprar nuestro seguro de automóvil.

//  If any row in this list matches the Customer, the customer isn't eligible for the car insurance.
let exclusionList =
  let __          _   = true
  let olderThan   x y = x < y
  let youngerThan x y = x > y
  [|
//  Description                         Age               Sex
    "Not allowed for senior citizens" , olderThan   65  , __
    "Not allowed for children"        , youngerThan 16  , __
    "Not allowed for young males"     , youngerThan 25  , (=) Male
  |]

Debido a la inferencia de tipos y la aplicación parcial, la lista de exclusión es flexible pero fácil de entender.

Finalmente, definimos una función que utiliza la lista de exclusión (una tabla) para dividir a los clientes en dos grupos: clientes potenciales y clientes rechazados.

// Splits customers into two buckets: potential customers and denied customers.
// The denied customer bucket also includes the reason for denying them the car insurance
let splitCustomers (today : System.DateTime) (cs : Customer []) : Customer []*(string*Customer) [] =
  let potential = ResizeArray<_> 16 // ResizeArray is an alias for System.Collections.Generic.List
  let denied    = ResizeArray<_> 16

  for c in cs do
    let age = today.Year - c.Born.Year
    let sex = c.Sex
    match exclusionList |> Array.tryFind (fun (_, testAge, testSex) -> testAge age && testSex sex) with
    | Some (description, _, _)  -> denied.Add (description, c)
    | None                      -> potential.Add c

  potential.ToArray (), denied.ToArray ()

Para concluir, definamos algunos clientes y veamos si hay algún cliente potencial para nuestro seguro de automóvil entre ellos:

let customers =
  let c n s y m d: Customer = { Name = n; Born = System.DateTime (y, m, d); Sex = s }
  [|
//    Name                      Sex     Born
    c "Clint Eastwood Jr."      Male    1930 05 31
    c "Bill Gates"              Male    1955 10 28
    c "Melina Gates"            Female  1964 08 15
    c "Justin Drew Bieber"      Male    1994 03 01
    c "Sophie Turner"           Female  1996 02 21
    c "Isaac Hempstead Wright"  Male    1999 04 09
  |]

[<EntryPoint>]
let main argv =
  let potential, denied = splitCustomers (System.DateTime (2014, 06, 01)) customers
  printfn "Potential Customers (%d)\n%A" potential.Length potential
  printfn "Denied Customers (%d)\n%A"    denied.Length    denied
  0

Esto imprime:

Potential Customers (3)
[|{Name = "Bill Gates";
   Born = 1955-10-28 00:00:00;
   Sex = Male;}; {Name = "Melina Gates";
                  Born = 1964-08-15 00:00:00;
                  Sex = Female;}; {Name = "Sophie Turner";
                                   Born = 1996-02-21 00:00:00;
                                   Sex = Female;}|]
Denied Customers (3)
[|("Not allowed for senior citizens", {Name = "Clint Eastwood Jr.";
                                       Born = 1930-05-31 00:00:00;
                                       Sex = Male;});
  ("Not allowed for young males", {Name = "Justin Drew Bieber";
                                   Born = 1994-03-01 00:00:00;
                                   Sex = Male;});
  ("Not allowed for children", {Name = "Isaac Hempstead Wright";
                                Born = 1999-04-09 00:00:00;
                                Sex = Male;})|]


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow