Is it possible to match the first element of a pair without arrows?

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

Is there an easy way to make map-alik that only applies to the first element of a 2-tuple? Taking firstfrom Control.Arrowand using Arrow (->)it does the trick beautifully:

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

My only concern is that I still have to get real intuition for the shooters, and therefore, I will probably sooner or later find myself in deep water if I continue this. In addition, this is, apparently, a rather convenient case that cannot be generalized.

Can I get the same functionality using something from functors, monads, or something else, getting to the bottom of what I want? I played with

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

-like ideas, but they couldn’t get there.

+5
source share
5 answers

Shooters have good tuple combinators. You can almost think of them as missing tuple functions!

For example,

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

is a useful way to display on the first component.

+9
source

Another abstraction that can do such things is a bifunduk. Edward Kmet has a package called bifunctors . Data.Bifunctor has a type class for this particular function and includes, for example, for 2 tuples.

+5
source

, (a -> b) -> (a,c) -> (b,c). ,

{-# LANGUAGE TupleSections #-}
instance Functor (,c) where
    fmap f (x,c) = (f x, c)

, , . , ; , .

Hayoo Data.Tuple.HT, mapFst.

( BiFunctor (,) , ) , , , , .

+2

, , - , , :

{-#LANGUAGE DeriveFunctor, MultiParamTypeClasses  #-}
import Control.Newtype

newtype P a b = P {p:: (b, a)} deriving (Show,Eq,Ord,Functor)
instance Newtype (P a b) (b,a) where pack = P; unpack = p

 -- *Main> fmap even ("Hi",4)
 -- ("Hi",True)
 -- *Main> map (fmap even) [("Hi",4),("Bye",5)]
 -- [("Hi",True),("Bye",False)]
 -- *Main> under P (fmap even) (4,"Hi")
 -- (True,"Hi")
 -- *Main> map (under P (fmap even) ) [(4,"Hi"),(5,"Bye")]
 -- [(True,"Hi"),(False,"Bye")]
+2

, BiFunctor .

:

data Flip a b = Flip b a

instance Functor (Flip a) where
  fmap f (Flip x y) = Flip (f x) y
+1

All Articles