Is there any explanation for why a lifted function, when applied to 2-tuple, only applies to the 2nd entry:
f x = x + 1
f <$> (2,2)
// -> (2,3)
On the other hand, tuples of any other length than 2 return errors. Also
:t f <$>
returns an error. Is it possible to see the type of f <$>
when acting on tuples?
Is there any explanation for that behaviour?
The Data.Tuple documentation is extremely brief and has no mention of how functions are lifted to tuples. Is there any source explaining it?
Update. A part of question about 2-tuples is related to this answer, where, however, the above question about multiple length tuples is not addressed.
One could (and arguably, GHC should) define a Functor instance for triples and larger tuples. To wit:
instance Functor ((,,) a b) where
fmap f (a, b, c) = (a, b, f c)
If this instance truly doesn't exist anywhere in base
, I suspect that's mostly oversight, though I don't know the history well enough to say for sure. You can include this in any code where it seems useful, with the caveat that you should then absolutely put a fairly strict upper bound on the version of base
in your *.cabal
file, as this instance might reasonably be included in future versions of base
. The PVP allows only the third component of the version to change in such a case, so include at least that many components in your upper bound!
Is there any explanation for why a lifted function, when applied to 2-tuple, only applies to the 2nd entry
Because tuples are heterogeneous which means that, in general, it would not make sense to try to apply a function of type b -> c
to each component of a tuple of type (a, b)
.
If you want pairs of values of the same type, you can declare your own type Pair
and then have the functor instance apply the function to each component.
data Pair a = Pair { fst :: a
, snd :: a }
instance Functor Pair where
fmap f (Pair fst snd) = Pair (f fst) (f snd)
Is it possible to see the type of
f <$>
when acting on tuples?
f <$>
is a section (a partially applied infix operator). To get its type, you need to wrap it with parentheses like so:
:t (f <$>)
The Data.Tuple documentation is extremely brief and has no mention of how functions are lifted to tuples. Is there any source explaining it?
The combinator (<$>)
(and (<*>)
) are more general than just for tuples, you can find them in the Control.Applicative module.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With