Re: [Haskell-cafe] Re: Bathroom reading
ok-4 wrote: Someone mentioned the Blow your mind page. One example there really caught my attention. 1234567 = (1357,246) foldr (\a ~(x,y) - (a:y,x)) ([],[]) I've known about lazy match since an early version of the Haskell report, but have never actually used it. Last night, looking at that example, the lights went on and I finally grokked why it's there and understood when/why I might use it myself. Don't you want an infinite list to illustrate the necessity of laziness? -- View this message in context: http://www.nabble.com/Bathroom-reading-tf4267956.html#a12196642 Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Bathroom reading
Dan Weston wrote: I hate to be a party pooper, but isn't this just: f = foldr (\a z - (a:snd z,fst z)) ([],[]) This takes less time to grok and takes no longer to run. For each type with exported constructors, one can always write deconstructors for it, if not already found in libraries. One may then argue that ~ is never necessary. Given f ( ~(Left (z0,_)) : Right ~(Just z1) : xs ) = (z0, z1, xs) you can always hand-compile to f (x0 : Right y1 : xs) = (fst (getLeft x0), fromJust y1, xs) But ~ is desirable: 0. Which version is easier to understand? That is a bit subjective, but I think it comes down to this. (As do all debates over whether concise notation is readable, really.) To a kid who has not learned the word arctan, I have to say, draw this right-angled triangle, with this side being length 3, that side being length 4, now measure this angle, that is what I mean by arctan(3/4) - you know, all the details, step by step, hand in hand. To a learned adult, I can just say, arctan. In fact, if I spelt out the details to the adult, step by step, hand in hand, he/she would think I'm condescending or counterproductive. Specifically in the case of ~, it makes transparent the structure of the data to be expected: By just reading one spot, you see it wants a list of two or more items, the first item is a Left, in which there is a tuple, the second item is a Right, in which there is a Just. That same information is torned apart without ~: part of the information is on the left, and the rest is hidden on the right to be recovered from the deconstructor calls and re-constructing the picture in your head. This is because it is more low-level. The what is encoded beneath the how. You follow the code execution and then you reverse-engineer its purpose. It is quite attractive when you have no notation to denote the purpose. It is a poor choice when you have a notation to denote the purpose: what data parts are wanted, and when they are wanted, without reading a single function call, the how. 1. Which version is easier to change strictness? Strictness and non-strictness are tricky to get right for performance or even mere feasibility. An important programming activity is investigating various levels of strictness. It is imperative to be able to change strictness efficiently. ~ is already a non-strictness annotation. Anyone who already understands the ! strictness annotation understands this one too. By just toggling ~'s you toggle non-strictness. It's that easy to change. Here is the function again. I'm going to change its strictness. f ( ~(Left (z0,_)) : Right ~(Just z1) : xs ) = (z0, z1, xs) I now want the second cons to be later, the Left to be earlier (at the same time as the first cons), the tuple to be later, the Right to be later (even later than the second cons), and the Just to be earlier (at the same time as the Right). I can do that by just toggling ~'s: f ( Left ~(z0,_) : ~(~(Right (Just z1)) : xs) ) = (z0, z1, xs) Without ~, much more change is necessary. Here is the non-~ code before change again: f (x0 : Right y1 : xs) = (fst (getLeft x0), fromJust y1, xs) The change is: f (Left y0 : xs) = (fst y0, fromJust (getRight (head xs)), tail xs) Both sides have to be changed. On the left, the data structure has to be changed. On the right, the function call structure has to be changed. You have to remove a constructor on the left and add a deconstructor on the right, or add a constructor on the left and remove a deconstructor on the right. This is a dream come true for IDE marketeers. This code manipulation is too annoying to be done by hand on a daily basis, yet mechanical enough to be done by software easily. A marketeer can sell an IDE plugin for this and garner much money and gratitude from unsuspecting programmers, capitalizing on the fact that some languages do not provide an annotation to trivialize this whole business, and in those that do, some programmers refuse to use it. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Bathroom reading
Someone mentioned the Blow your mind page. One example there really caught my attention. 1234567 = (1357,246) foldr (\a ~(x,y) - (a:y,x)) ([],[]) I've known about lazy match since an early version of the Haskell report, but have never actually used it. Last night, looking at that example, the lights went on and I finally grokked why it's there and understood when/why I might use it myself. Oh, I knew perfectly well what it does. It just never made itself at home in my head. I'd like to recommend this example for some sort of prize, therefore. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Bathroom reading
I hate to be a party pooper, but isn't this just: f = foldr (\a z - (a:snd z,fst z)) ([],[]) This takes less time to grok and takes no longer to run. But why stop there? import Control.Arrow swap = snd fst f = foldr (\a - swap first (a:)) ([],[]) Just read this aloud to see what it does (without the tilde encryption algorithm at work!). More importantly, there is manifestly no pattern failure to check for here. It is fun that with ~p we don't need deconstructors for p (reminds me of Lisp's setf), but how many types have exported constructors with no deconstructors? And Arrow notation makes up for the loss of fun, so you don't feel cheated. :) Dan P.S. Either doesn't count, because you can easily roll your own deconstructors: getLeft = either id undefined getRight = either undefined id but I honestly don't know why these aren't in Data.Either. Or for that matter, why swap is not in Control.Arrow, since it comes in handy quite frequently with pointless programming. ok wrote: Someone mentioned the Blow your mind page. One example there really caught my attention. 1234567 = (1357,246) foldr (\a ~(x,y) - (a:y,x)) ([],[]) I've known about lazy match since an early version of the Haskell report, but have never actually used it. Last night, looking at that example, the lights went on and I finally grokked why it's there and understood when/why I might use it myself. Oh, I knew perfectly well what it does. It just never made itself at home in my head. I'd like to recommend this example for some sort of prize, therefore. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Bathroom reading
Maybe something of these? http://www.haskell.org/haskellwiki/Blow_your_mind -- Chad Scherrer Time flies like an arrow; fruit flies like a banana -- Groucho Marx ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Bathroom reading
On 2007-08-14, Spencer Janssen [EMAIL PROTECTED] wrote: On Tuesday 14 August 2007 10:17:53 Dougal Stanton wrote: I'm looking for cool but mind-bending examples of functional brilliance. Let us say, hypothetically, you had a bathroom without any reading material. And having read all the Dilbert and Garfield you could seriously stomach, decide you should educate yourself while on the job. :-) So you decide to print up some one-liner style programs into a little booklet. Something between credit-card and postcard sized, with a neat but mind-bending program on it. Don Stewart occasionally swoops in with some fixpoint malarkey to defuse heated discussions. I mean that kind of thing, but with a slightly wider scope than just fibs... Suggestions, please! D. Here's a small puzzle: without using a Haskell interpreter, explain what the 'foo' function does. foo = filterM (const [True, False]) powerset. Very nice use of the list monad. -- Aaron Denney -- ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe