mardi 16 janvier 2018

How to handle different types for input of algorithm?

I have an algorithm that looks up data based on what the user inputs. There are multiple ways to specify a unique record so I am allowing the user to input several different unique identifiers. When I begin writing the algorithm however, alarm bells go on in my head because it seems verbose or non-functional. It just feels like I'm doing something wrong. Let me show you in code.

// Types for the domain model
type EmployeeID = ID of int

type EmployeeName =
    { First  : string
      Last   : string }

// Some instances of EmployeeName to use later
let james = {First = "James"; Last = "Winklenaught"}
let ted = {First = "Theodore"; Last = "Chesterton"}

// Input for the algorithm
type matcherInput =
    | EmployeeIDWrapper of EmployeeID
    | EmployeeNameWrapper of EmployeeName

// Output of the algorithm
type matcherOutput = 
    { Info : string }

// Returns data if it found it from our search algorithm
let LookupEmployee (input : matcherInput) : matcherOutput option = 
    (* 
       There's a lot of algorithm here in the real version
       that creates the lookup tables (maps). I just put in
       some dummy data instead. 
    *)
    let numberLookup = 
        Map.ofList [(james, ID 1); (ted, ID 2)]

    let infoLookup = 
        Map.ofList [(ID 1,{Info = "CEO"});(ID 2,{Info = "CFO"})]

    // output
    match input with
    | EmployeeIDWrapper number -> 
        Map.tryFind number infoLookup
    | EmployeeNameWrapper name -> 
        Map.tryFind name numberLookup 
        |> Option.bind (fun number -> Map.tryFind number infoLookup)



// doesn't work = (
LookupEmployee james
LookupEmployee (ID 1)

// right, but verbose
LookupEmployee (EmployeeNameWrapper james)
LookupEmployee (EmployeeIDWrapper (ID 1))

Somehow the needing to unwrap everything seems excessive to me. Should I not be using the discriminated union in this case? Is there an established functional design pattern I could leverage?

Aucun commentaire:

Enregistrer un commentaire