Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a library function or operator to create a tuple?

Tags:

f#

Given a string of digits, I would like to have a sequence of tuples mapping the non-zero characters with their position in the string. Example:

IN: "000140201"
OUT: { (3, '1'); (4, '4'); (6, '2'); (8, '1') }

Solution:

let tuples = source
             |> Seq.mapi (fun i -> fun c -> (i, c))
             |> Seq.filter (snd >> (<>) '0')

It seems like (fun i -> fun c -> (i, c)) is a lot more typing than it should be for such a simple and presumably common operation. It's easy to declare the necessary function:

let makeTuple a b = (a, b)
let tuples2 = source
              |> Seq.mapi makeTuple
              |> Seq.filter (snd >> (<>) '0')

But it seems to me that if the library provides the snd function, it should also provide the makeTuple function (and probably with a shorter name), or at least it should be relatively easy to compose. I couldn't find it; am I missing something? I tried to build something with the framework's Tuple.Create, but I couldn't figure out how to get anything other than the single-argument overload.

like image 676
phoog Avatar asked Feb 09 '13 06:02

phoog


2 Answers

But it seems to me that if the library provides the snd function, it should also provide the makeTuple function.

F# assumes that you decompose tuples (using fst, snd) much more often than composing them. Functional library design often follows minimal principle. Just provide functions for common use cases, other functions should be easy to define.

I couldn't find it; am I missing something?

No, you aren't. It's the same reason that FSharpPlus has defined tuple2, tuple3, etc. Here are utility functions straight from Operators:

/// Creates a pair
let inline tuple2 a b = a,b
/// Creates a 3-tuple
let inline tuple3 a b c = a,b,c
/// Creates a 4-tuple
let inline tuple4 a b c d = a,b,c,d
/// Creates a 5-tuple
let inline tuple5 a b c d e = a,b,c,d,e
/// Creates a 6-tuple
let inline tuple6 a b c d e f = a,b,c,d,e,f

I tried to build something with the framework's Tuple.Create, but I couldn't figure out how to get anything other than the single-argument overload.

F# compiler hides properties of System.Tuple<'T1, 'T2> to enforce pattern matching idiom on tuples. See Extension methods for F# tuples for more details.

That said, point-free style is not always recommended in F#. If you like point-free, you have to do a bit of heavy lifting yourself.

like image 147
pad Avatar answered Oct 31 '22 22:10

pad


The @pad's answer is great, just to add my 2 cents: I am using similar operator

let inline (-&-) a b = (a, b)

and it looks very convenient to write let x = a -&- b

Maybe you'll find this operator useful too

like image 21
Rustam Avatar answered Oct 31 '22 20:10

Rustam