How can I refer to a specific member of a Tuple of any size in F #

ok, that might be a dumb question.

So, I have some 4-tuples, so (int, int, int, int)

If it were 2 tuples, I could use fst (myTuple) to refer to the first element. How can I, say, refer to the third element of 4 tuples?

+3
source share
4 answers

Use pattern matching:

let tup = 1, 2, 3, 4 let _,_,third,_ = tup printfn "%d" third // displays "3" 

This is described directly in the MSDN documentation for tuples: Tuples (F #)

+8
source

Here's a version of @Daniels new, which calculates the Rest offsets of the Tuple base view to support position-based access on arbitrarily long tuples. Error handling omitted.

 let (@) t idx = let numberOfRests = (idx - 1) / 7 let finalIdx = idx - 7 * numberOfRests let finalTuple = let rec loop curTuple curRest = if curRest = numberOfRests then curTuple else loop (curTuple.GetType().GetProperty("Rest").GetValue(curTuple, null)) (curRest+1) loop t 0 finalTuple .GetType() .GetProperty(sprintf "Item%d" finalIdx) .GetValue(finalTuple, null) |> unbox //fsi usage: > let i : int = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36)@36;; val i : int = 36 
+4
source

For a clear novelty, here is an overloaded operator that works for tuples of any * size.

 let (@) t idx = match t.GetType().GetProperty(sprintf "Item%d" idx) with | null -> invalidArg "idx" "invalid index" | p -> p.GetValue(t, null) |> unbox //Usage let t = 4, 5, 6 let n1 : int = t@1 //4 let i = 2 let n2 = t@i //5 

* Any, in this context, has a more limited meaning, in particular, up to 7.

+3
source

If you need random access to the tuple as a whole, then this is not possible. For any given size, you can follow ildjarn's answer (expanding it to four, five, etc.), but this is the only (functional) way.

The possibility of tuples in the general case is to first convert it to the list found here , but this is not too pretty, since it requires reflection.

+1
source

All Articles