Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I map the first element of a pair without arrows?

Tags:

haskell

arrows

I'm eyeing functors, applicative functors… I'm not sure how to get where I want, but I have the feeling that following the types should get me closer.

Is there a simple way to make a map-alike which only applies to the first element of a 2-tuple? Taking first from Control.Arrow and using Arrow (->), this does the trick nicely:

map . first :: (b -> c) -> [(b, d)] -> [(c, d)]

My only concern is that I have yet to gain a real intuition for arrows, and so I'll probably find myself in deep water sooner or later if I keep this up. Plus, this seems to be a rather convenient case that can't be generalised.

Can I get the same functionality by using something from functors, monads or whatever else, while getting to the heart of what I want? I was toying around with

\f -> map (f `on` fst)

-like ideas, but couldn't quite get there.

like image 567
Asherah Avatar asked May 30 '12 14:05

Asherah


2 Answers

Arrows have nice combinators for operating on tuples. You can almost think of them as the missing tuple functions!

So e.g.

> :t \f -> map (f *** id)
  :: (b -> c) -> [(b, c')] -> [(c, c')]

is a useful way for mapping over the first component.

like image 109
Don Stewart Avatar answered Sep 22 '22 00:09

Don Stewart


Another abstraction that can do this kind of thing is a bifunctor. Edward Kmett has a package called bifunctors. Data.Bifunctor has a type class for exactly this functionality and it includes in instance for 2-tuples.

like image 22
mightybyte Avatar answered Sep 21 '22 00:09

mightybyte