How to execute this function F #

I tried to execute the following function in several ways, but always was a mistake. So how do I execute constructQuery:

type PersonName = | FirstOnly of string | LastOnly of string | FirstLast of string * string let constructQuery personName = match personName with | 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 

-edit -.

I tried calling the function as follows:

 constructQuery "himekami" constructQuery ("himekami" : PersonName.FirstOnly) constructQuery PersonName.FirstOnly("himekami") 

and an error occurred:

 Analyzer.fs(12,17): error FS0001: This expression was expected to have type PersonName 

but there is a string type here

This is because I do not quite understand how type works in F #.

0
source share
1 answer

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.

+7
source

Source: https://habr.com/ru/post/1246721/


All Articles