Send Beginners mailing list submissions to beginners@haskell.org To subscribe or unsubscribe via the World Wide Web, visit http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners or, via email, send a message with subject or body 'help' to beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. Re: arrows and 2-tuples (Michael Orlitzky) 2. Re: arrows and 2-tuples (Dennis Raddle) 3. Re: arrows and 2-tuples (Michael Orlitzky) 4. Re: arrows and 2-tuples (Dennis Raddle) ---------------------------------------------------------------------- Message: 1 Date: Tue, 16 Feb 2016 10:22:15 -0500 From: Michael Orlitzky <mich...@orlitzky.com> To: beginners@haskell.org Subject: Re: [Haskell-beginners] arrows and 2-tuples Message-ID: <56c33ea7.4090...@orlitzky.com> Content-Type: text/plain; charset=utf-8 On 02/16/2016 03:06 AM, Dennis Raddle wrote: > I am a Haskell beginner. I have used arrows occasionally to move > 2-tuples around, but don't understand more than that. > > I'm interested in know what's the connection between arrows and > 2-tuples. I don't really understand most of the Control.Arrow docs, but > it seems that a lot of stuff about arrows doesn't mention 2-tuples. Yet > the operators (***), (&&&), first, and second seem to be common. Is > there some way to explain the link? > > Also, the main instance of Arrow seems to be (->). There is also > something about Kleisli monads, but I don't know what those are. Is > there an another big use case for arrows besides (->)? Don't worry about > explaining it all, just a quick mention would be fine and I can > investigate it myself. > An arrow is basically a function and it doesn't hurt to think of them that way. In mathematics, "function" means something very specific, so they needed a new name (arrow) for a thing that's a lot like a function but isn't one. You can construct some weird situations where arrows aren't very much like mathematical functions at all, but it still doesn't hurt to think of them that way. Mentally I prefer to embiggen my concept of "function" rather than give it up entirely in the new setting. You're probably already used to this: the random() "function" is not a mathematical function, but we all call it one. There's no specific connection between arrows and two-tuples. It's extremely common to use functions on two-tuples, and every function is an arrow, so the fact that all of those useful (***) and (&&&) live in Control.Arrow is a bit of a premature abstraction. Frequently you'll need to take a function f and a pair (x,y) and want to compute the pair (f x, f y). There should really be a combinator for that! But when you write one, it turns out that it works just as well for arrows. Since all functions are arrows, they just used the more general type. The Kleisli arrow/monad thing isn't wrong, it's just useless without an example. Kleisli arrows are just plain old arrows (think: functions) in a monad. Suppose I want to read a file and then print its contents to the screen. How would I do that? In pseudo-code, it's something like, -- Read a file and print its contents to the screen (putStr . readFile) "/path/to/file.txt" But here, "print" and "readFile" aren't mathematical functions, so we can't compose them! The "." operator only works on functions. It would be great if there were something that was a lot like a function but could be composed in this manner... -- Read a file and print its contents to the screen ghci> import Control.Monad ( (<=<) ) ghci> (putStr <=< readFile) "hw.txt" Hello, world! Another useful example is when you want to "automatically" concatenate a list of results. Let's write a stupid function that duplicates its argument in a list: ghci> let twice x = [x, x] ghci> twice 3 [3,3] So far so good. But now I want four things. Can I compose "twice" with itself? ghci> (twice . twice) 3 [[3,3],[3,3]] ghci> :t (twice . twice) (twice . twice) :: t -> [[t]] Crap, that's giving me a list of lists. I just want one list! By thinking of "twice" as a multi-valued function (a special type of arrow), I can get what I want: ghci> (twice <=< twice) 3 [3,3,3,3] That trick is using the Monad instance for lists, but composition in monads is done with arrows (not mathematical functions). It's put to good use in e.g. HXT where you can say "give me all children of <p> elements that live in a <div> that live in a <body>" and you only want one list back. Without that funny arrow composition, you'd be stuck with lists of lists of lists of lists... ------------------------------ Message: 2 Date: Tue, 16 Feb 2016 13:11:57 -0800 From: Dennis Raddle <dennis.rad...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] arrows and 2-tuples Message-ID: <CAKxLvoqGi1646+r9j_uzgh8H0_j-gM1TkK3XD-bhTxKPDtjK=g...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" 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"? D On Tue, Feb 16, 2016 at 7:22 AM, Michael Orlitzky <mich...@orlitzky.com> wrote: > On 02/16/2016 03:06 AM, Dennis Raddle wrote: > > I am a Haskell beginner. I have used arrows occasionally to move > > 2-tuples around, but don't understand more than that. > > > > I'm interested in know what's the connection between arrows and > > 2-tuples. I don't really understand most of the Control.Arrow docs, but > > it seems that a lot of stuff about arrows doesn't mention 2-tuples. Yet > > the operators (***), (&&&), first, and second seem to be common. Is > > there some way to explain the link? > > > > Also, the main instance of Arrow seems to be (->). There is also > > something about Kleisli monads, but I don't know what those are. Is > > there an another big use case for arrows besides (->)? Don't worry about > > explaining it all, just a quick mention would be fine and I can > > investigate it myself. > > > > An arrow is basically a function and it doesn't hurt to think of them > that way. In mathematics, "function" means something very specific, so > they needed a new name (arrow) for a thing that's a lot like a function > but isn't one. > > You can construct some weird situations where arrows aren't very much > like mathematical functions at all, but it still doesn't hurt to think > of them that way. Mentally I prefer to embiggen my concept of "function" > rather than give it up entirely in the new setting. You're probably > already used to this: the random() "function" is not a mathematical > function, but we all call it one. > > There's no specific connection between arrows and two-tuples. It's > extremely common to use functions on two-tuples, and every function is > an arrow, so the fact that all of those useful (***) and (&&&) live in > Control.Arrow is a bit of a premature abstraction. Frequently you'll > need to take a function f and a pair (x,y) and want to compute the pair > (f x, f y). There should really be a combinator for that! But when you > write one, it turns out that it works just as well for arrows. Since all > functions are arrows, they just used the more general type. > > The Kleisli arrow/monad thing isn't wrong, it's just useless without an > example. Kleisli arrows are just plain old arrows (think: functions) in > a monad. Suppose I want to read a file and then print its contents to > the screen. How would I do that? In pseudo-code, it's something like, > > -- Read a file and print its contents to the screen > (putStr . readFile) "/path/to/file.txt" > > But here, "print" and "readFile" aren't mathematical functions, so we > can't compose them! The "." operator only works on functions. It would > be great if there were something that was a lot like a function but > could be composed in this manner... > > -- Read a file and print its contents to the screen > ghci> import Control.Monad ( (<=<) ) > ghci> (putStr <=< readFile) "hw.txt" > Hello, world! > > Another useful example is when you want to "automatically" concatenate a > list of results. Let's write a stupid function that duplicates its > argument in a list: > > ghci> let twice x = [x, x] > ghci> twice 3 > [3,3] > > So far so good. But now I want four things. Can I compose "twice" with > itself? > > ghci> (twice . twice) 3 > [[3,3],[3,3]] > ghci> :t (twice . twice) > (twice . twice) :: t -> [[t]] > > Crap, that's giving me a list of lists. I just want one list! By > thinking of "twice" as a multi-valued function (a special type of > arrow), I can get what I want: > > ghci> (twice <=< twice) 3 > [3,3,3,3] > > That trick is using the Monad instance for lists, but composition in > monads is done with arrows (not mathematical functions). It's put to > good use in e.g. HXT where you can say "give me all children of <p> > elements that live in a <div> that live in a <body>" and you only want > one list back. Without that funny arrow composition, you'd be stuck with > lists of lists of lists of lists... > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20160216/46cb6937/attachment-0001.html> ------------------------------ Message: 3 Date: Tue, 16 Feb 2016 18:19:05 -0500 From: Michael Orlitzky <mich...@orlitzky.com> To: beginners@haskell.org Subject: Re: [Haskell-beginners] arrows and 2-tuples Message-ID: <56c3ae69.9030...@orlitzky.com> Content-Type: text/plain; charset=utf-8 On 02/16/2016 04:11 PM, Dennis Raddle wrote: > 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"? Sure, they're just a special kind of arrow. My examples used (<=<) because otherwise you won't get the composition "in a monad" and it won't work the way it should: ghci> import Control.Arrow ( (<<<) ) ghci> let twice x = [x, x] ghci> (twice <<< twice) 3 [[3,3],[3,3]] "Why" is a little annoying. Basically, in Haskell, you can only make a structure an instance of a typeclass in one way. This gets in the way when there's more than one valid choice. For example, you might have, data Person = Person { firstname :: String, lastname :: String } Now if you want to display these, how would you do it? Here's one way: instance Show Person where -- FirstName LastName show p = (firstname p) ++ " " ++ (lastname p) But here's another: instance Show Person where -- Lastname, Firstname show p = (lastname p) ++ ", " ++ (firstname p) Which one is correct? They're equally valid... but you can only choose one. If I want both of them, I have to wrap Person in a newtype and then give that newtype a Show instance. Or another way would be to create a second typeclass (Show2?) that acts differently than Show. The same thing happens with these abstract algebraic structures. I can take the set {0, 1} and make it a group in two different ways, but in Haskell, I have to choose only one. What you're seeing with (<<<) versus (<=<) is just one of those choices. When you have a function like "twice", there's an obvious way to make it an arrow -- you define arrow composition to be function composition. In that way you can make every function an Arrow instance by default. But as you saw, there's actually a second and equally-valid way to define the (arrow) composition between things of the type a -> [a]. If you use "composition" from Arrow, you'll get the default function composition, but if you use "composition" from Monad, you'll get the second type. tl;dr if you want a useful example of arrows, you aren't going to get it by using (<<<) on regular functions because all you're going to get is regular function composition, and you already know how that's useful. ------------------------------ Message: 4 Date: Tue, 16 Feb 2016 18:12:12 -0800 From: Dennis Raddle <dennis.rad...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] arrows and 2-tuples Message-ID: <cakxlvoohjxns3rv-5pfpflh1mvi+o3aa++ancxdw+8vsquv...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" okay, got it. thanks!? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20160216/b1438ca0/attachment-0001.html> ------------------------------ Subject: Digest Footer _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners ------------------------------ End of Beginners Digest, Vol 92, Issue 19 *****************************************