I guess the question is how to build PersonName objects (since this is the input to your function).
It's pretty simple - just use one of the FirstOnly , LastOnly or FirstLast :
let firstOnly = FirstOnly "Tom" let lastOnly = LastOnly "Hengs" let firstLast = FirstLast ("Tom", "Hengs")
and you can use them as follows:
constructQuery firstOnly constructQuery lastOnly constructQuery firstLast
background
You see that PersonName is an algebraic data type with three constructors, and constructQuery matches it only for them. In VisualStudio (or MonoDevelop), you should get a tooltip with types for each part of it - you should do this all the time because types understand most.
other Ways to call this function
you can use the pipe operator |> and do it in one go:
FirstOnly "Tom" |> constructQuery
Of course, you can use it without this operator:
constructQuery (LastOnly "Hengs")
but here you need parades because without them you would enable the function LastOnly (and yes, this is the String -> PersonName function) in the constructQuery function, and then apply a line like this:
constructQuery LastOnly "Hengs" = (constructQuery LastOnly) "Hengs" // error: compiler complains about mismatched types
because LastOnly is really a function (unfortunately this is not the case for C # constructors), you can also do such cool things:
// Pipes all the way "Hengs" |> LastOnly |> constructQuery // this is another function String -> PersonName let constructFromLastOnly = LastOnly >> constructQuery // you can call it like this constructFromLastOnly "Hengs" // etc. ... imagine
another alternative is to use a return pipe <| (not so idiomatic):
constructQuery <| LastOnly "Hengs"
where you donβt need paranas, either
Notes
I would advise you (even if he really does not need a compiler) to give types for top-level functions (the one you want to use from other parts of your program):
let constructQuery (personName : PersonName) : () = match personName with
Have you seen that you really don't need PersonName besides calling match ? It is so common that there is another / shorter way to write this:
let constructQuery = function | FirstOnly(firstName) -> printf "May I call you %s?" firstName | LastOnly(lastName) -> printf "Are you Mr. or Ms. %s?" lastName | FirstLast(firstName, lastName) -> printf "Are you %s %s?" firstName lastName
or with signature:
let constructQuery : PersonName -> () = function | FirstOnly(firstName) -> printf "May I call you %s?" firstName | LastOnly(lastName) -> printf "Are you Mr. or Ms. %s?" lastName | FirstLast(firstName, lastName) -> printf "Are you %s %s?" firstName lastName
And finally, I don't like the fact that you mix printf there. See A function returning a block () is never clean, and you mix problems. Why not:
let constructQuery : PersonName -> string = function | FirstOnly(firstName) -> sprintf "May I call you %s?" firstName | LastOnly(lastName) -> sprintf "Are you Mr. or Ms. %s?" lastName | FirstLast(firstName, lastName) -> sprintf "Are you %s %s?" firstName lastName
and use it as follows:
FirstOnly "Tom" |> constructQuery |> Console.WriteLine
so that you can reuse it, for example, in a WPF application or in a logging script where the console is not available.