Some of the functions for working with Arrows are quite handy to use on pairs. But I can't understand how the types of these functions unify with a pair. In general, I find the types of the Arrow related functions to be quite confusing.
For example, we have first :: a b c -> a (b, d) (c, d)
, which means little to me. But it can be used to, say, increment the first number in a pair:
Prelude Control.Arrow> :t first (+1)
first (+1) :: (Num b) => (b, d) -> (b, d)
And
Prelude Control.Arrow> :t (&&&)
(&&&) :: (Arrow a) => a b c -> a b c' -> a b (c, c')
Prelude Control.Arrow> :t (pred &&& succ)
(pred &&& succ) :: (Enum b) => b -> (b, b)
Could someone please explain how this works?
There is an instance for
Arrow (->)
. Sohas the instantiation
or, written in more conventional notation,
The rest should follow from that.
I use the arrow functions (especially
(***)
and(&&&)
) all the time on the(->)
instance. My usage of those combinators for any other instance ofArrow
is very rare. So whenever you seea b c
, think "(generalized) function fromb
toc
", which works for regular functions too.