Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does this pipe tuple operator already exist* somewhere?

I'm aware of (||>) which does (a' * 'b) -> ('a -> b' -> 'c) -> 'c

But I've been finding this quite useful, and wondered if I was reinventing the wheel:

// ('a * 'a) -> ('a -> 'b) -> ('b * 'b)
let inline (|>>) (a,b) f = (f a, f b)

(*It can happen, I only discovered the ceil function half an hour ago!)

like image 496
Benjol Avatar asked Feb 07 '13 09:02

Benjol


2 Answers

No, it doesn't.

However, you will encounter its variant very often if you use FParsec. Here is the type signature in FParsec documentation:

val (|>>): Parser<'a,'u> -> ('a -> 'b) -> Parser<'b,'u>

I think the library has a very well-designed set of operators which can be generalized for other purposes as well. The list of FParsec operators can be found here.

I did a bit of digging; |>> operator doesn't seem to have built-in Haskell counterpart although it is easy to be defined using Control.Arrow.

like image 96
pad Avatar answered Sep 30 '22 19:09

pad


The operator you described is essentially the map function for a two-element tuple. The map function, in general has a signature (for some F<'a> which could be seq<'a> or many other types in F# libraries):

map : ('a -> 'b) -> F<'a> -> F<'b>

So, if you define F<'a> as a two element tuple, then your function is actually just map (if you flip the arguments):

type F<'a> = 'a * 'a
let map f (a, b) = (f a, f b)

The operation is not built-in anywhere in the F# library, but it is useful to realize that it actually matches a pattern that is quite common in F# libraries elsewhere (list, seq, array, etc.)

Looking at the Haskell answer referenced by @pad - in principle, Haskell makes it possible to define the same function for all types that support such operations using type classes (so you would write just fmap instead of Seq.map or instead of your TwoElementTuple.map, but it actually does not work for various technical reasons - so Haskellers need to call it differently).

In F#, this is not easily possible to define a single map function for different types, but you can still think of your function as a map for two-element tuples (even if you find it easier to give it a symbolic operator name, rather than the name map.)

like image 37
Tomas Petricek Avatar answered Sep 30 '22 19:09

Tomas Petricek