I’ve been trying to get a grip on arrows since they’re the basis of most FRP implementations. I think I understand the basic idea – they’re related to monads but store static information at each bind operator so you can walk through a chain of arrows and look at the static information without having to evaluate the whole arrow.
But I get lost at the point where we start discussing first, second, and swap. What do 2-tuples have to do with arrows? Tutorials present the tuple stuff as if it were an obvious next step, but I’m not really seeing the connection.
For that matter, what does the arrow syntax mean intuitively?
Please take a look in http://www.cs.yale.edu/homes/hudak/CS429F04/AFPLectureNotes.pdf, which explains how Arrows work in FRP.
2-tuples are used in defining Arrows because it’s needed to represent an arrowized function taking 2 arguments.
In FRP, constants and variables are often represented as arrows which ignores its “input”, e.g.
Function applications are then turned into compositions (
>>>):Now how do we turn a 2-argument function into an arrow? For instance
due to currying we may treat this as a function returning a function. So
now let’s apply it to a constant
hey wait, it doesn’t work. The result is still an arrow that returns a function, but we expect something akin to
f Int Int. We notice that currying fails in Arrow because only composition is allowed. Therefore we must uncurry the function firstThen we have the arrow
The 2-tuple arises because of this. Then the bunch functions like
&&&are needed to deal with these 2-tuples.then the addition can be correctly performed.
(Now, why don’t we need things like
&&&&for 3-tuples for functions having 3 arguments? Because a((a,b),c)can be used instead.)Edit: From John Hughes’s original paper Generalising Monads to Arrows, it states the reason as