
On Tue, May 28, 2013 at 1:54 AM, Dominique Devriese
Hi all,
I often find myself needing the following definitions:
mapPair :: (a -> b) -> (c -> d) -> (a,c) -> (b,d) mapPair f g (x,y) = (f x, g y)
mapFst :: (a -> b) -> (a,c) -> (b,c) mapFst f = mapPair f id
mapSnd :: (b -> c) -> (a,b) -> (a,c) mapSnd = mapPair id
But they seem missing from the prelude and Hoogle or Hayoo only turn up versions of them in packages like scion or fgl. Has anyone else felt the need for these functions? Am I missing some generalisation of them perhaps?
One generalization of them is to lenses. For example `lens` has "both", "_1", "_2", such that "mapPair = over both", "mapFst = over _1", etc., but you can also get "fst = view _1", "set _2 = \y' (x,_) -> (x,y')", and so on. (Since "both" refers to two elements, you end up with "view both = \(x,y) -> mappend x y".) The types you end up with are simple generalizations of mapFoo, with just an extra Functor or Applicative (think mapMFoo): both :: Applicative f => (a -> f b) -> (a,a) -> f (b,b) both f (x,y) = (,) <$> f x <*> g y _2 :: Functor f => (a -> f b) -> (e,a) -> f (e,b) _2 f (x,y) = (,) x <$> f y With an appropriate choice of f you can get many useful functions. Shachaf