F # 6: Tuples

So, our journey to F # continues. The following article will focus on F # types that may or may not have standard .NET equivalents. This post is about tuples.

What are tuples


A tuple is a group of unnamed, but ordered values, possibly of different types.

Creating Tuples


Tuples are very easy to create, we just do something like the one shown below. Notice how I created a mixed package of tuples, some of which are numbers and others are strings, and we can also mix and match both types and the number of values.

let a = (1,2) let b = (1,"cat") let c = (1,"cat") let d = (1,"cat", 'c') 

Universal tuples


Functions that accept tuples can also accept universal tuples without any problems. An inference system like F # will happily handle the inference of the correct types for a tuple. Here is an example.

 let someFunction tup = let (x,y) = tup printfn "x is %A and y is %A" xy do someFunction ("cat","dog") do someFunction (11,12) 

And here are the results of the execution above, where you can see that the someFunction function accepted and worked with various typed tuples without problems.

image

Tuple Signatures


So far, we have not touched upon the understanding of F # signatures at all, in fact, this is a topic to which I also decided to devote a whole blog post, since I believe that it is quite complicated. However, we are located where we are, that is, here and now, and we are studying tuples, so now I just wanted to demonstrate what the signature of the tuple would look like.

Suppose I declared the following tuples in the FSI window:
 let a = (1,2) let b = (1,"codfather") let c = (1,"c", 12.5) 

And then I examined them in the FSI window; we will see something like this:
 val a : int * int = (1, 2) val b : int * string = (1, "codfather") val c : int * string * float = (1, "c", 12.5) 

This is interesting, we can see a couple of things here, namely:

So the crystal clear tuple looks like this:
 let a = (1,2) 

Will have the following signature:
 int * int 


Tuple Breakdown


So, we saw how we can create tuples, but what about breaking or deconstructing them back into separate values. Is it possible? Yes of course. As before, let's start with a few examples:
 let (a,b) = (1,2) printfn "(a,b) = (1,2), so value of 'a' should be 1, and it is =%i,\r\n 'b' should be 2, and it is =%i" ab //   ,  ,     ,   //     let (_,z) = (1,2) printfn "grabbing last value from (1,2) which is = %i" z let (a,b :string) = (1,"cat") printfn "grabbing (1,\"cat\") which has values = %i %s" ab let (a :int,b :string) = (1,"cat") printfn "grabbing (1,\"cat\") which has values = %i %s" ab let (a ,b, c) = (1,"cat", 'c') printfn "grabbing (1,\"cat\",'c') which has values = %i %s %c" abc let first = fst (1, 2) printfn "grabbing fst from (1,2) which has values = %i" first let second = snd (1, 2) printfn "grabbing 2nd from (1,2) which has values = %i" second 

The results are printed in a standard console window, as follows:
image

Using Let


But how did we get the individual parts? Well, all you need is the code above, but let's look at one example. Suppose we had a tuple like this:
 (1,2) 

And I wanted to get the values ​​of both "values" of the tuple, tied to some new individual values, we could just do this:
 let (a,b) = (1,2) 

We can also select only those values ​​that we really need, which is done using a wildcard for unwanted parts. Which guarantees the absence of unnecessary value binding. Here is an example:
 let (_,z) = (1,2) 


Using the built-in tuple functions


There is also built-in support for getting the first and second values ​​from a tuple. What can be done with the fst and snd functions. There is no support for anything other than the 2nd element (these are probably the most common cases). “ Fst ” and “ snd ” can be used as follows:
 let first = fst (1, 2) let second = snd (1, 2) 

Now I want to draw your attention to a special case where we may have a mismatch with the number of values ​​that we are trying to explode into individual values. So this will be something like an example here:
 let (a ,b) = (1,"cat", 'c') 

You can see that the tuple itself actually contains 3 values, but the Let binding has only 2 values, so the compiler warns us about this, as you can see in the screenshot below:
image

Creating New Tuples


You might want to create new tuples from existing tuples, it's simple enough, here is an example:
 let oldOne = (1,2) let (x,y) = oldOne let newOne = (x+1,y+1) printfn "original = %A, and we did this (x+1,y+1)\r\n to obtain newOne = %A" oldOne newOne 

image

Comparing Tuples


Tuples are considered equal only if


Let's look at some simple example.

 printfn "(1,2) = (3,4) =% b" ((1,2) = (3,4)) printfn "(1,2) = (1,2) =% b" ((1,2) = (1,2)) printfn "('a', 'b') = ('a', 'b') =% b" (('a', 'b') = ('a', 'b')) printfn "('a', 'b') = ('a', 'c') =% b" (('a', 'b') = ('a', 'c')) 

image

In fact, if your tuples have different lengths (the number of elements) and you try to compare them using the equality operator “=”, you will get a warning:
image

Tuple matching patterns


We have not dealt with matching patterns yet, but later we will see a whole post on this topic. In the meantime, just know that this is a way to match input parameters again. You can do this for tuples, which is done as follows:
 let someFunction tup = match tup with | 1,2 -> printfn "you passed (1,2)" | _,_ -> printfn "you passed some other tuple" do someFunction (11,12) do someFunction (4,5) do someFunction (1,2) do someFunction (13,23) 

image

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


All Articles