<div dir="ltr">Thank you, this is great. I notice that none of your monad examples import Control.Arrow. The composition operators come from Control.Monad, right? So it's correct to call putStr etc. an arrow even though we never need to actually use the word "arrow" to work with it or compose such "functions"?<div><br></div><div>D</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 16, 2016 at 7:22 AM, Michael Orlitzky <span dir="ltr"><<a href="mailto:michael@orlitzky.com" target="_blank">michael@orlitzky.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 02/16/2016 03:06 AM, Dennis Raddle wrote:<br>
> I am a Haskell beginner. I have used arrows occasionally to move<br>
> 2-tuples around, but don't understand more than that.<br>
><br>
> I'm interested in know what's the connection between arrows and<br>
> 2-tuples. I don't really understand most of the Control.Arrow docs, but<br>
> it seems that a lot of stuff about arrows doesn't mention 2-tuples. Yet<br>
> the operators (***), (&&&), first, and second seem to be common. Is<br>
> there some way to explain the link?<br>
><br>
> Also, the main instance of Arrow seems to be (->). There is also<br>
> something about Kleisli monads, but I don't know what those are. Is<br>
> there an another big use case for arrows besides (->)? Don't worry about<br>
> explaining it all, just a quick mention would be fine and I can<br>
> investigate it myself.<br>
><br>
<br>
</span>An arrow is basically a function and it doesn't hurt to think of them<br>
that way. In mathematics, "function" means something very specific, so<br>
they needed a new name (arrow) for a thing that's a lot like a function<br>
but isn't one.<br>
<br>
You can construct some weird situations where arrows aren't very much<br>
like mathematical functions at all, but it still doesn't hurt to think<br>
of them that way. Mentally I prefer to embiggen my concept of "function"<br>
rather than give it up entirely in the new setting. You're probably<br>
already used to this: the random() "function" is not a mathematical<br>
function, but we all call it one.<br>
<br>
There's no specific connection between arrows and two-tuples. It's<br>
extremely common to use functions on two-tuples, and every function is<br>
an arrow, so the fact that all of those useful (***) and (&&&) live in<br>
Control.Arrow is a bit of a premature abstraction. Frequently you'll<br>
need to take a function f and a pair (x,y) and want to compute the pair<br>
(f x, f y). There should really be a combinator for that! But when you<br>
write one, it turns out that it works just as well for arrows. Since all<br>
functions are arrows, they just used the more general type.<br>
<br>
The Kleisli arrow/monad thing isn't wrong, it's just useless without an<br>
example. Kleisli arrows are just plain old arrows (think: functions) in<br>
a monad. Suppose I want to read a file and then print its contents to<br>
the screen. How would I do that? In pseudo-code, it's something like,<br>
<br>
  -- Read a file and print its contents to the screen<br>
  (putStr . readFile) "/path/to/file.txt"<br>
<br>
But here, "print" and "readFile" aren't mathematical functions, so we<br>
can't compose them! The "." operator only works on functions. It would<br>
be great if there were something that was a lot like a function but<br>
could be composed in this manner...<br>
<br>
  -- Read a file and print its contents to the screen<br>
  ghci> import Control.Monad ( (<=<) )<br>
  ghci> (putStr <=< readFile) "hw.txt"<br>
  Hello, world!<br>
<br>
Another useful example is when you want to "automatically" concatenate a<br>
list of results. Let's write a stupid function that duplicates its<br>
argument in a list:<br>
<br>
  ghci> let twice x = [x, x]<br>
  ghci> twice 3<br>
  [3,3]<br>
<br>
So far so good. But now I want four things. Can I compose "twice" with<br>
itself?<br>
<br>
  ghci> (twice . twice) 3<br>
  [[3,3],[3,3]]<br>
  ghci> :t (twice . twice)<br>
  (twice . twice) :: t -> [[t]]<br>
<br>
Crap, that's giving me a list of lists. I just want one list! By<br>
thinking of "twice" as a multi-valued function (a special type of<br>
arrow), I can get what I want:<br>
<br>
  ghci> (twice <=< twice) 3<br>
  [3,3,3,3]<br>
<br>
That trick is using the Monad instance for lists, but composition in<br>
monads is done with arrows (not mathematical functions). It's put to<br>
good use in e.g. HXT where you can say "give me all children of <p><br>
elements that live in a <div> that live in a <body>" and you only want<br>
one list back. Without that funny arrow composition, you'd be stuck with<br>
lists of lists of lists of lists...<br>
<br>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
</blockquote></div><br></div>