From rendel at cs.au.dk Fri Jan 1 07:36:41 2010 From: rendel at cs.au.dk (Tillmann Rendel) Date: Fri Jan 1 07:09:55 2010 Subject: [Haskell-cafe] Re: Data.Ring -- Pre-announce In-Reply-To: <5ab17e790912311437i32870c49x616533c902978e2d@mail.gmail.com> References: <4B3D09BA.20504@gmail.com> <5ab17e790912311437i32870c49x616533c902978e2d@mail.gmail.com> Message-ID: <4B3DEC59.4060807@cs.au.dk> Hi, Iavor Diatchki schrieb: > I usually refer to this structure as a RingBuffer. Really? According to my understanding, and to wikipedia [1], a ring buffer is a data structure used to implement O(1) bounded FIFO queues with mutable arrays. So in a ring buffer, you have distinct reading and writing foci, while in John's circular list, you have only one focus for reading and writing. Tillmann [1] http://en.wikipedia.org/wiki/Circular_buffer From tomahawkins at gmail.com Fri Jan 1 10:09:52 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Fri Jan 1 09:43:01 2010 Subject: [Haskell-cafe] Linking in Large ByteStrings Message-ID: <594c1e831001010709g7de915cu92848868aad3921@mail.gmail.com> I have a large tarball I want to link into an executable as a ByteString. What is the best way to do this? I can convert the tarball into a haskell file, but I'm afraid ghc would take a long time to compile it. Is there any way to link constant data directly with ghc? If not, what's the most efficient way to code large ByteStrings for fast compilation? From tomahawkins at gmail.com Fri Jan 1 10:32:23 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Fri Jan 1 10:05:34 2010 Subject: [Haskell-cafe] Timing in atom -- how consistent? In-Reply-To: <42784f260912311943t22976bc6n24d2b31ffd4f3b67@mail.gmail.com> References: <42784f260912311943t22976bc6n24d2b31ffd4f3b67@mail.gmail.com> Message-ID: <594c1e831001010732v7bdbcdadm140ffdfaff7702a7@mail.gmail.com> On Fri, Jan 1, 2010 at 4:43 AM, Jason Dusek wrote: > ?I'm working with Atom to program an ATtiny25. I am curious > ?about how consistent the timings actually are. The function returned by Atom is intended to be called periodically, preferably using some hardware timer, like this: while (1) { waitForNextSample(); atomGeneratedFunction(); } This provides consistent cycle-to-cycle timing. However, the events that occur within the Atom function will most likely vary in time from call to call, due to rules being scheduled at different periods. > > ?Also, I am a little puzzled by the `__coverage` variable. What > ?does it do? __coverage keeps track of which rules have fired during the execution of a program to provide some measure of code coverage. The compiler returns RuleCoverage[1], which is a list of rule names with associated indices bit positions to the __coverage array. Inside an Atom program, you can access this array with nextCoverage[2], which provides the current index and value of __coverage[index]. Repeated calls to nextCoverage would loop through the __coverage array. This feature was added before Atom had support for arrays, so it should probably be rewritten as some point in the future. [1] type RuleCoverage = [(Name, Int, Int)] [2] nextCoverage :: Atom (E Word32, E Word32) > > ?As for my project/motivation -- I'm just trying to blink a > ?little LED on much less robust/rich kit -- the Trippy RGB > ?Waves kit from Lady Ada. I am (gratuitously) exploring ways to > ?program it with Haskell. > > -- > Jason Dusek > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From vanenkj at gmail.com Fri Jan 1 10:48:53 2010 From: vanenkj at gmail.com (John Van Enk) Date: Fri Jan 1 10:22:05 2010 Subject: [Haskell-cafe] Timing in atom -- how consistent? In-Reply-To: <42784f260912311943t22976bc6n24d2b31ffd4f3b67@mail.gmail.com> References: <42784f260912311943t22976bc6n24d2b31ffd4f3b67@mail.gmail.com> Message-ID: Hi Jason, Regarding timing, the version of blink_atom.c below does not contain this, but my later versions used the hardware timers to control the blink rate. One can setup the interrupt vector for a hardware timer to call your outermost atom function at whatever resolution you want. As long as the timer allows enough time between expirations for any of the task groups to finish, it will run in hard real time. Hope this helps. John Van Enk On Thu, Dec 31, 2009 at 10:43 PM, Jason Dusek wrote: > I'm working with Atom to program an ATtiny25. I am curious > about how consistent the timings actually are. > > Consider John Van Enk' example of blinking a LED on an > Arduino: > > http://code.sw17ch.com/blog/atom/blink_atom.c > > We see that sometimes `setLED' is executed and sometimes not. > When `__clock' is incremented, it will be incremented > sometimes sooner, sometimes later. > > Also, I am a little puzzled by the `__coverage` variable. What > does it do? > > As for my project/motivation -- I'm just trying to blink a > little LED on much less robust/rich kit -- the Trippy RGB > Waves kit from Lady Ada. I am (gratuitously) exploring ways to > program it with Haskell. > > -- > Jason Dusek > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100101/f72c2744/attachment.html From vanenkj at gmail.com Fri Jan 1 10:51:18 2010 From: vanenkj at gmail.com (John Van Enk) Date: Fri Jan 1 10:24:30 2010 Subject: [Haskell-cafe] Timing in atom -- how consistent? In-Reply-To: References: <42784f260912311943t22976bc6n24d2b31ffd4f3b67@mail.gmail.com> Message-ID: I remembered that I have some of this stuff on github. Here's the example C file that sets up the timers on an Ardunio board. http://github.com/sw17ch/atom-arduino-experiments/blob/master/Blink/blink.c Notice that the main function does nothing. All the work is done by blink_atom() which is called out of the ISR (Interrupt Service Routine). On Fri, Jan 1, 2010 at 10:48 AM, John Van Enk wrote: > Hi Jason, > > Regarding timing, the version of blink_atom.c below does not contain this, > but my later versions used the hardware timers to control the blink rate. > > One can setup the interrupt vector for a hardware timer to call your > outermost atom function at whatever resolution you want. As long as the > timer allows enough time between expirations for any of the task groups to > finish, it will run in hard real time. > > Hope this helps. > > John Van Enk > > > On Thu, Dec 31, 2009 at 10:43 PM, Jason Dusek wrote: > >> I'm working with Atom to program an ATtiny25. I am curious >> about how consistent the timings actually are. >> >> Consider John Van Enk' example of blinking a LED on an >> Arduino: >> >> http://code.sw17ch.com/blog/atom/blink_atom.c >> >> We see that sometimes `setLED' is executed and sometimes not. >> When `__clock' is incremented, it will be incremented >> sometimes sooner, sometimes later. >> >> Also, I am a little puzzled by the `__coverage` variable. What >> does it do? >> >> As for my project/motivation -- I'm just trying to blink a >> little LED on much less robust/rich kit -- the Trippy RGB >> Waves kit from Lady Ada. I am (gratuitously) exploring ways to >> program it with Haskell. >> >> -- >> Jason Dusek >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100101/6ecb61fd/attachment.html From svein.ove at aas.no Fri Jan 1 11:49:50 2010 From: svein.ove at aas.no (Svein Ove Aas) Date: Fri Jan 1 11:23:02 2010 Subject: [Haskell-cafe] Linking in Large ByteStrings In-Reply-To: <594c1e831001010709g7de915cu92848868aad3921@mail.gmail.com> References: <594c1e831001010709g7de915cu92848868aad3921@mail.gmail.com> Message-ID: <221b53ab1001010849m42bae655ice7753673d1b5a92@mail.gmail.com> On Fri, Jan 1, 2010 at 4:09 PM, Tom Hawkins wrote: > I have a large tarball I want to link into an executable as a > ByteString. ?What is the best way to do this? ?I can convert the > tarball into a haskell file, but I'm afraid ghc would take a long time > to compile it. ?Is there any way to link constant data directly with > ghc? ?If not, what's the most efficient way to code large ByteStrings > for fast compilation? > In the limit, you can convert it to an assembly file. Something like this, though I've done very little checking indeed of the syntax. Consider this to be pseudocode. foo.s ==== .global bytestring, bytestring_end .label bytestring .db 0x0c 0xdf 0xwhatever .label bytestring_end foo.hs === import Foreign import Data.ByteString.Internal foreign import ptr bytestring :: Ptr Word8 foreign import ptr bytestring_end :: Ptr Word8 yourString :: ByteString yourString = unsafePerformIO $ do fptr <- newForeignPtr_ bytestring return $ fromForeignPtr (fptr, bytestring_end `minusPtr` bytestring, 0) -- ^ If I got the foreignPtr parameter order right Unfortunately Data.ByteString.Internal, though still exported, is no longer haddocked; this makes it hard to check the parameters. You should go look up the 6.10.1 version's documentation, which is still correct. -- Svein Ove Aas From pumpkingod at gmail.com Fri Jan 1 12:59:34 2010 From: pumpkingod at gmail.com (Daniel Peebles) Date: Fri Jan 1 12:32:44 2010 Subject: [Haskell-cafe] Re: [BostonHaskell] Haskell Hackathon in Boston January 29th-31st? In-Reply-To: <161d443c0911211236y71a2ebefp8a6289c7b3cc6cd9@mail.gmail.com> References: <161d443c0911211236y71a2ebefp8a6289c7b3cc6cd9@mail.gmail.com> Message-ID: Is there any news on this? I'd be up for it! Thanks, Dan On Sat, Nov 21, 2009 at 9:36 PM, Ravi Nanavati wrote: > After all of the fun I had at Hac Phi, I've been thinking for a while > that it would be fun to organize a Boston hackathon (to have all of > the hackathon fun without the long drive). After some recent chats > with my MIT friends, it seems like the weekend just after IAP (January > 29th-January 31st) might be a good one. > > I've created a page to start organizing this hackathon (which I'm > calling HacBOS unless someone comes up with a catchier name) here: > http://www.haskell.org/haskellwiki/HacBOS > > If you'd be interested in attending a Boston hackathon, please add > yourself to the possible attendees list on that page. If the proposed > weekend does NOT work for you, but you're still interested in > attending a Boston hackathon please indicate what other weekends > during MIT's IAP (January 4th-January 29th) might work for you. > > I'm looking forward to making HacBOS happen! > > Thanks, > > - Ravi Nanavati > > -- > > You received this message because you are subscribed to the Google Groups > "BostonHaskell" group. > To post to this group, send email to bostonhaskell@googlegroups.com. > To unsubscribe from this group, send email to > bostonhaskell+unsubscribe@googlegroups.com > . > For more options, visit this group at > http://groups.google.com/group/bostonhaskell?hl=. > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100101/4b68572e/attachment-0001.html From ezyang at MIT.EDU Fri Jan 1 13:27:49 2010 From: ezyang at MIT.EDU (Edward Z. Yang) Date: Fri Jan 1 13:01:37 2010 Subject: [Haskell-cafe] Use of the Try typeclass In-Reply-To: <57526e770912302313k54c29c70jd09d1c4b61d09ae9@mail.gmail.com> References: <1262223783-sup-5099@ezyang> <57526e770912302106s44e75c87jd86806f50c514611@mail.gmail.com> <1262236175-sup-6707@ezyang> <29bf512f0912302143k77a9779egf31a55cc2be8edee@mail.gmail.com> <1262242441-sup-9805@ezyang> <57526e770912302313k54c29c70jd09d1c4b61d09ae9@mail.gmail.com> Message-ID: <1262370427-sup-7492@ezyang> I upgraded, but now both Control.Monad.Failure and Control.Monad.Error claim to be exporting "Error". Is this correct, and if so, which one should I hide? Cheers, Edward From ezyang at MIT.EDU Fri Jan 1 13:30:51 2010 From: ezyang at MIT.EDU (Edward Z. Yang) Date: Fri Jan 1 13:04:16 2010 Subject: [Haskell-cafe] Use of the Try typeclass In-Reply-To: <1262370427-sup-7492@ezyang> References: <1262223783-sup-5099@ezyang> <57526e770912302106s44e75c87jd86806f50c514611@mail.gmail.com> <1262236175-sup-6707@ezyang> <29bf512f0912302143k77a9779egf31a55cc2be8edee@mail.gmail.com> <1262242441-sup-9805@ezyang> <57526e770912302313k54c29c70jd09d1c4b61d09ae9@mail.gmail.com> <1262370427-sup-7492@ezyang> Message-ID: <1262370582-sup-6666@ezyang> Excerpts from Edward Z. Yang's message of Fri Jan 01 13:27:49 -0500 2010: > I upgraded, but now both Control.Monad.Failure and Control.Monad.Error > claim to be exporting "Error". Is this correct, and if so, which one > should I hide? Sorry my bad; I should have been importing Control.Monad.Failure.MTL. The error has gone away. Cheers, Edwadrd From pirelo at googlemail.com Fri Jan 1 14:07:49 2010 From: pirelo at googlemail.com (Pablo Nogueira) Date: Fri Jan 1 13:41:00 2010 Subject: [Haskell-cafe] ANN: WFLP 2010 Call for participation Message-ID: ******************************************************************** Call For Participation WFLP2010 19th International Workshop on Functional and (Constraint) Logic Programming Madrid, Spain, January 17, 2010 http://babel.ls.fi.upm.es/events/wflp2010/ ********* colocated with Principles of Programming Languages POPL 2010 http://www.cse.psu.edu/popl/10/ ******************************************************************** IMPORTANT DATES Hotel reservation deadline: December 28, 2009 VENUE WFLP2010 and all POPL'10 affiliated events will take place at the Melia Castilla Hotel, Madrid. REGISTRATION To register for WFLP2010, follow the link from the POPL 2010 page, at http://www.cse.psu.edu/popl/10/ SCOPE The aim of the Workshop on Functional and (Constraint) Logic Programming is to bring together researchers interested in functional programming and (constraint) logic programming with special emphasis on the integration of both paradigms and of other declarative programming extensions. It promotes the cross-fertilizing exchange of ideas and experiences among researchers and students from the different communities interested in the foundations, applications, and combinations of high-level declarative programming languages and related areas. INVITED SPEAKER Mariangiola Dezani (University of Torino, Italy) ACCEPTED PAPERS Transforming Functional Logic Programs into Monadic Functional Programs Bernd Brassel, Sebastian Fischer, Michael Hanus and Fabian Reck Mixed-level Embedding and JIT Compilation for an Iteratively Staged DSL George Giorgidze and Henrik Nilsson An Access Control Language based on Term Rewriting and Description Logic Michele Baggi, Demis Ballis and Moreno Falaschi Lazy and Faithful Assertions for Functional Logic Programs Michael Hanus Parameterized Models for On-line and Off-line Use Pieter Wuille and Tom Schrijvers A Denotational Semantics for Curry Jan Christiansen, Daniel Seidel and Janis Voigtlander A Declarative Debugger of Missing Answers for Functional and Logic Programming Rafael del Vado Virseda and Fernando Perez Morente Efficient and Compositional Higher-Order Streams Gergely Patai Bridging the gap between two Concurrent Constraint Languages Alexei Lescaylle Daudinot and Alicia Villanueva Garcia Large scale random testing with QuickCheck on MapReduce framework Shigeru Kusakabe and Yuuki Ikuta Automated verification of security protocols in tccp Alexei Lescaylle Daudinot and Alicia Villanueva Garcia Implementation and Evaluation of a Declarative Debugger for Java Herbert Kuchen and Christian Hermanns PROGRAM CHAIR Julio Marino (Universidad Politecnica de Madrid, Spain) PROGRAM COMMITTEE Maria Alpuente (Universidad Politecnica de Valencia, Spain) Sergio Antoy (Portland State University, USA) Bernd Brassel (CAU Kiel, Germany) Olaf Chitil (Univ. of Kent, UK) Rachid Echahed (CNRS-IMAG, France) Santiago Escobar (Universidad Politecnica de Valencia, Spain) Moreno Falaschi (Universita di Siena, Italy) Murdoch Gabbay (Heriot-Watt University, UK) Maria Garcia de la Banda (Monash University, Australia) Victor Gulias (Lambdastream SL, Spain) Michael Hanus (CAU Kiel, Germany) Herbert Kuchen (Univ. of Muenster, Germany) Francisco Lopez-Fraguas (Universidad Complutense de Madrid, Spain) James Lipton (Wesleyan University, USA) Mircea Marin (Univ. of Tsukuba, Japan) Juan Jose Moreno-Navarro (Ministry of Science & Innovation, Spain) Brigitte Pientka (McGill University, Canada) -------------- next part -------------- ******************************************************************** Call For Participation WFLP2010 19th International Workshop on Functional and (Constraint) Logic Programming Madrid, Spain, January 17, 2010 http://babel.ls.fi.upm.es/events/wflp2010/ ********* colocated with Principles of Programming Languages POPL 2010 http://www.cse.psu.edu/popl/10/ ******************************************************************** IMPORTANT DATES Hotel reservation deadline: December 28, 2009 VENUE WFLP2010 and all POPL'10 affiliated events will take place at the Melia Castilla Hotel, Madrid. REGISTRATION To register for WFLP2010, follow the link from the POPL 2010 page, at http://www.cse.psu.edu/popl/10/ SCOPE The aim of the Workshop on Functional and (Constraint) Logic Programming is to bring together researchers interested in functional programming and (constraint) logic programming with special emphasis on the integration of both paradigms and of other declarative programming extensions. It promotes the cross-fertilizing exchange of ideas and experiences among researchers and students from the different communities interested in the foundations, applications, and combinations of high-level declarative programming languages and related areas. INVITED SPEAKER Mariangiola Dezani (University of Torino, Italy) ACCEPTED PAPERS Transforming Functional Logic Programs into Monadic Functional Programs Bernd Brassel, Sebastian Fischer, Michael Hanus and Fabian Reck Mixed-level Embedding and JIT Compilation for an Iteratively Staged DSL George Giorgidze and Henrik Nilsson An Access Control Language based on Term Rewriting and Description Logic Michele Baggi, Demis Ballis and Moreno Falaschi Lazy and Faithful Assertions for Functional Logic Programs Michael Hanus Parameterized Models for On-line and Off-line Use Pieter Wuille and Tom Schrijvers A Denotational Semantics for Curry Jan Christiansen, Daniel Seidel and Janis Voigtlander A Declarative Debugger of Missing Answers for Functional and Logic Programming Rafael del Vado Virseda and Fernando Perez Morente Efficient and Compositional Higher-Order Streams Gergely Patai Bridging the gap between two Concurrent Constraint Languages Alexei Lescaylle Daudinot and Alicia Villanueva Garcia Large scale random testing with QuickCheck on MapReduce framework Shigeru Kusakabe and Yuuki Ikuta Automated verification of security protocols in tccp Alexei Lescaylle Daudinot and Alicia Villanueva Garcia Implementation and Evaluation of a Declarative Debugger for Java Herbert Kuchen and Christian Hermanns PROGRAM CHAIR Julio Marino (Universidad Politecnica de Madrid, Spain) PROGRAM COMMITTEE Maria Alpuente (Universidad Politecnica de Valencia, Spain) Sergio Antoy (Portland State University, USA) Bernd Brassel (CAU Kiel, Germany) Olaf Chitil (Univ. of Kent, UK) Rachid Echahed (CNRS-IMAG, France) Santiago Escobar (Universidad Politecnica de Valencia, Spain) Moreno Falaschi (Universita di Siena, Italy) Murdoch Gabbay (Heriot-Watt University, UK) Maria Garcia de la Banda (Monash University, Australia) Victor Gulias (Lambdastream SL, Spain) Michael Hanus (CAU Kiel, Germany) Herbert Kuchen (Univ. of Muenster, Germany) Francisco Lopez-Fraguas (Universidad Complutense de Madrid, Spain) James Lipton (Wesleyan University, USA) Mircea Marin (Univ. of Tsukuba, Japan) Juan Jose Moreno-Navarro (Ministry of Science & Innovation, Spain) Brigitte Pientka (McGill University, Canada) From jmillikin at gmail.com Fri Jan 1 14:11:42 2010 From: jmillikin at gmail.com (John Millikin) Date: Fri Jan 1 13:45:12 2010 Subject: [Haskell-cafe] Linking in Large ByteStrings In-Reply-To: <221b53ab1001010849m42bae655ice7753673d1b5a92@mail.gmail.com> References: <594c1e831001010709g7de915cu92848868aad3921@mail.gmail.com> <221b53ab1001010849m42bae655ice7753673d1b5a92@mail.gmail.com> Message-ID: <3283f7fe1001011111y84109c9tb872e1af20ae8a73@mail.gmail.com> On Fri, Jan 1, 2010 at 08:49, Svein Ove Aas wrote: > foo.hs > === > foreign import ptr bytestring :: Ptr Word8 > foreign import ptr bytestring_end :: Ptr Word8 Is this valid syntax? I get a syntax error in 6.10.1, and I don't see it documented in the FFI report. From jason.dusek at gmail.com Fri Jan 1 14:51:22 2010 From: jason.dusek at gmail.com (Jason Dusek) Date: Fri Jan 1 14:24:32 2010 Subject: [Haskell-cafe] Timing in atom -- how consistent? In-Reply-To: References: <42784f260912311943t22976bc6n24d2b31ffd4f3b67@mail.gmail.com> Message-ID: <42784f261001011151s607575deyd6d3507206b055aa@mail.gmail.com> 2010/1/1 John Van Enk : > I remembered that I have some of this stuff on github. Here's > the example C file that sets up the timers on an Ardunio > board. > > http://github.com/sw17ch/atom-arduino-experiments/blob/master/Blink/blink.c > > Notice that the main function does nothing. All the work is > done by blink_atom() which is called out of the ISR (Interrupt > Service Routine). Thanks for the example. -- Jason Dusek From jason.dusek at gmail.com Fri Jan 1 14:53:21 2010 From: jason.dusek at gmail.com (Jason Dusek) Date: Fri Jan 1 14:26:30 2010 Subject: [Haskell-cafe] Timing in atom -- how consistent? In-Reply-To: <594c1e831001010732v7bdbcdadm140ffdfaff7702a7@mail.gmail.com> References: <42784f260912311943t22976bc6n24d2b31ffd4f3b67@mail.gmail.com> <594c1e831001010732v7bdbcdadm140ffdfaff7702a7@mail.gmail.com> Message-ID: <42784f261001011153k46261029y56cc47ee25be8ef8@mail.gmail.com> 2010/1/1 Tom Hawkins : > ...the events that occur within the Atom function will most > likely vary in time from call to call, due to rules being > scheduled at different periods. So the purpose of the "period" is really not so much to set a consistent execution time as it is to ensure non-interleaved execution for safe multi-threading? -- Jason Dusek From jason.dusek at gmail.com Fri Jan 1 15:02:17 2010 From: jason.dusek at gmail.com (Jason Dusek) Date: Fri Jan 1 14:35:26 2010 Subject: [Haskell-cafe] Timing in atom -- how consistent? In-Reply-To: <42784f261001011153k46261029y56cc47ee25be8ef8@mail.gmail.com> References: <42784f260912311943t22976bc6n24d2b31ffd4f3b67@mail.gmail.com> <594c1e831001010732v7bdbcdadm140ffdfaff7702a7@mail.gmail.com> <42784f261001011153k46261029y56cc47ee25be8ef8@mail.gmail.com> Message-ID: <42784f261001011202n5cf53beah3834d5431c29beef@mail.gmail.com> Wait, no -- I missed something. As long as the outermost Atom routine is run every `n' ?s by a hardware clock, the counter (`__global_clock') will contain an accurate count of how many `n' ?s intervals have passed in our application. -- Jason Dusek From vanenkj at gmail.com Fri Jan 1 16:17:16 2010 From: vanenkj at gmail.com (John Van Enk) Date: Fri Jan 1 15:50:27 2010 Subject: [Haskell-cafe] Timing in atom -- how consistent? In-Reply-To: <42784f261001011202n5cf53beah3834d5431c29beef@mail.gmail.com> References: <42784f260912311943t22976bc6n24d2b31ffd4f3b67@mail.gmail.com> <594c1e831001010732v7bdbcdadm140ffdfaff7702a7@mail.gmail.com> <42784f261001011153k46261029y56cc47ee25be8ef8@mail.gmail.com> <42784f261001011202n5cf53beah3834d5431c29beef@mail.gmail.com> Message-ID: Yes, exactly. On Fri, Jan 1, 2010 at 3:02 PM, Jason Dusek wrote: > Wait, no -- I missed something. As long as the outermost Atom > routine is run every `n' ?s by a hardware clock, the counter > (`__global_clock') will contain an accurate count of how many > `n' ?s intervals have passed in our application. > > -- > Jason Dusek > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100101/2389a956/attachment.html From judah.jacobson at gmail.com Fri Jan 1 16:19:42 2010 From: judah.jacobson at gmail.com (Judah Jacobson) Date: Fri Jan 1 15:53:11 2010 Subject: [Haskell-cafe] Linking in Large ByteStrings In-Reply-To: <594c1e831001010709g7de915cu92848868aad3921@mail.gmail.com> References: <594c1e831001010709g7de915cu92848868aad3921@mail.gmail.com> Message-ID: <6d74b0d21001011319q5f6dcbe0w1cf4b0a65c726326@mail.gmail.com> On Fri, Jan 1, 2010 at 7:09 AM, Tom Hawkins wrote: > I have a large tarball I want to link into an executable as a > ByteString. ?What is the best way to do this? ?I can convert the > tarball into a haskell file, but I'm afraid ghc would take a long time > to compile it. ?Is there any way to link constant data directly with > ghc? ?If not, what's the most efficient way to code large ByteStrings > for fast compilation? Possibly the simplest is to use unsafePackAddress or unsafePackAddressLen: {-# LANGUAGE MagicHash #-} module Const where import Data.ByteString.Unsafe as U import System.IO.Unsafe my_bstr = unsafePerformIO $ U.unsafePackAddress "abcdefg"# This trick of embedding raw strings (of type Addr#) is how happy and alex store their parser lookup tables in the modules they generate. I haven't seen any performance issues with it myself. Hope that helps, -Judah From pgsql at j-davis.com Fri Jan 1 17:17:09 2010 From: pgsql at j-davis.com (Jeff Davis) Date: Fri Jan 1 16:53:12 2010 Subject: [Haskell-cafe] lazily-loaded structures Message-ID: <1262384229.22866.9096.camel@jdavis> I'm relatively new to haskell. Let's say I have a simple program like this: import Data.Map type Tree = String type StringMap = Map String String f :: StringMap -> Tree -> Tree f _ y = y ++ "!" getStringMap :: IO StringMap getStringMap = return (Data.Map.fromList [("k1","v1")]) main :: IO () main = do m <- getStringMap s <- getLine putStr $ show (f m s) ++ "\n" Ignore the implementation of f and getStringMap for now. Assume f is a fairly complex function that uses the Map during the process of transforming the Tree argument into the result Tree (here I defined Tree as a string just so that it would compile). getStringMap reads the whole Map into memory at once. However, now let's say that the whole Map is too large, so I decide to store it over a network in a remote database system instead. And then I define another function like: type Connection = String getStringMapValue :: Connection -> String -> IO String that takes a connection string and a key and returns the value. My question is this: how do I change my program to make StringMap a lazily-loaded structure based on getStringMapValue without changing f? Regards, Jeff Davis From svein.ove at aas.no Fri Jan 1 17:33:01 2010 From: svein.ove at aas.no (Svein Ove Aas) Date: Fri Jan 1 17:06:11 2010 Subject: [Haskell-cafe] Linking in Large ByteStrings In-Reply-To: <3283f7fe1001011111y84109c9tb872e1af20ae8a73@mail.gmail.com> References: <594c1e831001010709g7de915cu92848868aad3921@mail.gmail.com> <221b53ab1001010849m42bae655ice7753673d1b5a92@mail.gmail.com> <3283f7fe1001011111y84109c9tb872e1af20ae8a73@mail.gmail.com> Message-ID: <221b53ab1001011433t25e7d193w1559fb4980969fad@mail.gmail.com> On Fri, Jan 1, 2010 at 8:11 PM, John Millikin wrote: > On Fri, Jan 1, 2010 at 08:49, Svein Ove Aas wrote: >> foo.hs >> === >> foreign import ptr bytestring :: Ptr Word8 >> foreign import ptr bytestring_end :: Ptr Word8 > > Is this valid syntax? I get a syntax error in 6.10.1, and I don't see > it documented in the FFI report. > That's why I called it pseudocode. No, it's not valid syntax, though it wouldn't have overly surprised me if it were. You probably get the idea, though; importing a symbol, instead of a function. Actually reading the FFi got me this, though: foreign import ccall "&" bytestring :: Ptr Word8 foreign import ccall "&" bytestring_end :: Ptr Word8 -- Svein Ove Aas From qdunkan at gmail.com Fri Jan 1 18:07:49 2010 From: qdunkan at gmail.com (Evan Laforge) Date: Fri Jan 1 17:40:59 2010 Subject: [Haskell-cafe] lazily-loaded structures In-Reply-To: <1262384229.22866.9096.camel@jdavis> References: <1262384229.22866.9096.camel@jdavis> Message-ID: <2518b95d1001011507i13422253l8da4657f538678c1@mail.gmail.com> > My question is this: how do I change my program to make StringMap a > lazily-loaded structure based on getStringMapValue without changing f? You can't, because 'f' has a pure signature, but you want it to run network operations, which are not pure. You could say it's logically pure if you guarantee that no one else is modifying the DB while your program is running, and you are willing to completely abort on a network error, in which case there's a hack called unsafeInterleaveIO. However, I'm guessing no one is going to recommend actually doing that. The Prelude getContents function does that and it gets a lot of flak for poor error handling, not closing the handle when you want it to, etc. Talking over the network will have all those same problems. If you want to operate over a large structure and hide the fetching part, you can look into the iteratee stuff. Basically you would define a function that opens a socket, passes chunks of data to a passed in pure iteratee function, and closes the socket afterwards. If you have a random access Map then I can't think of anything more elegant than the standard imperative "lookup :: Key -> RemoteMap -> IO Val" possibly with caching. Put the reading strategy in an IO function, and the rest of the processing in passed-in pure functions. From daniel.is.fischer at web.de Fri Jan 1 19:06:26 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Fri Jan 1 18:41:11 2010 Subject: [Haskell-cafe] ANNOUNCE: restyle-0.1.0 Message-ID: <201001020106.26569.daniel.is.fischer@web.de> I have the pleasure to announce restyle-0.1.0, a tool for the conversion of Haskell source between camelCase and separated_words style. If you want to read your local haddockumentation in your favourite separated-words style, it can do that too, with a liberal choice of separation characters. If you prefer to do your coding in separated_words, it may be as easy as one restyle to then deliver your cool library to the world in the prevalent camelCase (well, it'll probably take a few minor version bumps before that, but we can hope). If you love underscores or hyphens, give it a try. If it sucks, at least it wasn't *your* wasted effort :) -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100101/5380a84b/attachment.html From tomahawkins at gmail.com Fri Jan 1 19:15:37 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Fri Jan 1 18:48:45 2010 Subject: [Haskell-cafe] Linking in Large ByteStrings In-Reply-To: <221b53ab1001011433t25e7d193w1559fb4980969fad@mail.gmail.com> References: <594c1e831001010709g7de915cu92848868aad3921@mail.gmail.com> <221b53ab1001010849m42bae655ice7753673d1b5a92@mail.gmail.com> <3283f7fe1001011111y84109c9tb872e1af20ae8a73@mail.gmail.com> <221b53ab1001011433t25e7d193w1559fb4980969fad@mail.gmail.com> Message-ID: <594c1e831001011615sf2f3c99r9a753d9c17f3e2cb@mail.gmail.com> Thanks, this worked great. Just a few seconds to link in a 5M tarball. Details: test.s: .global test_data test_data: .byte 0 .byte 1 .byte 2 ... Foo.hs: import Foreign import Data.ByteString.Internal import Data.Word import System.IO.Unsafe foreign import ccall "&" test_data :: Ptr Word8 test :: ByteString test = fromForeignPtr (unsafePerformIO (newForeignPtr_ test_data)) 0 lengthOfTestData Compiled with: ghc --make -W -fglasgow-exts -o something test.s ... From pgsql at j-davis.com Fri Jan 1 20:24:30 2010 From: pgsql at j-davis.com (Jeff Davis) Date: Fri Jan 1 20:00:34 2010 Subject: [Haskell-cafe] lazily-loaded structures In-Reply-To: <2518b95d1001011507i13422253l8da4657f538678c1@mail.gmail.com> References: <1262384229.22866.9096.camel@jdavis> <2518b95d1001011507i13422253l8da4657f538678c1@mail.gmail.com> Message-ID: <1262395470.22866.9160.camel@jdavis> On Fri, 2010-01-01 at 15:07 -0800, Evan Laforge wrote: > You could say it's logically pure if you guarantee that no one else is > modifying the DB while your program is running, and you are willing to > completely abort on a network error, in which case there's a hack > called unsafeInterleaveIO. What do you mean by "completely abort"? Couldn't it simply raise an exception that could be handled in main? > However, I'm guessing no one is going to recommend actually doing > that. The Prelude getContents function does that and it gets a lot of > flak for poor error handling, not closing the handle when you want it > to, etc. Talking over the network will have all those same problems. Yes, when I saw the definition of getContents, I suspected problems were possible. > If you want to operate over a large structure and hide the fetching > part, you can look into the iteratee stuff. Basically you would > define a function that opens a socket, passes chunks of data to a > passed in pure iteratee function, and closes the socket afterwards. > If you have a random access Map then I can't think of anything more > elegant than the standard imperative "lookup :: Key -> RemoteMap -> IO > Val" possibly with caching. Put the reading strategy in an IO > function, and the rest of the processing in passed-in pure functions. Interesting. I wonder if it might be useful to approach it like a virtual memory system. Searching for a value that hasn't been loaded into the structure would raise an exception, which would then be caught, handled by using normal (safe) IO, and then the computation could be retried. Is that idea crazy, or does it have some merit? Regards, Jeff Davis From lrpalmer at gmail.com Fri Jan 1 20:37:50 2010 From: lrpalmer at gmail.com (Luke Palmer) Date: Fri Jan 1 20:10:59 2010 Subject: [Haskell-cafe] lazily-loaded structures In-Reply-To: <1262395470.22866.9160.camel@jdavis> References: <1262384229.22866.9096.camel@jdavis> <2518b95d1001011507i13422253l8da4657f538678c1@mail.gmail.com> <1262395470.22866.9160.camel@jdavis> Message-ID: <7ca3f0161001011737i6e0919ffnc716c3814de55ef8@mail.gmail.com> On Fri, Jan 1, 2010 at 6:24 PM, Jeff Davis wrote: > I wonder if it might be useful to approach it like a virtual memory > system. Searching for a value that hasn't been loaded into the structure > would raise an exception, which would then be caught, handled by using > normal (safe) IO, and then the computation could be retried. > > Is that idea crazy, or does it have some merit? No, pretty much crazy. Exceptions are just as impure as any other effect. To capture network computations, abstract them out, into eg. a type "Network a" which represents values which depend on network data. It would naturally be monadic, but you can restrict the operations so that Network can only do specific things - eg. reading, not writing, not overwritng your hard drive, not throwing exceptions (or throwing them if you want it to), etc. This is the typical method of abstracting over IO in Haskell. As a sort of dual to the OO way, where you start with simple operations and add features, we start with "anything" (the IO monad) and take away features until we have something we can reason about. Luke From jason.dusek at gmail.com Fri Jan 1 20:52:56 2010 From: jason.dusek at gmail.com (Jason Dusek) Date: Fri Jan 1 20:26:06 2010 Subject: [Haskell-cafe] ANN: HPath-0.0.2 Message-ID: <42784f261001011752i32b6bceoe4c91e25b24ae3a9@mail.gmail.com> This version of `HPath' depends on new release of `haskell-src-exts' with improved pretty printing. http://hackage.haskell.org/package/HPath-0.0.2 No other changes have been made. -- Jason Dusek From qdunkan at gmail.com Fri Jan 1 23:32:46 2010 From: qdunkan at gmail.com (Evan Laforge) Date: Fri Jan 1 23:05:56 2010 Subject: [Haskell-cafe] lazily-loaded structures In-Reply-To: <1262395470.22866.9160.camel@jdavis> References: <1262384229.22866.9096.camel@jdavis> <2518b95d1001011507i13422253l8da4657f538678c1@mail.gmail.com> <1262395470.22866.9160.camel@jdavis> Message-ID: <2518b95d1001012032h62d2b02fo998eeadf6325cfbe@mail.gmail.com> > What do you mean by "completely abort"? Couldn't it simply raise an > exception that could be handled in main? Yeah, that's what I meant by complete abort. You don't get to save the work you did get done. You could checkpoint progress, but of course that's an impure operation. From will_n48 at yahoo.com Sat Jan 2 08:13:29 2010 From: will_n48 at yahoo.com (Will Ness) Date: Sat Jan 2 07:47:02 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <200912292017.01409.daniel.is.fischer@web.de> <200912300316.49130.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > > Am Mittwoch 30 Dezember 2009 20:46:57 schrieb Will Ness: > > Daniel Fischer web.de> writes: > > > Am Dienstag 29 Dezember 2009 20:16:59 schrieb Daniel Fischer: > > > > > especially the claim that going by primes squares > > > > > is "a pleasing but minor optimization", > > > > > > > > Which it is not. It is a major optimisation. It reduces the algorithmic > > > > complexity *and* reduces the constant factors significantly. > > > > > > D'oh! Thinko while computing sum (takeWhile (<= n) primes) without paper. > > > It doesn't change the complexity, and the constant factors are reduced > > > far less than I thought. > > > > I do not understand. Turner's sieve is > > > > primes = sieve [2..] > > where > > sieve (p:xs) = p : sieve [x | x<-xs, x `mod` p /= 0] > > > > and the Postponed Filters is > > > > primes = 2: 3: sieve (tail primes) [5,7..] > > where > > sieve (p:ps) xs = h ++ sieve ps [x | x<-t, x `rem` p /= 0] > > where (h,~(_:t)) = span (< p*p) xs > > > > Are you saying they both exhibit same complexity? > > No. They don't. > But if you're looking at an imperative (mutable array) sieve (that's simpler > to analyse because you don't have to take the book-keeping costs of your > priority queue, heap or whatever into account), if you start crossing out The key question then, is _*WHEN*_ and not _*WHAT*_. As is clearly demonstrated by the case of Turner/Postponed filters, the work that is done (of crossing numbers off) is the same - _when_ it is actually done - but Turner's starts out so _prematurely_ that it is busy doing nothing most of the time. Thus its function call overhead costs pile up enormously, overstaging the actual calculation. So analyzing that calculation in the premature execution setting is missing the point, although helpful after we fix this, with the Postponed Filters. _Only then_ the finer points of this algorithm's analysis can be applied - namely, of avoiding testing primes divisibility altogether. And _if_ a fast cheap primality test were to have existed, the filtering versions would win over, because they progressively cull the input sequence so there would be no double hits as we have when merging the multiples (whether from lists or inside the PQ). > the multiples of p with 2*p, you have > > sum [bound `div` p - 1 | p <- takeWhile (<= sqrt bound) primes] > > crossings-out, that is Theta(bound*log (log bound)). If you eliminate > multiples of some small primes a priori (wheel), you can reduce the constant > factor significantly, but the complexity remains the same (you drop a few > terms from the front of the sum and multiply the remaining terms with > phi(n)/n, where n is the product of the excluded primes). > > If you start crossing out at p^2, the number is > > sum [bound `div` p - (p-1) | p <- takeWhile (<= sqrt bound) primes]. > > The difference is basically sum (takeWhile (<= sqrt bound) primes), which I > stupidly - I don't remember how - believed to cancel out the main term. > It doesn't, it's O(bound/log bound), so the complexity is the same. > > Now if you take a stream of numbers from which you remove composites, having > a priority queue of multiples of primes, things are a little different. > If you start crossing out at 2*p, when you are looking at n, you have more > multiples in your PQ than if you start crossing out at p^2 (about pi(n/2) > vs. pi(sqrt n)), so updating the PQ will be more expensive. But updating the > PQ is O(log size), I believe, and log pi(n) is O(log pi(sqrt n)), so I think > it shouldn't change the complexity here either. I think this would have > complexity O(bound*log bound*log (log bound)). There are two questions here - where to start crossing off numbers, and when. If you'd start at 2*p maybe the overall complexity would remain the same but it'll add enormous overhead with all those duplicate multiples. No, the question is not where to start, but when. PQ might hide the problem until the memory blows up. Anything that we add that won't have any chance of contributing to the final result, is added for nothing and only drives the total cost up needlessly. > > > I was under impression that the first shows O(n^2) approx., and the second > > one O(n^1.5) (for n primes produced). > > In Turner/postponed filters, things are really different. Actually, Ms. > O'Neill is right, it is a different algorithm. In the above, we match each what _is_ different is divisibility testing vs composites removal, which follows from her in-depth analysis although is never quite formulated in such words in her article. But nothing matters until the premature starting up is eliminated, and that key observation is missing for the article either - worse, it is brushed off with the casual remark that it is "a pleasing but minor optimization". Which remark, as you show here, is true in the imperative, mutable-storage setting, but is made in an article abut functional code, in regard to the functional code of Turner's sieve. So the key understanding is overlooked. Her article even adds the primes into the PQ prematurely itself, as soon as the prime is discovered (she fixes that in her ZIP package). With the PQ keeping these prematurely added elements deep inside its guts, the problem might not even manifest itself immediately, but the memory blow-up would eventually hit the wall (having the PQ contain all the preceding primes, instead of just those below the square root of a limit - all the entries above the square root not contributing to the calculation at all). And what we're after here is the insight anyway. Skipping steps of natural development does not contribute to garnering an insight. Most prominent problem with Turner's /code/ _specification_, is the premature start ups, and divisibility testing of primes (as Melissa O'Neill's analysis shows). Fix one, and you get Postponed Filters (which should really be used as a basis reference point for all the rest). Fix the other - and you've got the Euler's sieve: primes = 2: 3: sieve (tail primes) [5,7..] where sieve (p:ps) xs = h ++ sieve ps [t `minus` tail [p*p, p*p+2*p..]] where (h,~(_:t)) = span (< p*p) xs Clear, succinct, and plenty efficient for an introductory textbook functional lazy code, of the same order of magnitude performance as PQ code on odds only. Now comparing the PQ performance against _that_ would only be fare, and IMO would only add to its value - it is faster, has better asymptotics, and is greatly amenable to the wheel optimization right away. > prime only with its multiples (plus the next composite in the PQ version). > In Turner's algorithm, we match each prime with all smaller primes (and each > composite with all primes <= its smallest prime factor, but that's less work > than the primes). That gives indeed a complexity of O(pi(bound)^2). > > In the postponed filters, we match each prime p with all primes <= sqrt p > (again, the composites contribute less). I think that gives a complexity of > O(pi(bound)^1.5*log (log bound)) or O(n^1.5*log (log n)) for n primes > produced. Empirically, it was always _below_ 1.5, and above 1.4 , and PQ/merged multiples removal around 1.25..1.17 . > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From kinch1967 at me.com Sat Jan 2 09:33:02 2010 From: kinch1967 at me.com (Peter Green) Date: Sat Jan 2 09:06:17 2010 Subject: [Haskell-cafe] Space Efficiency When Sorting a List of Many Lists In-Reply-To: <7ca3f0160912310238t7bdefdd4xeac221d792ac03bc@mail.gmail.com> References: <7ca3f0160912310238t7bdefdd4xeac221d792ac03bc@mail.gmail.com> Message-ID: <90427C13-F6A7-48E1-B169-35942CA81636@me.com> On 31/12/2009, at 6:38 PM, Luke Palmer wrote: > On Wed, Dec 30, 2009 at 9:39 PM, Peter Green wrote: >> I can guess that there might be be less laziness and more >> instantiation when >> sorting is introduced, > > Yes, by a lot. Sorting requires keeping the entire list in memory. > And Haskell lists, unfortunately, are not that cheap in terms of space > usage (I think [Int] uses 3 words per element). > >> but my questions are: >> (1) Am I doing anything terribly stupid/naive here? >> (2) If so, what can I do to improve space efficiency? >> >> TIA! >> >> >> import Data.List (sort) >> import Data.List.Split (splitOn) >> >> -- Cartesian Product over a List of Lists >> -- cp [[1,2],[3],[4,5,6]] --> >> [[1,3,4],[1,3,5],[1,3,6],[2,3,4],[2,3,5],[2,3,6]] >> cp :: [[a]] -> [[a]] >> cp [] = [[]] >> cp (xs:xss) = [y:ys | y <- xs, ys <- cp xss] > > This cartesian product varies in its tail faster than its head, so > every head gets its own unique tail. If you reverse the order of the > bindings so that it varies in its head faster, then tails are shared. > If my quick and dirty reasoning is correct, it improves the space > usage by a factor of the number of sublists. > > cp' [] = [[]] > cp' (xs:xss) = [y:ys | ys <- cp' xss, y <- xs] > > But if you're serious, you can probably do better than just generating > them all and passing them to sort. I get the impression that there is > some structure here that can be taken advantage of. > >> >> -- fromCSV ["8+12,11,7+13,10", "1+2+3,1+9,3+6,4"] --> >> -- [[[8,12],[11],[7,13],[10]],[[1,2,3],[1,9],[3,6],[4]]] >> fromCSV :: [String] -> [[[Int]]] >> fromCSV = map parseOneLine >> where parseOneLine = map parseGroup . splitOn "," >> where parseGroup = map read . splitOn "+" >> >> -- explode [[[1,2],[3],[4,5,6]], [[1, 2], [14,15], [16]]] --> >> [[1,3,4],[1,3,5], >> -- [1,3,6],[2,3,4],[2,3,5],[2,3,6],[1,14,16],[1,15,16],[2,14,16], >> [2,15,16]] >> explode :: [[[a]]] -> [[a]] >> explode = concatMap cp >> >> -- toCSV [[8,11,7,10,12],[8,11,7,10,12],[8,11,7,10,12]] --> >> -- ["8,11,7,10,12","8,11,7,10,12","8,11,7,10,12"] >> toCSV :: (Show a) => [[a]] -> [String] >> toCSV = map $ tail . init . show >> --toCSV = map (intercalate "," . map show) >> >> main = interact (unlines . toCSV . sort . explode . fromCSV . lines) Thank you everyone for the very helpful suggestions so far! I think I should re-state the problem and provide more background info. In answer to the poster who suggested using a Trie, there *is* a real world application for what I'm attempting to do. I'll also hint at that below: I have text files containing 'compressed lists' Compressed lists look like this: 8+12,11,7+13,10 1+2+3,1+9,3+6,4 . . Sublists are comma-delimited, and sublist elements are separated by '+' character. Sublists contain integers in the range 1..20. I parse these to look like so: [[[8,12],[11],[7,13],[10]], [[1,2,3],[1,9],[3,6],[4]], . . ] I need to explode these and produce a lex-sorted list of exploded lists: [[1,1,3,4],[1,1,6,4],[1,9,3,4],[1,9,6,4],[2,1,3,4],[2,1,6,4],[2,9,3,4], [2,9,6,4],[3,1,3,4],[3,1,6,4],[3,9,3,4],[3,9,6,4], [8,11,7,10],[8,11,13,10],[12,11,7,10],[12,11,13,10]] I then output this data as comma-delimited lists: 1,1,3,4 1,1,6,4 . . 12,11,13,10 It is a property of the underlying problem 'structure' that none of these comma-delimited lists in the exploded data is repeated. i.e. we can never see two instances of (say) 1,1,3,4. { Begin Aside on Why I Would Want to do Such a Silly Thing: 'Compressed lists' are in fact compressed wager combinations for multi- leg exotic horse racing events. 'Exploded lists' are the single wager combinations covered by the grouped combinations. Why use compressed combinations? Well, it's a lot easier to submit 5,000 compressed tickets (whether physically or electronically) than 1M single tickets for the individual combinations we have somehow managed to represent by the 5,000 compressed tickets. However, single combinations are the currency of the realm. These are the underlying wagers and compression is merely a convenience/ necessity to enable single wagers to be placed. It's not uncommon to generate large numbers of single combinations: Imagine 6 races with 15 runners in each race, and a wager requiring one to select first place getters in all 6 legs. The number of potential outcomes is 15^6 = 11,390,625. One might decide (somehow) that it makes sense in a positive expectation way to wager (say) 500K of these potential outcomes. Getting from theoretically desirable single combinations to optimally compressed wagers is actually NP-Complete and another story for another day. Suffice it to say that one might use some nasty hacks and heuristics to arrive at compressed wagers - but in the process doing violence to one's precise coverage of the theoretically desirable single combinations. That's one reason why I need to recover (by 'exploding') the *actual* wagered single combinations from the compressed/ wagers. I need to explode these compressed wagers back to single combinations because, I need to (eventually) do set comparisons on collections of single combinations. i.e. given File A and File B of compressed wagers, I need to be able to answer questions like: (1) How many single combinations are common to File A and File B (2) How many single combinations in File A are missing from File B . . etc. i.e a few of the common set comparison operations. And the dumbest, quickest and dirtiest and most idiot-proof way of doing this as a baseline approach before I start using maps, tries, etc... is to explode Files A and B into lex sorted single combinations order and then use diff -y with judicious grepping for '>' and <'' End Aside } I'm probably going to go with an external sort for starters to keep memory usage down. For most use-cases, I can get away with my current in-memory sort - just have to beware edge cases. However, later on, I'm keen to do everything with set theoretic operations and avoid writing large files of single combinations to disk. So, I guess the things I'd like to get a feel for are: (1) Is it realistic to expect to do in-memory set comparisons on sets with ~1M elements where each element is a (however-encoded) list of (say) 6 integers? I mean realistic in terms of execution time and space usage, of course. (2) What would be a good space-efficient encoding for these single combinations? I know that there will never be more than 8 integers in a combination, and none of these values will be < 1 or > 20. So perhaps I should map them to ByteString library Word8 strings? Presumably sorting a big list of ByteStrings is going to be faster than sorting a big list of lists of int? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100102/bf5ca8e2/attachment.html From daniel.is.fischer at web.de Sat Jan 2 23:08:45 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sat Jan 2 22:43:28 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: Message-ID: <201001030508.46357.daniel.is.fischer@web.de> Am Samstag 02 Januar 2010 14:13:29 schrieb Will Ness: > Daniel Fischer web.de> writes: > > Am Mittwoch 30 Dezember 2009 20:46:57 schrieb Will Ness: > > > Daniel Fischer web.de> writes: > > > > Am Dienstag 29 Dezember 2009 20:16:59 schrieb Daniel Fischer: > > > > > > especially the claim that going by primes squares > > > > > > is "a pleasing but minor optimization", > > > > > > > > > > Which it is not. It is a major optimisation. It reduces the > > > > > algorithmic complexity *and* reduces the constant factors > > > > > significantly. > > > > > > > > D'oh! Thinko while computing sum (takeWhile (<= n) primes) without > > > > paper. It doesn't change the complexity, and the constant factors are > > > > reduced far less than I thought. > > > > > > I do not understand. Turner's sieve is > > > > > > primes = sieve [2..] > > > where > > > sieve (p:xs) = p : sieve [x | x<-xs, x `mod` p /= 0] > > > > > > and the Postponed Filters is > > > > > > primes = 2: 3: sieve (tail primes) [5,7..] > > > where > > > sieve (p:ps) xs = h ++ sieve ps [x | x<-t, x `rem` p /= 0] > > > where (h,~(_:t)) = span (< p*p) xs > > > > > > Are you saying they both exhibit same complexity? > > > > No. They don't. > > But if you're looking at an imperative (mutable array) sieve (that's > > simpler to analyse because you don't have to take the book-keeping costs > > of your priority queue, heap or whatever into account), if you start > > crossing out > > The key question then, is _*WHEN*_ and not _*WHAT*_. As is clearly > demonstrated by the case of Turner/Postponed filters, the work that is done > (of crossing numbers off) is the same Crossing off is only part of the work. Most of the work is checking whether to cross off the number in this round. And Turner does a lot more of that than the postponed filters. > - _when_ it is actually done - but > Turner's starts out so _prematurely_ that it is busy doing nothing most of > the time. It's not doing nothing. It's just doing a lot of superfluous work. It is _achieveing_ nothing most of the time, though. Take 7919, the thousandth prime. The postponed filters decide to keep it when fitering out the multiples of 89, the twenty-fourth prime. Turner also divides it by all 975 primes in between. That is a lot of real but futile work. > Thus its function call overhead costs pile up enormously, > overstaging the actual calculation. It's not only the function calls. Division is expensive, too. > > So analyzing that calculation in the premature execution setting is missing > the point, although helpful after we fix this, with the Postponed Filters. > _Only then_ the finer points of this algorithm's analysis can be applied - > namely, of avoiding testing primes divisibility altogether. And _if_ a fast > cheap primality test were to have existed, the filtering versions would win Sorry, I can't follow. What's the point of a primality test here? Every number whose multiples we want to remove is prime, what's left to test? > over, because they progressively cull the input sequence so there would be > no double hits as we have when merging the multiples (whether from lists or > inside the PQ). But there's a lot of list constructuion and deconstruction necessary for the Euler sieve. That may be more work than the multiple hits cause. > > > the multiples of p with 2*p, you have > > > > sum [bound `div` p - 1 | p <- takeWhile (<= sqrt bound) primes] > > > > crossings-out, that is Theta(bound*log (log bound)). If you eliminate > > multiples of some small primes a priori (wheel), you can reduce the > > constant factor significantly, but the complexity remains the same (you > > drop a few terms from the front of the sum and multiply the remaining > > terms with phi(n)/n, where n is the product of the excluded primes). > > > > If you start crossing out at p^2, the number is > > > > sum [bound `div` p - (p-1) | p <- takeWhile (<= sqrt bound) primes]. > > > > The difference is basically sum (takeWhile (<= sqrt bound) primes), which > > I stupidly - I don't remember how - believed to cancel out the main term. > > It doesn't, it's O(bound/log bound), so the complexity is the same. > > > > Now if you take a stream of numbers from which you remove composites, > > having a priority queue of multiples of primes, things are a little > > different. If you start crossing out at 2*p, when you are looking at n, > > you have more multiples in your PQ than if you start crossing out at p^2 > > (about pi(n/2) vs. pi(sqrt n)), so updating the PQ will be more > > expensive. But updating the PQ is O(log size), I believe, and log pi(n) > > is O(log pi(sqrt n)), so I think it shouldn't change the complexity here > > either. I think this would have complexity O(bound*log bound*log (log > > bound)). > > There are two questions here - where to start crossing off numbers, and > when. If you'd start at 2*p maybe the overall complexity would remain the > same but it'll add enormous overhead with all those duplicate multiples. The additional duplicate multiples aren't the problem. Sure, the numbers having a prime divisor larger than the square root would be crossed off one additional time, but that isn't so much per se. The additional crossings off are O(bound), so they don't harm the time complexity. But they can have effects which multiply the running time by a large constant. > No, the question is not where to start, but when. PQ might hide the problem > until the memory blows up. Anything that we add that won't have any chance > of contributing to the final result, is added for nothing and only drives > the total cost up needlessly. Well, if you start crossing off at p^2 and feed your PQ from a separate prime generator, the memory blow-up is far away. E.g., when the main sieve is at 10^12, the PQ contains less than 80000 multiples. No space problem in sight. At 10^14, the PQ's size is still less than 700000. That's noticeable, but there's still plenty of space. If, on the other hand, you start crossung off at 2*p, when the main sieve is at 10^7, the size of the PQ is > 650000, at 10^8, the size is more than 5.5 million. That starts to become a memory problem rather soon. > > > > I was under impression that the first shows O(n^2) approx., and the > > > second one O(n^1.5) (for n primes produced). > > > > In Turner/postponed filters, things are really different. Actually, Ms. > > O'Neill is right, it is a different algorithm. In the above, we match > > each > > what _is_ different is divisibility testing vs composites removal, which > follows from her in-depth analysis although is never quite formulated in > such words in her article. But nothing matters until the premature starting > up is eliminated, and that key observation is missing for the article > either - worse, it is brushed off with the casual remark that it is "a > pleasing but minor optimization". Which remark, as you show here, is true > in the imperative, mutable-storage setting, but is made in an article abut > functional code, in regard to the functional code of Turner's sieve. I think that remark was meant to apply to composite removal, not Turner's sieve. But even then, the 'minor' isn't adequate considering her PQ approach where, although it doesn't change time complexity (in theory), it changes space complexity - and that may affect running time drastically. Probably she was thinking of the typical array sieve when she made that remark. > So the key understanding is overlooked. > > Her article even adds the primes into the PQ prematurely itself, as soon as > the prime is discovered (she fixes that in her ZIP package). With the PQ > keeping these prematurely added elements deep inside its guts, the problem > might not even manifest itself immediately, but the memory blow-up would > eventually hit the wall (having the PQ contain all the preceding primes, > instead of just those below the square root of a limit - all the entries > above the square root not contributing to the calculation at all). > > And what we're after here is the insight anyway. Skipping steps of natural > development does not contribute to garnering an insight. Most prominent > problem with Turner's /code/ _specification_, is the premature start ups, > and divisibility testing of primes (as Melissa O'Neill's analysis shows). > Fix one, and you get Postponed Filters (which should really be used as a > basis reference point for all the rest). Fix the other - and you've got the > Euler's sieve: > > primes = 2: 3: sieve (tail primes) [5,7..] > where > sieve (p:ps) xs = h ++ sieve ps [t `minus` tail [p*p, p*p+2*p..]] > where (h,~(_:t)) = span (< p*p) xs > > Clear, succinct, and plenty efficient for an introductory textbook > functional lazy code, of the same order of magnitude performance as PQ code > on odds only. > > Now comparing the PQ performance against _that_ would only be fare, and IMO > would only add to its value - it is faster, has better asymptotics, and is > greatly amenable to the wheel optimization right away. > > > prime only with its multiples (plus the next composite in the PQ > > version). In Turner's algorithm, we match each prime with all smaller > > primes (and each composite with all primes <= its smallest prime factor, > > but that's less work than the primes). That gives indeed a complexity of > > O(pi(bound)^2). > > > > In the postponed filters, we match each prime p with all primes <= sqrt p > > (again, the composites contribute less). I think that gives a complexity > > of O(pi(bound)^1.5*log (log bound)) or O(n^1.5*log (log n)) for n primes > > produced. > > Empirically, it was always _below_ 1.5, and above 1.4 , and PQ/merged > multiples removal around 1.25..1.17 . I should really stop doing those calculations in my head, it seems I'm getting too old for that. Doing it properly, on paper, the cost for identifying p_k is pi(sqrt p_k) [trial division by all primes less than sqrt p_k]. p_k is approximately k*log k, so pi(sqrt p_k) is approximately (sqrt $ k* log k)/log (sqrt $ k*log k) ~ 2*sqrt (k/log k). Summing that, the cost for identifying the first n primes is Theta(n^1.5/log n). Using a feeder, i.e. primes = 2:3.sieve feederprimes [5, 7 .. ], where feederprimes are generated as above, to reduce memory pressure and GC impact, that fits pretty well with my measurements of the time to find p_k for several k between 500,000 and 20,000,000. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100102/0654e4d2/attachment-0001.html From brandon.m.simmons at gmail.com Sat Jan 2 23:29:12 2010 From: brandon.m.simmons at gmail.com (jberryman) Date: Sat Jan 2 23:02:17 2010 Subject: [Haskell-cafe] Why can't we make an instance declaration on a type synonym? Message-ID: <303b11b2-337b-4115-86ea-dfee96f329c2@3g2000vbp.googlegroups.com> This may be a dumb question, but why can we not declare a Monad instance of a type synonym? This question came to me while working with the State monad recently and feeling that the requirement that we wrap our functions in the State constructor is a bit... kludgy. Why can't the State monad be defined this way?: > type State s a = \s -> (a , s) > > instance Monad (State s) where > return a = \s -> (a, s) > m >>= k = \s -> let > (a, s') = m s > in k a s' It seems like Haskell's type system could understand the above, but I'm interested in hearing the technical reason which I'm sure exists for why we can't do this. Thanks for any clues, Brandon Simmons http://coder.bsimmons.name/blog/ From jason.dusek at gmail.com Sat Jan 2 23:37:31 2010 From: jason.dusek at gmail.com (Jason Dusek) Date: Sat Jan 2 23:10:35 2010 Subject: [Haskell-cafe] Why can't we make an instance declaration on a type synonym? In-Reply-To: <303b11b2-337b-4115-86ea-dfee96f329c2@3g2000vbp.googlegroups.com> References: <303b11b2-337b-4115-86ea-dfee96f329c2@3g2000vbp.googlegroups.com> Message-ID: <42784f261001022037m47675ce0ue36628272258e805@mail.gmail.com> Well, you can, with: -XTypeSynonymInstances though I'm not sure it addresses your specific need. -- Jason Dusek From daniel.is.fischer at web.de Sun Jan 3 00:18:34 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sat Jan 2 23:53:13 2010 Subject: [Haskell-cafe] Why can't we make an instance declaration on a type synonym? In-Reply-To: <42784f261001022037m47675ce0ue36628272258e805@mail.gmail.com> References: <303b11b2-337b-4115-86ea-dfee96f329c2@3g2000vbp.googlegroups.com> <42784f261001022037m47675ce0ue36628272258e805@mail.gmail.com> Message-ID: <201001030618.34348.daniel.is.fischer@web.de> Am Sonntag 03 Januar 2010 05:37:31 schrieb Jason Dusek: > Well, you can, with: > > -XTypeSynonymInstances > > though I'm not sure it addresses your specific need. Doesn't help him here, he would need instance Monad (State s) where ... but that would be a partially applied type synonym. He would also need type level lambdas, type State s = /\ a -> (s -> (a,s)) But type level lambdas and partially applied type synonyms make type inference undecidable if I remember correctly (if it wasn't that, they'd have other dire consequences). -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100102/28ce28c8/attachment.html From Andrejs.Sisojevs at nextmail.ru Sun Jan 3 02:13:04 2010 From: Andrejs.Sisojevs at nextmail.ru (Andrey Sisoyev) Date: Sun Jan 3 01:46:09 2010 Subject: [Haskell-cafe] ANNOUNCE: PriorityChansConverger-0.1 Message-ID: <26999572.post@talk.nabble.com> Hello, cafe! Didn't find it in HackageDB, so made it. http://hackage.haskell.org/package/PriorityChansConverger Category: concurency Converges multiple channels into one. When user reads from the PCC, the choice is made - from which channel to read. System selects a nonempty channel, whose (CurrentPriority, StartPriority) tuple is max. The side effect of the channel selection is it's CurrentPriority decrease by one, if it's value becomes less than one, then the CurrentPriority is set to StartPriority. Based on STM.TChan, extended with capacity control. Version wrapped into is also available. The realization probably isn't very fast and isn't good at memory economy, since it uses fresh high level primitive - STM. It wasn't intended to be used with millions of channels. But it's max throughput comparing to the ordinary Chan throughput is to be estimated (will do it in some future version). Regards, Andrey Sisoyev -- View this message in context: http://old.nabble.com/ANNOUNCE%3A-PriorityChansConverger-0.1-tp26999572p26999572.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From ivan.miljenovic at gmail.com Sun Jan 3 02:22:54 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Sun Jan 3 01:56:05 2010 Subject: [Haskell-cafe] Why can't we make an instance declaration on a type synonym? In-Reply-To: <303b11b2-337b-4115-86ea-dfee96f329c2@3g2000vbp.googlegroups.com> (jberryman's message of "Sat, 2 Jan 2010 20:29:12 -0800 (PST)") References: <303b11b2-337b-4115-86ea-dfee96f329c2@3g2000vbp.googlegroups.com> Message-ID: <87tyv3fy9d.fsf@gmail.com> jberryman writes: > This may be a dumb question, but why can we not declare a Monad > instance of a type synonym? This question came to me while working > with the State monad recently and feeling that the requirement that we > wrap our functions in the State constructor is a bit... kludgy. > Because type defines an _alias_. If you define "type Foo = Maybe Int", then everywhere you have a "Foo" the compiler should be able to replace it with "Maybe Int". As such, if you have a custom instance on your type synonym (say a custom Show instance for Foo), then which instance will the compiler use? -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From jason.dusek at gmail.com Sun Jan 3 03:15:08 2010 From: jason.dusek at gmail.com (Jason Dusek) Date: Sun Jan 3 02:48:12 2010 Subject: [Haskell-cafe] Atom's `__global_clock' and `__scheduling_clock'. Message-ID: <42784f261001030015l262716fat54813954c1b80d59@mail.gmail.com> I am mystified by the relationship between Atom's `__global_clock' and the `scheduling_clock'. For example, here is some generated code: /* Includes omitted. */ static uint64_t __global_clock = 0; /* Subroutine declarations omitted. */ void main(void) { { static uint8_t __scheduling_clock = 0; if (__scheduling_clock == 0) { __r0(); /* main.set_up_pins */ __r1(); /* main.set_up_timer */ __scheduling_clock = 0; } else { __scheduling_clock = __scheduling_clock - 1; } } __global_clock = __global_clock + 1; } Looking at code generated by an older version of Atom, it seems like there used not be separate "global" and "scheduling" clocks: /* From http://code.sw17ch.com/blog/atom/blink_atom.c */ void blink_atom(void) { if (__clock % 1 == 0) { r0(); /* blink_atom.decrement */ } if (__clock % 2 == 0) { r1(); /* blink_atom.reset */ } if (__clock % 2 == 1) { r2(); /* blink_atom.flip */ } __clock = __clock + 1; } I would like to know how the `__global_clock' influences execution in the present system. -- Jason Dusek From will_n48 at yahoo.com Sun Jan 3 03:54:37 2010 From: will_n48 at yahoo.com (Will Ness) Date: Sun Jan 3 03:28:08 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001030508.46357.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > > Am Samstag 02 Januar 2010 14:13:29 schrieb Will Ness: > > Daniel Fischer web.de> writes: > > > Am Mittwoch 30 Dezember 2009 20:46:57 schrieb Will Ness: > > > > Daniel Fischer web.de> writes: > > > > > Am Dienstag 29 Dezember 2009 20:16:59 schrieb Daniel Fischer: > > > > > > > especially the claim that going by primes squares > > > > > > > is "a pleasing but minor optimization", > > > > > > > > > > > > Which it is not. It is a major optimisation. It reduces the > > > > > > algorithmic complexity *and* reduces the constant factors > > > > > > significantly. > > > > > > > > > > D'oh! Thinko while computing sum (takeWhile (<= n) primes) without > > > > > paper. It doesn't change the complexity, and the constant factors are > > > > > reduced far less than I thought. > > > > > > > > I do not understand. Turner's sieve is > > > > > > > > primes = sieve [2..] > > > > where > > > > sieve (p:xs) = p : sieve [x | x<-xs, x `mod` p /= 0] > > > > > > > > and the Postponed Filters is > > > > > > > > primes = 2: 3: sieve (tail primes) [5,7..] > > > > where > > > > sieve (p:ps) xs = h ++ sieve ps [x | x<-t, x `rem` p /= 0] > > > > where (h,~(_:t)) = span (< p*p) xs > > > > > > > > Are you saying they both exhibit same complexity? > > > > > > No. They don't. > > > But if you're looking at an imperative (mutable array) sieve (that's > > > simpler to analyse because you don't have to take the book-keeping costs > > > of your priority queue, heap or whatever into account), if you start > > > crossing out > > > > The key question then, is _*WHEN*_ and not _*WHAT*_. As is clearly > > demonstrated by the case of Turner/Postponed filters, the work that is done > > (of crossing numbers off) is the same > > Crossing off is only part of the work. Most of the work is checking whether > to cross off the number in this round. And Turner does a lot more of that > than the postponed filters. Exactly the point I tried to make. :) > > - _when_ it is actually done - but > > Turner's starts out so _prematurely_ that it is busy doing nothing most of > > the time. > > It's not doing nothing. It's just doing a lot of superfluous work. It is > _achieveing_ nothing most of the time, though. again, yes. :) > Take 7919, the thousandth prime. The postponed filters decide to keep it when > fitering out the multiples of 89, the twenty-fourth prime. Turner also > divides it by all 975 primes in between. That is a lot of real but futile > work. yes. > > Thus its function call overhead costs pile up enormously, > > overstaging the actual calculation. > > It's not only the function calls. Division is expensive, too. yes, that's what I meant - the cost of calling all the fuctions that - we know in advance will - have nothing to do eventually. > > So analyzing that calculation in the premature execution setting is missing > > the point, although helpful after we fix this, with the Postponed Filters. > > _Only then_ the finer points of this algorithm's analysis can be applied - > > namely, of avoiding testing primes divisibility altogether. And _if_ a fast > > cheap primality test were to have existed, the filtering versions would win > > Sorry, I can't follow. What's the point of a primality test here? Every > number whose multiples we want to remove is prime, what's left to test? sorry for being obstruse. I meant in a filtering sieve (i.e. postponed filters) vs the multiples removing sieves, if only the cheap primality test have existed (by some _magic_) which _could_ be run on _every_ numer (unlike the costly divisiility test), than the filtering sieves would win. Hypothetically. > > over, because they progressively cull the input sequence so there would be > > no double hits as we have when merging the multiples (whether from lists or > > inside the PQ). > > But there's a lot of list constructuion and deconstruction necessary for the > Euler sieve. yes. Unless, of course, s smart compiler recognizes there's only one consumer for the values each multiples-list is producing, and keeps it stripped down to a generator function, and its current value. I keep thinkig a smart compiler could eliminate all these "span" calls and replace them with just some pointers manipulating... > That may be more work than the multiple hits cause. so that too would make filters win; only _if_ the cheap primality test existed!.. > > > > > the multiples of p with 2*p, you have > > > ... > > > > There are two questions here - where to start crossing off numbers, and > > when. If you'd start at 2*p maybe the overall complexity would remain the > > same but it'll add enormous overhead with all those duplicate multiples. > > The additional duplicate multiples aren't the problem. Sure, the numbers > having a prime divisor larger than the square root would be crossed off one > additional time, but that isn't so much per se. The additional crossings off > are O(bound), so they don't harm the time complexity. But they can have > effects which multiply the running time by a large constant. yes, exactly what I wanted to say. :) > > No, the question is not where to start, but when. PQ might hide the problem > > until the memory blows up. Anything that we add that won't have any chance > > of contributing to the final result, is added for nothing and only drives > > the total cost up needlessly. > > Well, if you start crossing off at p^2 and feed your PQ from a separate prime > generator, the memory blow-up is far away. E.g., when the main sieve is at > 10^12, the PQ contains less than 80000 multiples. No space problem in sight. > At 10^14, the PQ's size is still less than 700000. That's noticeable, but > there's still plenty of space. again, what I mean is, not _where_ I start crossing them off in a PQ, but _when_. The article's code starts crossing them off _at_ p^2 - by adding p^2+2p into the PQ - _as_ _soon_ as p itself is reached. It won't surface until p^2 will be considered for a prime; it'll lay dormant deep inside the queue's guts. When reaching 7919, the thousand (i.e. pi(7919) ) entries will hang out inside the PQ - instead of just 24. A memory blowup. (this is of course fixed in Melissa's ZIP package). Of course due to the nature of PQ it might actually not hurt the performance for a while, depending on partcular PQ implementation. Complexity _and_ constant factors. > If, on the other hand, you start crossung off at 2*p, when the main sieve is > at 10^7, the size of the PQ is > 650000, at 10^8, the size is more than 5.5 > million. That starts to become a memory problem rather soon. here you don't have a choice or when to add it - you have to add it at p itself - so the problem is clear. But even when you cross at p^2, the question remains, of when you add the p^2 entry into the PQ. That was my point. Postponed Filters code makes this clear, and thus hard to err on. Unfortunately, it wasn't present the article. > > > > > > I was under impression that the first shows O(n^2) approx., and the > > > > second one O(n^1.5) (for n primes produced). > > > > > > In Turner/postponed filters, things are really different. Actually, Ms. > > > O'Neill is right, it is a different algorithm. In the above, we match > > > each > > > > what _is_ different is divisibility testing vs composites removal, which > > follows from her in-depth analysis although is never quite formulated in > > such words in her article. But nothing matters until the premature starting > > up is eliminated, and that key observation is missing for the article > > either - worse, it is brushed off with the casual remark that it is "a > > pleasing but minor optimization". Which remark, as you show here, is true > > in the imperative, mutable-storage setting, but is made in an article abut > > functional code, in regard to the functional code of Turner's sieve. > > I think that remark was meant to apply to composite removal, not Turner's > sieve. It is right there on page 2, right when the Turner's sieve is presented and discussed. The only explanation that I see is that she thought of it in regards to the imperative code, just as her analysis concentrates only on calculation aspects of the imperative code itself. > But even then, the 'minor' isn't adequate considering her PQ approach where, > although it doesn't change time complexity (in theory), it changes space > complexity - and that may affect running time drastically. Probably she was > thinking of the typical array sieve when she made that remark. In short, that remark was not referring to what it seemingly refers to, in the article, and as such was very confusing. It was a big STOP sign on the way to Postponed Filters - Euler's - Bird's merged multiples - tree-merging (with wheel) road of little steps, and used as a justification for her to make a big leap across the chasm towards the PQ code. So to speak. :) > > So the key understanding is overlooked. > > > > And what we're after here is the insight anyway. Skipping steps of natural > > development does not contribute to garnering an insight. .. and that is of course a matter of personal preference. A genius is perfectly capable of making big leaps across chasms. Heck they might even be able to fly :) > > > In the postponed filters, we match each prime p with all primes <= sqrt p > > > (again, the composites contribute less). I think that gives a complexity > > > of O(pi(bound)^1.5*log (log bound)) or O(n^1.5*log (log n)) for n primes > > > produced. > > > > Empirically, it was always _below_ 1.5, and above 1.4 , and PQ/merged > > multiples removal around 1.25..1.17 . > > I should really stop doing those calculations in my head, it seems I'm > getting too old for that. Doing it properly, on paper, the cost for > identifying p_k is pi(sqrt p_k) [trial division by all primes less than > sqrt p_k]. > p_k is approximately k*log k, so pi(sqrt p_k) is approximately > (sqrt $ k* log k)/log (sqrt $ k*log k) ~ 2*sqrt (k/log k). > Summing that, the cost for identifying the first n primes is > Theta(n^1.5/log n). that would correspond to what I've seen much better. > Using a feeder, i.e. primes = 2:3.sieve feederprimes [5, 7 .. ], where > feederprimes are generated as above, to reduce memory pressure and GC > impact, that fits pretty well with my measurements of the time to find > p_k for several k between 500,000 and 20,000,000. The quesion of a memory blowup with the treefolding merge still remains. For some reason using its second copy for a feeder doesn't reduce the memory (as reported by standalone compiled program, GHCi reported values are useless) - it causes it to increase twice..... > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From conor at strictlypositive.org Sun Jan 3 04:37:05 2010 From: conor at strictlypositive.org (Conor McBride) Date: Sun Jan 3 04:08:09 2010 Subject: [Haskell-cafe] Why can't we make an instance declaration on a type synonym? In-Reply-To: <201001030618.34348.daniel.is.fischer@web.de> References: <303b11b2-337b-4115-86ea-dfee96f329c2@3g2000vbp.googlegroups.com> <42784f261001022037m47675ce0ue36628272258e805@mail.gmail.com> <201001030618.34348.daniel.is.fischer@web.de> Message-ID: On 3 Jan 2010, at 05:18, Daniel Fischer wrote: > Am Sonntag 03 Januar 2010 05:37:31 schrieb Jason Dusek: > > Well, you can, with: > > > > -XTypeSynonymInstances > > > > though I'm not sure it addresses your specific need. > Doesn't help him here, he would need > instance Monad (State s) where ... > but that would be a partially applied type synonym. He would also > need type level lambdas, > type State s = /\ a -> (s -> (a,s)) > But type level lambdas and partially applied type synonyms make type > inference undecidable if I remember correctly (if it wasn't that, > they'd have other dire consequences). Type inference is undecidable already. It's still extremely useful, cut with just enough type annotation and checking to resolve ambiguities. That creates a bunch of trade-offs to negotiate and a design space to explore. Lots of dependent type systems have type-level lambda (that is, they have lambda), undecidable type inference, decidable type checking, and substantial (but inadequately rationalised) facilities for suppressing and recovering boring details. Nobody's campaigning to kick type-level lambda out of Agda. Adding type-level lambda to Haskell would amount to admitting the awful truth: application is not injective. When you write a do-program of type t, you need to solve a constraint m x = t for m and x, to figure out which monad to plumb in. Pretending application is injective makes this easy, at the cost of requiring lots of wrapper- types. Type-level lambda makes this constraint highly ambiguous: Maybe Int is also (\ x -> x) (Maybe Int), the type of a computation in the identity monad. To cope, we'd need a new way to be signal such decompositions. Worth thinking about, perhaps, but certainly a Big Deal. Type-level lambda is not inherently disastrous. It's just a poor fit with Haskell's current design. Cheers Conor > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From bulat.ziganshin at gmail.com Sun Jan 3 05:41:20 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Jan 3 05:18:15 2010 Subject: [Haskell-cafe] ANNOUNCE: PriorityChansConverger-0.1 In-Reply-To: <26999572.post@talk.nabble.com> References: <26999572.post@talk.nabble.com> Message-ID: <581750329.20100103134120@gmail.com> Hello Andrey, Sunday, January 3, 2010, 10:13:04 AM, you wrote: > http://hackage.haskell.org/package/PriorityChansConverger thanks, it will be useful. one thing missing in announcement - whether it works in IO or STM monad? -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From will_n48 at yahoo.com Sun Jan 3 07:16:25 2010 From: will_n48 at yahoo.com (Will Ness) Date: Sun Jan 3 06:49:57 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001030508.46357.daniel.is.fischer@web.de> Message-ID: Will Ness yahoo.com> writes: > > ... It was a big STOP sign on the way to > Postponed Filters - Euler's - Bird's merged multiples - tree-merging (with > wheel) road of little steps, and used as a justification for her to make a > big leap across the chasm towards the PQ code. correction: "across the /supposed/ chasm". There is no chasm. There is a nice straight freeway, with rest stops and gas stations, and exits to local roads going across the county in every which way. :) > .. and that is of course a matter of personal preference. A genius is > perfectly capable of making big leaps across chasms. Heck they might even > be able to fly :) From jdkoeck at gmail.com Sun Jan 3 09:28:53 2010 From: jdkoeck at gmail.com (Jean-Denis Koeck) Date: Sun Jan 3 09:01:58 2010 Subject: [Haskell-cafe] Compiling a shared library on MacOS X Message-ID: <96255e01001030628r7375a866p22cc1b6c3802b6a5@mail.gmail.com> Hello, I'm using the following cabal file to build a shared library with ghc: Build-Type: Simple Executable libmylibrary.dll If os(windows) CPP-Options: -DWIN32 Extensions: ForeignFunctionInterface Build-Depends: ... Main-Is: libmylibrary.hs Ghc-Options: -W --make -no-hs-main -optl-shared -optl-s -O2 The resulting library is called from a C++ graphical user interface (using Qt), which worked great so far on Windows and Linux. However, the compilation fails on MacOS X: Undefined symbols: "_ZCMain_main_closure", referenced from: _ZCMain_main_closure$non_lazy_ptr in libHSrts.a(Main.o) "___stginit_ZCMain", referenced from: ___stginit_ZCMain$non_lazy_ptr in libHSrts.a(Main.o) ld: symbol(s) not found collect2: ld returned 1 exit status I don't know much about shared libraries, even less about them on MacOS X :( Any idea ? Jean-Denis Koeck -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100103/2798b38e/attachment.html From tomahawkins at gmail.com Sun Jan 3 11:06:42 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Sun Jan 3 10:39:45 2010 Subject: [Haskell-cafe] Atom's `__global_clock' and `__scheduling_clock'. In-Reply-To: <42784f261001030015l262716fat54813954c1b80d59@mail.gmail.com> References: <42784f261001030015l262716fat54813954c1b80d59@mail.gmail.com> Message-ID: <594c1e831001030806w3a1e43bcy73270b75c26da8e9@mail.gmail.com> On Sun, Jan 3, 2010 at 9:15 AM, Jason Dusek wrote: > > ?I would like to know how the `__global_clock' influences > ?execution in the present system. As you observed, __global_clock is no longer used for rule scheduling. It is only there to provide a time reference. BTW, __global_clock is accessed via 'clock'. From jdkoeck at gmail.com Sun Jan 3 11:33:33 2010 From: jdkoeck at gmail.com (Jean-Denis Koeck) Date: Sun Jan 3 11:06:38 2010 Subject: [Haskell-cafe] Re: Compiling a shared library on MacOS X In-Reply-To: <96255e01001030628r7375a866p22cc1b6c3802b6a5@mail.gmail.com> References: <96255e01001030628r7375a866p22cc1b6c3802b6a5@mail.gmail.com> Message-ID: <96255e01001030833w45971db6o318975eabc7b2300@mail.gmail.com> According to the manual, I have to use the -shared flag to compile a library. But I get the following error: link: GHC not built to link this way: LinkDynLib Guess I have to recompile ghc ! 2010/1/3 Jean-Denis Koeck > Hello, > I'm using the following cabal file to build a shared library with ghc: > > Build-Type: Simple > Executable libmylibrary.dll > If os(windows) > CPP-Options: -DWIN32 > Extensions: ForeignFunctionInterface > Build-Depends: ... > Main-Is: libmylibrary.hs > Ghc-Options: -W --make -no-hs-main -optl-shared -optl-s -O2 > > The resulting library is called from a C++ graphical user interface (using > Qt), > which worked great so far on Windows and Linux. > > However, the compilation fails on MacOS X: > > Undefined symbols: > "_ZCMain_main_closure", referenced from: > _ZCMain_main_closure$non_lazy_ptr in libHSrts.a(Main.o) > "___stginit_ZCMain", referenced from: > ___stginit_ZCMain$non_lazy_ptr in libHSrts.a(Main.o) > ld: symbol(s) not found > collect2: ld returned 1 exit status > > I don't know much about shared libraries, even less about them on MacOS X > :( > Any idea ? > > Jean-Denis Koeck > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100103/ffeb2e4b/attachment.html From uzytkownik2 at gmail.com Sun Jan 3 11:34:52 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Sun Jan 3 11:09:12 2010 Subject: [Haskell-cafe] [Very long] (CHP?) Compressing, MD5 and big files Message-ID: <1262536492.5358.47.camel@picard> I have following problem: I'd like to operate on big files so I'd prefere to operate on 'stream' instead of whole file at a time to avoid keeping too much in memory. I need to calculate MD5 and compress file. I tried to use something like that but I'm afraid that I'd need to patch zlib package as it results in deadlock: > {-# LANGUAGE GADTs #-} > import Codec.Compression.GZip > import Control.Applicative > import Control.Concurrent.CHP > import qualified Control.Concurrent.CHP.Common as CHP > import Control.Concurrent.CHP.Enroll > import Control.Concurrent.CHP.Utils > import Control.Monad.State.Strict > import Data.Digest.Pure.MD5 > import Data.Maybe > import qualified Data.ByteString.Char8 as BS > import qualified Data.ByteString.Lazy.Char8 as LBS > import qualified Data.ByteString.Lazy.Internal as LBS > import System.Environment > import System.IO > import System.IO.Unsafe > > > calculateMD5 :: (ReadableChannel r, > Poisonable (r (Maybe BS.ByteString)), > WriteableChannel w, > Poisonable (w MD5Digest)) > => r (Maybe BS.ByteString) > -> w MD5Digest > -> CHP () > calculateMD5 in_ out = evalStateT (forever loop) md5InitialContext > `onPoisonRethrow` (poison in_ >> poison out) > where loop = liftCHP (readChannel in_) >>= > calc' > calc' Nothing = gets md5Finalize >>= > liftCHP . > writeChannel out >> > put md5InitialContext > calc' (Just b) = modify (flip md5Update > $ LBS.fromChunks [b]) Calculate MD5 hash of input stream. Nothing indicates EOF. > unsafeInterleaveCHP :: CHP a -> CHP a > unsafeInterleaveCHP = fromJust <.> liftIO <=< > unsafeInterleaveIO <.> embedCHP Helper function. It is suppose to move the execution in time - just as unsafeInterleaveIO. I belive that the main problem lives here. Especially that Maybe.fromJust: Nothing is the error. > chan2List :: (ReadableChannel r, Poisonable (r a)) > => r a -> CHP [a] > chan2List in_ = unsafeInterleaveCHP ((liftM2 (:) (readChannel in_) > (chan2List in_)) > `onPoisonTrap` return []) Changes channel to lazy read list. > chanMaybe2List :: (ReadableChannel r, > Poisonable (r (Maybe a))) > => r (Maybe a) > -> CHP [[a]] > chanMaybe2List in_ = splitByMaybe <$> chan2List > where splitByMaybe [] = [] > splitByMaybe (Nothing:xs) = > []:splitByMaybe xs > splitByMaybe (Just v :[]) = [[v]] > splitByMaybe (Just v :xs) = > let (y:ys) = splitByMaybe xs > in (v:y):ys Reads lazyly from channel o list of list > compressCHP :: (ReadableChannel r, > Poisonable (r (Maybe BS.ByteString)), > WriteableChannel w, > Poisonable (w (Maybe BS.ByteString))) > => r (Maybe BS.ByteString) > -> w (Maybe BS.ByteString) > -> CHP () > compressCHP in_ out = toOut >>= mapM_ sendBS > where in_' :: CHP [LBS.ByteString] > in_' = fmap LBS.fromChunks <$> > chanMaybe2List in_ > toOut :: CHP [LBS.ByteString] > toOut = fmap compress <$> in_' > sendBS :: LBS.ByteString -> CHP () > sendBS LBS.Empty = writeChannel out > Nothing > sendBS (LBS.Chunk c r) = writeChannel out > (Just c) > >> sendBS r Compress process > readFromFile :: (ReadableChannel r, > Poisonable (r String), > WriteableChannel w, > Poisonable (w (Maybe BS.ByteString))) > => r String > -> w (Maybe BS.ByteString) > -> CHP () > readFromFile file data_ = > forever (do path <- readChannel file > hnd <- liftIO $ openFile path ReadMode > let copy = liftIO (BS.hGet hnd LBS.defaultChunkSize) >>= > writeChannel data_ . Just > copy `onPoisonRethrow` liftIO (hClose hnd) > writeChannel data_ Nothing > liftIO $ hClose hnd) > `onPoisonRethrow` (poison file >> poison data_) Process reading from file > writeToFile :: (ReadableChannel r, > Poisonable (r String), > ReadableChannel r', > Poisonable (r' (Maybe BS.ByteString))) > => r String > -> r' (Maybe BS.ByteString) > -> CHP () > writeToFile file data_ = > forever (do path <- readChannel file > hnd <- liftIO $ openFile path WriteMode > let writeUntilNothing = readChannel data_ >>= > writeUntilNothing' > writeUntilNothing' Nothing = return () > writeUntilNothing' (Just v) = liftIO (BS.hPutStr > hnd v) >> > writeUntilNothing > writeUntilNothing `onPoisonFinally` liftIO (hClose hnd)) > `onPoisonRethrow` (poison file >> poison data_) Process writing to file > getFiles :: (WriteableChannel w, Poisonable (w String)) > => w String -> CHP () > getFiles out = mapM_ (writeChannel out) ["test1", "test2"] >> > poison (out) Sample files. Each contains "Test1\n" > pipeline1 :: CHP () > pipeline1 = do md5sum <- oneToOneChannel' $ chanLabel "MD5" > runParallel_ [(getFiles ->|^ > ("File", readFromFile) ->|^ > ("Data", calculateMD5)) > (writer md5sum), > forever $ readChannel (reader md5sum) >>= > liftIO . print] First pipeline. Output: fa029a7f2a3ca5a03fe682d3b77c7f0d fa029a7f2a3ca5a03fe682d3b77c7f0d < File."test1", Data.Just "Test1\n", Data.Nothing, MD5.fa029a7f2a3ca5a03fe682d3b77c7f0d, File."test2", Data.Just "Test1\n", Data.Nothing, MD5.fa029a7f2a3ca5a03fe682d3b77c7f0d > > pipeline2 :: CHP () > pipeline2 = enrolling $ do > file <- oneToManyChannel' $ chanLabel "File" > fileMD5 <- oneToOneChannel' $ chanLabel "File MD5" > data_ <- oneToOneChannel' $ chanLabel "Data" > md5 <- oneToOneChannel' $ chanLabel "MD5" > md5BS <- oneToOneChannel' $ chanLabel "MD5 ByteString" > fileMD5' <- Enroll (reader file) > fileData <- Enroll (reader file) > liftCHP $ runParallel_ [getFiles (writer file), > (forever $ readChannel fileMD5' >>= > writeChannel (writer fileMD5) . > (++".md5")) > `onPoisonRethrow` > (poison fileMD5' >> > poison (writer fileMD5)), > readFromFile fileData (writer data_), > calculateMD5 (reader data_) (writer md5), > (forever $ do v <- readChannel (reader md5) > let v' = Just $ BS.pack $ show v > writeChannel (writer md5BS) v' > writeChannel (writer md5BS) > Nothing) > `onPoisonRethrow` > (poison (writer md5BS) >> > poison (reader md5)), > writeToFile (reader fileMD5) (reader md5BS)] Correct pipeline (testing EnrollingT): < _b4, File MD5."test1.md5", Data.Just "Test1\n", Data.Nothing, MD5.fa029a7f2a3ca5a03fe682d3b77c7f0d, _b4, MD5 ByteString.Just "fa029a7f2a3ca5a03fe682d3b77c7f0d", Data.Just "Test1\n", Data.Nothing, MD5 ByteString.Nothing, MD5.fa029a7f2a3ca5a03fe682d3b77c7f0d, File MD5."test2.md5", MD5 ByteString.Just "fa029a7f2a3ca5a03fe682d3b77c7f0d", MD5 ByteString.Nothing > % cat test1.md5 fa029a7f2a3ca5a03fe682d3b77c7f0d% > pipeline3 :: CHP () > pipeline3 = enrolling $ do > file <- oneToManyChannel' $ chanLabel "File" > fileGZ <- oneToOneChannel' $ chanLabel "File GZ" > data_ <- oneToManyChannel' $ chanLabel "Data" > compressed <- oneToManyChannel' $ chanLabel "Data Compressed" > md5 <- oneToOneChannel' $ chanLabel "MD5" > md5Compressed <- oneToOneChannel' $ chanLabel "MD5 Compressed" > fileGZ' <- Enroll (reader file) > fileData <- Enroll (reader file) > dataMD5 <- Enroll (reader data_) > dataCompress <- Enroll (reader data_) > compressedFile <- Enroll (reader compressed) > compressedMD5 <- Enroll (reader compressed) > liftCHP $ runParallel_ [getFiles (writer file), > (forever $ readChannel fileGZ' >>= > writeChannel (writer fileGZ) . > (++".gz")) > `onPoisonRethrow` > (poison fileGZ' >> poison (writer fileGZ)), > readFromFile fileData (writer data_), > calculateMD5 dataMD5 (writer md5), > compressCHP dataCompress > (writer compressed), > writeToFile (reader fileGZ) compressedFile, > calculateMD5 compressedMD5 > (writer md5Compressed), > forever $ readChannel dataMD5 >>= > liftIO . print >> > readChannel compressedMD5 >>= > liftIO . print] Problems: (CHP) Thread terminated with: thread blocked indefinitely in an STM transaction < _b3, _b4, File GZ."test1.gz" > > onPoisonFinally :: CHP a -> CHP () -> CHP a > onPoisonFinally m b = (m `onPoisonRethrow` b) <* b > Utility function (used for closing handles) > (<.>) :: Functor f => (b -> c) -> (a -> f b) -> a -> f c > f <.> g = fmap f . g <.> is for <$> as . to $. > instance MonadCHP m => MonadCHP (StateT s m) where > liftCHP = lift . liftCHP Missing instance for strict monad > (->|^) :: Show b > => (Chanout b -> CHP ()) -> (String, Chanin b -> c -> CHP ()) > -> (c -> CHP ()) > (->|^) p (l, q) x = do c <- oneToOneChannel' $ chanLabel l > runParallel_ [p (writer c), q (reader c) x] 'Missing' helper function > data EnrollingT a where > Lift :: CHP a -> EnrollingT a > Enroll :: (Enrollable b z) => b z -> EnrollingT (Enrolled b z) > > enrolling :: EnrollingT a -> CHP a > enrolling (Lift v) = v > enrolling (Enroll b) = enroll b return > > instance Monad EnrollingT where > (Lift m) >>= f = Lift $ m >>= enrolling . f > (Enroll b) >>= f = Lift $ enroll b (enrolling . f) > return = Lift . return > instance MonadIO EnrollingT where > liftIO = Lift . liftIO > instance MonadCHP EnrollingT where > liftCHP = Lift Helper monad for enrolling (I know T should stand for transforming but then I realize problems). Thanks in advance From Andrejs.Sisojevs at nextmail.ru Sun Jan 3 12:17:51 2010 From: Andrejs.Sisojevs at nextmail.ru (Andrey Sisoyev) Date: Sun Jan 3 11:50:55 2010 Subject: [Haskell-cafe] ANNOUNCE: PriorityChansConverger-0.1 In-Reply-To: <581750329.20100103134120@gmail.com> References: <26999572.post@talk.nabble.com> <581750329.20100103134120@gmail.com> Message-ID: <27002956.post@talk.nabble.com> > thanks, it will be useful. That's pleasant to hear, Bulat. =) > whether it works in IO or STM monad? I made both versions. PriorityChansConvergerSTM is made in STM in one module. And in another module STM version is wrapped into IO. The IO version is a buildup on top of STM version, and it has additional properties: (1) It (PCC in IO monad) uses MVar locks to secure system from "waste work". I thought, that transactions don't look too lightweight, so few bottleneck would be great... The negative side of this, is that asynchronous exception may cause loss of locks. Probably in a future version I will try to introduce more advanced locking mechanics, which will be secure facing async-excpts... (2) STM version has interruptableRead and interruptableWrite operations, whose interruption is controlled with parameter (STM Bool). IO version also has these operations + interruptables, that are controlled by parameter (Chan a, a -> Bool). I'm no sure if interruptables for IO monad are made optimal - they do spawn additional temporary threads, but I didn't see any better way to make this interruption. Regards, Andrey -- View this message in context: http://old.nabble.com/ANNOUNCE%3A-PriorityChansConverger-0.1-tp26999572p27002956.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From larrye2000 at gmail.com Sun Jan 3 12:46:30 2010 From: larrye2000 at gmail.com (Larry E.) Date: Sun Jan 3 12:19:33 2010 Subject: [Haskell-cafe] setting seed for random numbers Message-ID: <173d9fb01001030946i8c15351u834015a791510513@mail.gmail.com> I want to set a random seed for a random number generator. I tried this: getSeed = do time <- getClockTime return (ctPicosec (toUTCTime time)) seed <- getSeed randList minval maxval = randomRs (minval,maxval) (mkStdGen seed) But I get the error: parse error on input `<-' which refers to "seed<-getSeed". Using "seed<-getSeed" from the ghci command line works. Why doesn't it work in a script? THe second problem is the seed is of type Integer but mkStdGen wants an Int. How can I get an Int from an Integer? I tried mod to get the seed to within range for an int but the result is still of type Integer how can I coerce Integer to Int when I know result will fit? Thanks From bulat.ziganshin at gmail.com Sun Jan 3 13:24:20 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Jan 3 12:57:41 2010 Subject: [Haskell-cafe] setting seed for random numbers In-Reply-To: <173d9fb01001030946i8c15351u834015a791510513@mail.gmail.com> References: <173d9fb01001030946i8c15351u834015a791510513@mail.gmail.com> Message-ID: <1215458823.20100103212420@gmail.com> Hello Larry, Sunday, January 3, 2010, 8:46:30 PM, you wrote: > Using "seed<-getSeed" from the ghci command line works. Why doesn't > it work in a > script? because it's a feature of ghci command prompt, not haskell language. use smth like this: randList minval maxval = do seed <- getSeed return$ randomRs (minval,maxval) (mkStdGen seed) of course, it will make randList non-pure function that may return different results on different calls but that that you mean, no? ;) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From daniel.is.fischer at web.de Sun Jan 3 13:29:52 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sun Jan 3 13:04:31 2010 Subject: [Haskell-cafe] setting seed for random numbers In-Reply-To: <173d9fb01001030946i8c15351u834015a791510513@mail.gmail.com> References: <173d9fb01001030946i8c15351u834015a791510513@mail.gmail.com> Message-ID: <201001031929.52386.daniel.is.fischer@web.de> Am Sonntag 03 Januar 2010 18:46:30 schrieb Larry E.: > I want to set a random seed for a random number generator. I tried > this: > getSeed = do > time <- getClockTime > return (ctPicosec (toUTCTime time)) > > seed <- getSeed > randList minval maxval = randomRs (minval,maxval) (mkStdGen seed) > > > But I get the error: parse error on input `<-' which refers to > "seed<-getSeed". > > Using "seed<-getSeed" from the ghci command line works. Why doesn't > it work in a > script? The value <- action syntax is only available in do-blocks. At the ghci prompt, you are in an IO do-block, so it's available there. In a script (source file), you are not. I suggest making the generator an argument of randList, getting the seed and from that the generator in main and pass the generator to the pure functions doing the work. Also, it might be good to use the random monad, available from http://hackage.haskell.org/package/MonadRandom > > THe second problem is the seed is of type Integer but mkStdGen wants > an Int. How can I get an Int from an Integer? I tried mod to get the > seed to within range for an int but the result is still of type > Integer how can I coerce Integer to Int when I know result will fit? fromInteger > > Thanks -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100103/9de40230/attachment.html From allbery at ece.cmu.edu Sun Jan 3 18:08:17 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Sun Jan 3 17:41:22 2010 Subject: [Haskell-cafe] Compiling a shared library on MacOS X In-Reply-To: <96255e01001030628r7375a866p22cc1b6c3802b6a5@mail.gmail.com> References: <96255e01001030628r7375a866p22cc1b6c3802b6a5@mail.gmail.com> Message-ID: <8A6E62AF-3CEF-465B-845C-946234B2B96B@ece.cmu.edu> Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100103/baae1744/PGP.bin From ivan.miljenovic at gmail.com Sun Jan 3 18:36:40 2010 From: ivan.miljenovic at gmail.com (Ivan Miljenovic) Date: Sun Jan 3 18:09:46 2010 Subject: [Haskell-cafe] Compiling a shared library on MacOS X In-Reply-To: <96255e01001030628r7375a866p22cc1b6c3802b6a5@mail.gmail.com> References: <96255e01001030628r7375a866p22cc1b6c3802b6a5@mail.gmail.com> Message-ID: If I recall correctly, dynamic linking/shared library support is not yet available for OSX, as the Industrial Haskell Group does not have any knowledge of OSX (but is willing to pay someone who does to do the work). 2010/1/4 Jean-Denis Koeck : > Hello, > I'm using the following cabal file to build a shared library with ghc: > > Build-Type:??? ??????? Simple > Executable libmylibrary.dll > ? If os(windows) > ??? CPP-Options:??????? -DWIN32 > ? Extensions:?????????? ForeignFunctionInterface > ? Build-Depends:??????? ... > ? Main-Is:????????????? libmylibrary.hs > ? Ghc-Options:????????? -W --make -no-hs-main -optl-shared -optl-s -O2 > > The resulting library is called from a C++ graphical user interface (using > Qt), > which worked great so far on Windows and Linux. > > However, the compilation fails on MacOS X: > > Undefined symbols: > ? "_ZCMain_main_closure", referenced from: > ????? _ZCMain_main_closure$non_lazy_ptr in libHSrts.a(Main.o) > ? "___stginit_ZCMain", referenced from: > ????? ___stginit_ZCMain$non_lazy_ptr in libHSrts.a(Main.o) > ld: symbol(s) not found > collect2: ld returned 1 exit status > > I don't know much about shared libraries, even less about them on MacOS X :( > Any idea ? > > Jean-Denis Koeck > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com Joan Crawford - "I, Joan Crawford, I believe in the dollar. Everything I earn, I spend." - http://www.brainyquote.com/quotes/authors/j/joan_crawford.html From daniel.is.fischer at web.de Sun Jan 3 19:29:22 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sun Jan 3 19:04:02 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001030508.46357.daniel.is.fischer@web.de> Message-ID: <201001040129.22689.daniel.is.fischer@web.de> Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: V13Primes.hs Type: text/x-haskell Size: 3621 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100103/620e267e/V13Primes.bin From patrick.leboutillier at gmail.com Sun Jan 3 20:17:06 2010 From: patrick.leboutillier at gmail.com (Patrick LeBoutillier) Date: Sun Jan 3 19:50:11 2010 Subject: [Haskell-cafe] Interpreting profiling results In-Reply-To: References: Message-ID: Hi, This question didn't get any replies on the beginners list, I thought I'd try it here... I've written (and improved using other solutions I've found on the net) a simple sudoku solver which I'm trying to profile. Here is the code: import Array import List (transpose, nub, (\\)) import Data.List data Sudoku = Sudoku { unit :: Int, cells :: Array (Int, Int) Int, holes :: [(Int, Int)] } cell :: Sudoku -> (Int, Int) -> Int cell s i = (cells s) ! i instance Read Sudoku where ?readsPrec _ s = [(Sudoku unit cells holes, "")] ? ?where unit = length . words . head . lines $ s ? ? ? ? ?cells = listArray ((1, 1), (unit, unit)) (map read . words $ s) ? ? ? ? ?holes = [ c | c <- indices cells, (cells ! c) == 0] instance Show Sudoku where ?show s = unlines [unwords [show $ cell s (x,y) | x <- [1 .. unit s]] | y <- [1 .. unit s]] genNums :: Sudoku -> (Int, Int) -> [Int] genNums s c@(i,j) = ([1 .. u] \\) . nub $ used ?where ? ?used = (row s u i j) ++ (col s u i j) ++ (square s sq u i j) ? ?u = unit s ? ?sq = truncate . sqrt . fromIntegral $ u row s u i j = [cell s (i, y) | y <- [1 .. u]] col s u i j = [cell s (x, j) | x <- [1 .. u]] square s sq u i j = [cell s (x, y) | y <- [1 .. u], x <- [1 .. u], f x i, f y j] ?where f a b = div (a-1) sq == div (b-1) sq solve :: Sudoku -> [Sudoku] solve s = ?case holes s of ? ?[] -> [s] ? ?(h:hs) -> do ? ? ?n <- genNums s h ? ? ?let s' = Sudoku (unit s) ((cells s) // [(h, n)]) hs ? ? ?solve s' main = print . head . solve . read =<< getContents When I compile as such: $ ghc -O2 --make Sudoku.hs -prof -auto-all -caf-all -fforce-recomp and run it on the following puzzle: 0 2 3 4 3 4 1 0 2 1 4 0 0 3 2 1 I get the following profiling report: ? ? ? ?Fri Jan ?1 10:34 2010 Time and Allocation Profiling Report ?(Final) ? ? ? ? ? Sudoku +RTS -p -RTS ? ? ? ?total time ?= ? ? ? ?0.00 secs ? (0 ticks @ 20 ms) ? ? ? ?total alloc = ? ? 165,728 bytes ?(excludes profiling overheads) COST CENTRE ? ? ? ? ? ? ? ? ? ?MODULE ? ? ? ? ? ? ? %time %alloc CAF ? ? ? ? ? ? ? ? ? ? ? ? ? ?GHC.Handle ? ? ? ? ? ? 0.0 ? 10.7 CAF ? ? ? ? ? ? ? ? ? ? ? ? ? ?Text.Read.Lex ? ? ? ? ?0.0 ? ?2.1 CAF ? ? ? ? ? ? ? ? ? ? ? ? ? ?GHC.Read ? ? ? ? ? ? ? 0.0 ? ?1.2 square ? ? ? ? ? ? ? ? ? ? ? ? Main ? ? ? ? ? ? ? ? ? 0.0 ? ?2.8 solve ? ? ? ? ? ? ? ? ? ? ? ? ?Main ? ? ? ? ? ? ? ? ? 0.0 ? ?1.3 show_aVx ? ? ? ? ? ? ? ? ? ? ? Main ? ? ? ? ? ? ? ? ? 0.0 ? ?3.7 readsPrec_aYF ? ? ? ? ? ? ? ? ?Main ? ? ? ? ? ? ? ? ? 0.0 ? 60.6 main ? ? ? ? ? ? ? ? ? ? ? ? ? Main ? ? ? ? ? ? ? ? ? 0.0 ? ?9.6 genNums ? ? ? ? ? ? ? ? ? ? ? ?Main ? ? ? ? ? ? ? ? ? 0.0 ? ?5.0 cell ? ? ? ? ? ? ? ? ? ? ? ? ? Main ? ? ? ? ? ? ? ? ? 0.0 ? ?1.2 ? ? ? ? ? ? ? ? ? ? ? ?individual ? ?inherited COST CENTRE ? ? ? ? ? ? ?MODULE ? ? ? no. ? ?entries ?%time %alloc ? %time %alloc MAIN ? ? ? ? ? ? ? ? ? ? MAIN ? ? ? ? 1 ? ? ? ? ? 0 ? 0.0 ? ?0.3 ? ? 0.0 ?100.0 ?main ? ? ? ? ? ? ? ? ? ?Main ? ? ? 186 ? ? ? ? ? 1 ? 0.0 ? ?9.6 ? ? 0.0 ? 85.6 ?show_aVx ? ? ? ? ? ? ? Main ? ? ? 196 ? ? ? ? ? 2 ? 0.0 ? ?3.7 ? ? 0.0 ? ?3.7 ? cell ? ? ? ? ? ? ? ? ?Main ? ? ? 197 ? ? ? ? ?16 ? 0.0 ? ?0.0 ? ? 0.0 ? ?0.0 ?solve ? ? ? ? ? ? ? ? ?Main ? ? ? 188 ? ? ? ? ? 5 ? 0.0 ? ?1.3 ? ? 0.0 ? 11.8 ? genNums ? ? ? ? ? ? ? Main ? ? ? 189 ? ? ? ? ? 8 ? 0.0 ? ?5.0 ? ? 0.0 ? 10.4 ? ?square ? ? ? ? ? ? ? Main ? ? ? 194 ? ? ? ? ?88 ? 0.0 ? ?2.8 ? ? 0.0 ? ?3.2 ? ? cell ? ? ? ? ? ? ? ?Main ? ? ? 195 ? ? ? ? ?16 ? 0.0 ? ?0.4 ? ? 0.0 ? ?0.4 ? ?col ? ? ? ? ? ? ? ? ?Main ? ? ? 192 ? ? ? ? ? 4 ? 0.0 ? ?0.7 ? ? 0.0 ? ?1.1 ? ? cell ? ? ? ? ? ? ? ?Main ? ? ? 193 ? ? ? ? ?16 ? 0.0 ? ?0.4 ? ? 0.0 ? ?0.4 ? ?row ? ? ? ? ? ? ? ? ?Main ? ? ? 190 ? ? ? ? ? 4 ? 0.0 ? ?0.7 ? ? 0.0 ? ?1.1 ? ? cell ? ? ? ? ? ? ? ?Main ? ? ? 191 ? ? ? ? ?16 ? 0.0 ? ?0.4 ? ? 0.0 ? ?0.4 ?readsPrec_aYF ? ? ? ? ?Main ? ? ? 187 ? ? ? ? ? 3 ? 0.0 ? 60.6 ? ? 0.0 ? 60.6 ?CAF ? ? ? ? ? ? ? ? ? ? GHC.Read ? ? ? 151 ? ? ? ? ? 1 ? 0.0 ? ?1.2 ? ? 0.0 ? ?1.2 ?CAF ? ? ? ? ? ? ? ? ? ? Text.Read.Lex ? ? ? 144 ? ? ? ? ? 8 ? 0.0 ? ?2.1 ? ? 0.0 ? ?2.1 ?CAF ? ? ? ? ? ? ? ? ? ? GHC.Handle ? ? ? 128 ? ? ? ? ? 4 ? 0.0 ? 10.7 ? ? 0.0 ? 10.7 ?CAF ? ? ? ? ? ? ? ? ? ? GHC.Conc ? ? ? 127 ? ? ? ? ? 1 ? 0.0 ? ?0.0 ? ? 0.0 ? ?0.0 Does the column 'entries' represent the number of times the function was called? If so, I don't understand how the 'square' function could be called 88 times when it's caller is only called 8 times. Same thing with 'genNums' (called 8 times, and solve called 5 times) What am I missing here? Patrick -- ===================== Patrick LeBoutillier Rosem?re, Qu?bec, Canada From patc at pessce.net Sun Jan 3 21:30:50 2010 From: patc at pessce.net (Patrick Caldon) Date: Sun Jan 3 21:03:28 2010 Subject: [Haskell-cafe] Template Haskell - substitution in pattern in a lambda Message-ID: <4B4152DA.5000901@pessce.net> I'm trying to write some template haskell which will transform: $(buildCP 0) into \(SimpleM d1 d2 d3) (SimpleM _ _ _) -> (SimpleM d1 d2 d3) $(buildCP 1) into \(SimpleM _ d2 d3) (SimpleM d1 _ _) -> (SimpleM d1 d2 d3) $(buildCP 1) into \(SimpleM d1 _ d3) (SimpleM _ d2 _) -> (SimpleM d1 d2 d3) and so on. Ultimately I want to generalize this to more variables. I can't seem to get anything to substitute for the pattern variables in a lambda. Is there a straightforward way of doing this? Below is what I've been playing with to try to make this work. Thanks, Patrick. --- module THTest where import Language.Haskell.TH import qualified Data.Bits type Policy = Int data Management = SimpleM Policy Policy Policy deriving Show -- Compiles - but no substitution for the "aX" and "bX" variables buildCP :: Int -> ExpQ buildCP k = [|\(SimpleM a1 a2 a3) (SimpleM b1 b2 b3) -> (SimpleM $e1 $e2 $e3) |] where (e1,a1,b1) = bitToExprs 0 k (e2,a2,b2) = bitToExprs 1 k (e3,a3,b3) = bitToExprs 2 k -- Won't compile: buildCP2 :: Int -> ExpQ buildCP2 k = [|\(SimpleM $a1 $a2 $a3) (SimpleM $b1 $b2 $b3) -> (SimpleM $e1 $e2 $e3) |] where (e1,a1,b1) = bitToExprs 0 k (e2,a2,b2) = bitToExprs 1 k (e3,a3,b3) = bitToExprs 2 k cp1 0 = \(SimpleM d1 d2 d3) (SimpleM _ _ _) -> (SimpleM d1 d2 d3) {- -- idea is to use in calls like this: cp0 0 = $(buildCP 0) -- should be \(SimpleM d1 d2 d3) (SimpleM _ _ _) -> (SimpleM d1 d2 d3) cp0 1 = $(buildCP 1) -} -- There is also a template haskell [p| ... |] syntax, but not yet implemented ... bitToExprs:: Int -> Int -> (ExpQ,PatQ,PatQ) bitToExprs n k = if Data.Bits.testBit (k::Int) (n::Int) then (e,v1,v2) else (e,v2,v1) where v1 = return WildP v2 = return $ VarP (mkName name) e = return $ VarE (mkName name) name = "d" ++ (show $ n + 1) {- -- ulitmate goal is something like this with 10ish d variables: -- cp0 0 (SimpleM d1 d2 d3 m1) (SimpleM _ _ _ m2) = (SimpleM d1 d2 d3 (me1 m1 m2)) cp0 1 (SimpleM d1 d2 _ m1) (SimpleM _ _ d3 m2) = (SimpleM d1 d2 d3 (me2 m1 m2)) cp0 2 (SimpleM d1 _ d3 m1) (SimpleM _ d2 _ m2) = (SimpleM d1 d2 d3 (me1 m1 m2)) cp0 3 (SimpleM d1 _ _ m1) (SimpleM _ d2 d3 m2) = (SimpleM d1 d2 d3 (me2 m1 m2)) cp0 4 (SimpleM _ d2 d3 m1) (SimpleM d1 _ _ m2) = (SimpleM d1 d2 d3 (me1 m1 m2)) cp0 5 (SimpleM _ d2 _ m1) (SimpleM d1 _ d3 m2) = (SimpleM d1 d2 d3 (me2 m1 m2)) cp0 6 (SimpleM _ _ d3 m1) (SimpleM d1 d2 _ m2) = (SimpleM d1 d2 d3 (me1 m1 m2)) cp0 7 (SimpleM _ _ _ m1) (SimpleM d1 d2 d3 m2) = (SimpleM d1 d2 d3 (me2 m1 m2)) cp0 _ _ _ = (trace "cp0 error" undefined) -} From aslatter at gmail.com Sun Jan 3 21:41:13 2010 From: aslatter at gmail.com (Antoine Latter) Date: Sun Jan 3 21:14:16 2010 Subject: [Haskell-cafe] Template Haskell - substitution in pattern in a lambda In-Reply-To: <4B4152DA.5000901@pessce.net> References: <4B4152DA.5000901@pessce.net> Message-ID: <694519c51001031841u5eb4c1bev4396bb65d59acc8b@mail.gmail.com> On Sun, Jan 3, 2010 at 8:30 PM, Patrick Caldon wrote: > > I'm trying to write some template haskell which will transform: > > $(buildCP 0) ?into \(SimpleM d1 d2 d3) (SimpleM _ _ _) -> (SimpleM d1 d2 d3) > $(buildCP 1) ?into \(SimpleM _ d2 d3) (SimpleM d1 _ _) -> (SimpleM d1 d2 d3) > $(buildCP 1) ?into \(SimpleM d1 _ d3) (SimpleM _ d2 _) -> (SimpleM d1 d2 d3) > and so on. > > Ultimately I want to generalize this to more variables. > > I can't seem to get anything to substitute for the pattern variables in a > lambda. ?Is there a straightforward way of doing this? > Hello, It looks like you want to construct expressions with the LamE constructor, which is declared like so: LamE [Pat] Exp For the Pat, you would use eiter VarP or WildP for variable binding patterns or wild-card patterns. Or am I missing something? Antoine From cantthinkthinkpink at gmail.com Sun Jan 3 21:50:07 2010 From: cantthinkthinkpink at gmail.com (Jamie Morgenstern) Date: Sun Jan 3 21:23:11 2010 Subject: [Haskell-cafe] Significant slow-down in parallel code? Message-ID: Hello; I have a piece of code in which I employ the `par` construct to add some implicit parallelism to a theorem prover. However, when running the *same* code with +RTS -N1 +RTS -N5 +RTS -N10 I see a huge slowdown (a factor of 50 with 5 processes and a factor of 100 for 10 on an 8-core machine). Very little time is being spent using the garbage collector. Any suggestions? Thanks, -Jamie -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100103/9f66f86d/attachment.html From patc at pessce.net Sun Jan 3 21:59:18 2010 From: patc at pessce.net (Patrick Caldon) Date: Sun Jan 3 21:31:56 2010 Subject: [Haskell-cafe] Template Haskell - substitution in pattern in a lambda In-Reply-To: <694519c51001031841u5eb4c1bev4396bb65d59acc8b@mail.gmail.com> References: <4B4152DA.5000901@pessce.net> <694519c51001031841u5eb4c1bev4396bb65d59acc8b@mail.gmail.com> Message-ID: <4B415986.5090009@pessce.net> Antoine Latter wrote: > On Sun, Jan 3, 2010 at 8:30 PM, Patrick Caldon wrote: > >> I'm trying to write some template haskell which will transform: >> >> $(buildCP 0) into \(SimpleM d1 d2 d3) (SimpleM _ _ _) -> (SimpleM d1 d2 d3) >> $(buildCP 1) into \(SimpleM _ d2 d3) (SimpleM d1 _ _) -> (SimpleM d1 d2 d3) >> $(buildCP 1) into \(SimpleM d1 _ d3) (SimpleM _ d2 _) -> (SimpleM d1 d2 d3) >> and so on. >> >> Ultimately I want to generalize this to more variables. >> >> I can't seem to get anything to substitute for the pattern variables in a >> lambda. Is there a straightforward way of doing this? >> >> > > Hello, > > It looks like you want to construct expressions with the LamE > constructor, which is declared like so: > > LamE [Pat] Exp > > Thanks - I see how that could work, I'll try it. But really I was wondering if there was something like: buildCP2 :: Int -> ExpQ buildCP2 k = [|\(SimpleM ~a1 ~a2 ~a3) (SimpleM ~b1 ~b2 ~b3) -> (SimpleM $e1 $e2 $e3) |] where (e1,a1,b1) = bitToExprs 0 k (e2,a2,b2) = bitToExprs 1 k (e3,a3,b3) = bitToExprs 2 k bitToExprs:: Int -> Int -> (ExpQ,PatQ,PatQ) Where ~a1 would mean "look for something called a1 returning a pattern, and slot it into the pattern part of the lambda in the appropriate spot". I'm guessing no such syntax exists? Thanks again, Patrick. From dezgeg at gmail.com Sun Jan 3 22:35:33 2010 From: dezgeg at gmail.com (Tuomas Tynkkynen) Date: Sun Jan 3 22:08:37 2010 Subject: [Haskell-cafe] Template Haskell - substitution in pattern in a lambda In-Reply-To: <4B4152DA.5000901@pessce.net> References: <4B4152DA.5000901@pessce.net> Message-ID: 2010/1/4 Patrick Caldon > > I'm trying to write some template haskell which will transform: > > $(buildCP 0) ?into \(SimpleM d1 d2 d3) (SimpleM _ _ _) -> (SimpleM d1 d2 d3) > $(buildCP 1) ?into \(SimpleM _ d2 d3) (SimpleM d1 _ _) -> (SimpleM d1 d2 d3) > $(buildCP 1) ?into \(SimpleM d1 _ d3) (SimpleM _ d2 _) -> (SimpleM d1 d2 d3) > and so on. > > Ultimately I want to generalize this to more variables. > > I can't seem to get anything to substitute for the pattern variables in a lambda. ?Is there a straightforward way of doing this? > > Below is what I've been playing with to try to make this work. > > Thanks, > Patrick. Here's something pretty generic that gets the patterns right: module THTest where import Language.Haskell.TH import Data.List import Control.Monad type Policy = Int data Management = SimpleM Policy Policy Policy ? deriving Show buildCP :: Name -> Int -> Int -> ExpQ buildCP ctor nVars nth = do names <- replicateM nVars $ newName "pat" ??? ??? ??????????? let p1 = replaceAt nth WildP $ map VarP names ??? ??? ??? ??????? p2 = replaceAt nth (VarP $ names!!nth) $ replicate nVars WildP ??? ??? ??? ??? return $ LamE [ConP ctor p1, ConP ctor p2] (ListE $ map VarE names) replaceAt :: Int -> a -> [a] -> [a] replaceAt pos x xs = let (first,_:rest) = splitAt pos xs ??? ??? ??? in first ++ [x] ++ rest -- for example: doFst = $(buildCP 'SimpleM 3 0) doFst (SimpleM 1 2 3) (SimpleM 4 5 6) ==> [4,2,3] (returns a list because it's easier to do. Modifying it to return SimpleM left as an exercise :) From patc at pessce.net Sun Jan 3 23:09:30 2010 From: patc at pessce.net (Patrick Caldon) Date: Sun Jan 3 22:42:08 2010 Subject: [Haskell-cafe] Template Haskell - substitution in pattern in a lambda In-Reply-To: References: <4B4152DA.5000901@pessce.net> Message-ID: <4B4169FA.8040803@pessce.net> Tuomas Tynkkynen wrote: > Here's something pretty generic that gets the patterns right: > Thanks for that - about 2/3rds of the length of my proposed solution! Cheers, Patrick. From bulat.ziganshin at gmail.com Mon Jan 4 03:12:53 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Mon Jan 4 02:46:04 2010 Subject: [Haskell-cafe] Template Haskell - substitution in pattern in a lambda In-Reply-To: <4B415986.5090009@pessce.net> References: <4B4152DA.5000901@pessce.net> <694519c51001031841u5eb4c1bev4396bb65d59acc8b@mail.gmail.com> <4B415986.5090009@pessce.net> Message-ID: <1698783747.20100104111253@gmail.com> Hello Patrick, Monday, January 4, 2010, 5:59:18 AM, you wrote: > I'm guessing no such syntax exists? you are right. look at http://www.haskell.org/bz/th3.htm http://www.haskell.org/bz/thdoc.htm -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From gcross at phys.washington.edu Mon Jan 4 03:48:54 2010 From: gcross at phys.washington.edu (Gregory Crosswhite) Date: Mon Jan 4 03:25:22 2010 Subject: [Haskell-cafe] Template Haskell - substitution in pattern in a lambda In-Reply-To: <1698783747.20100104111253@gmail.com> References: <4B4152DA.5000901@pessce.net> <694519c51001031841u5eb4c1bev4396bb65d59acc8b@mail.gmail.com> <4B415986.5090009@pessce.net> <1698783747.20100104111253@gmail.com> Message-ID: <2CB20FE1-14EF-4712-BF5D-DF5C58A6EBCF@phys.washington.edu> Cool, Burat! Those are the first tutorials I've read on TH that have succeeded in giving me a sense of how I can actually use it! Thanks for writing them up. :-D Cheers, Greg On Jan 4, 2010, at 3:12 AM, Bulat Ziganshin wrote: > Hello Patrick, > > Monday, January 4, 2010, 5:59:18 AM, you wrote: > >> I'm guessing no such syntax exists? > > you are right. look at > http://www.haskell.org/bz/th3.htm > http://www.haskell.org/bz/thdoc.htm > > > -- > Best regards, > Bulat mailto:Bulat.Ziganshin@gmail.com > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From uzytkownik2 at gmail.com Mon Jan 4 04:30:51 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Mon Jan 4 04:04:26 2010 Subject: [Haskell-cafe] Re: [Very long] (CHP?) Compressing, MD5 and big files In-Reply-To: <1262536492.5358.47.camel@picard> References: <1262536492.5358.47.camel@picard> Message-ID: <1262597451.13413.42.camel@picard> On Sun, 2010-01-03 at 17:34 +0100, Maciej Piechotka wrote: > I have following problem: I'd like to operate on big files so I'd > prefere to operate on 'stream' instead of whole file at a time to avoid > keeping too much in memory. I need to calculate MD5 and compress file. > > I tried to use something like that but I'm afraid that I'd need to patch > zlib package as it results in deadlock: > If I add: > pipeline4 = do file <- oneToOneChannel' $ chanLabel "File" > data_ <- oneToOneChannel' $ chanLabel "Data" > compressed <- oneToOneChannel' $ chanLabel "Compressed" > runParallel_ [getFiles (writer file), > readFromFile (reader file) > (writer data_), > compressCHP (reader data_) > (writer compressed), > CHP.consume (reader compressed)] And change compress to(I'm not tested without change but here I omit explicit interleave): > stateM :: Monad m => a -> (a -> m a) -> m b > stateM i f = f i >>= flip stateM f Like forever but with state > chanMaybe2List :: (ReadableChannel r, Poisonable (r (Maybe a)), > WriteableChannel w, Poisonable (w [a])) > => r (Maybe a) > -> w [a] > -> CHP () > chanMaybe2List in_ out = do > chan <- liftIO $ newChan > list <- liftIO ((Just Nothing :) <$> getChanContents chan) > runParallel_ [forever (readChannel in_ >>= > liftIO . writeChan chan . Just) > `onPoisonRethrow` (liftIO (writeChan chan Nothing) >> > poison in_), > forever $ stateM list process] > where process (Nothing :_) = poison out >> throwPoison > process (Just Nothing:Nothing:_) = poison out >> throwPoison > process (Just Nothing:xs) = > let (this, that) = span isJust xs > isJust = maybe False (maybe False (const True)) > this' = map fromJust (map fromJust this) > in writeChannel out (map fromJust $ map fromJust this) >> > process that Writes to output lazy list of all elements in input > compressCHP' :: (ReadableChannel r, Poisonable (r [BS.ByteString]), > WriteableChannel w, Poisonable (w [BS.ByteString])) > => r [BS.ByteString] > -> w [BS.ByteString] > -> CHP () > compressCHP' in_ out = forever (writeChannel out . > LBS.toChunks . compress . > LBS.fromChunks =<< > readChannel in_) > `onPoisonRethrow` (poison in_ >> poison out) Compresses the lists of chunks > toMaybeList :: (ReadableChannel r, Poisonable (r [a]), > WriteableChannel w, Poisonable (w (Maybe a))) > => r [a] > -> w (Maybe a) > -> CHP () > toMaybeList in_ out = forever (readChannel in_ >>= > mapM_ (writeChannel out . Just) >> > writeChannel out Nothing) > `onPoisonRethrow` (poison in_ >> poison out) Converts back to list > compressCHP :: (ReadableChannel r, > Poisonable (r (Maybe BS.ByteString)), > WriteableChannel w, > Poisonable (w (Maybe BS.ByteString))) > => r (Maybe BS.ByteString) > -> w (Maybe BS.ByteString) > -> CHP () > compressCHP = chanMaybe2List |->| compressCHP' |->| toMaybeList Combines all 3 operations. However pipeline3 still results in deadlock: Just "Test1\n" (CHP) Thread terminated with: thread blocked indefinitely in an STM transaction < _b3, _b4, _b4, File GZ."test1.gz", _c5, _b6, _c7, _b3 > Well - at least I know where there is no problem. Regardss From wouter at vectorfabrics.com Mon Jan 4 05:35:40 2010 From: wouter at vectorfabrics.com (Wouter Swierstra) Date: Mon Jan 4 05:08:42 2010 Subject: [Haskell-cafe] Data.Ring -- Pre-announce In-Reply-To: References: Message-ID: <42c6c021001040235y65177485u6cafca3ccba7cc3d@mail.gmail.com> Hi John, > I threw something together fairly quickly and would like some feedback before tossing it on Hackage. > > I'd really appreciate if some one would: > > make sure the code looks goodish (127 lines with full docs) > make sure my tests look saneish A similar structure is used in XMonad where it's called a Stack (which isn't a very good name). There are loads of QuickCheck properties in the XMonad sources you might want to use. Hope this helps, Wouter From will_n48 at yahoo.com Mon Jan 4 07:25:47 2010 From: will_n48 at yahoo.com (Will Ness) Date: Mon Jan 4 06:59:12 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001030508.46357.daniel.is.fischer@web.de> <201001040129.22689.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > > Am Sonntag 03 Januar 2010 09:54:37 schrieb Will Ness: > > > Daniel Fischer web.de> writes: > > > > > But there's a lot of list constructuion and deconstruction necessary for > > > the Euler sieve. > > > > yes. Unless, of course, s smart compiler recognizes there's only one > > consumer for the values each multiples-list is producing, and keeps it > > stripped down to a generator function, and its current value. I keep > > thinkig a smart compiler could eliminate all these "span" calls and replace > > them with just some pointers manipulating... > > > > Of course I'm no smart compiler, but I don't see how it could be even > possible to replace the span calls with pointer manipulation when dealing > with lazily generated (infinite, if we're really mean) lists. Even when > you're dealing only with strict finite lists, it's not trivial to do > efficiently. I keep thinking that storage duplication with span, filter etc. is not really necessary, and can be replaced with some pointer chasing - especially when there's only one consumer present for the generated values. What I mean is thinking of lists in terms of produce/consumer paradigm, as objects supporting the { pull, peek } interface, keeping the generator inside that would produce the next value on 'pull' request and keep it ready for any 'peek's. Euler's sieve is sieve (p:ps) xs = h ++ sieve ps (t `minus` map (p*) [p,p+2..]) where (h,t) = span (< p*p) xs Everything lives only through access, so (sieve (tail primes) [5,7]) would create an object with the generator which has the 'span' logic inlined: sieve ps xs = make producer such that p := pull ps -- alter ps as well (actually pull a value from it) q := p*p peek = x := peek xs if x < q then x else peek (remake self) pull = x := peek xs if x < q then pull xs else pull (remake self) remake = ys := minus xs (intsFromBy q (2*p)) self := sieve ps ys Here the only thing that gets created are the 'minus' nodes which essentially maintain pointers into the two streams that they consume. 'intsFromBy' only has to maintain two integers inside it (currentVal and step) as there's no need for it to maintain any storage for its results, as they are immediately consumed. A persistent list would be represented by a different kind of producer which would be given a storage to operate on, upon creation (as would the top level variable like 'primes'). The real difference here is between those producers whose values will only be consumed once, by one specific consumer, and those which values may be needed more than once, so need really to be maintained in some storage. If not - span, filter, map, whatever - they all are just little modifiers on top of the real producers, which may or may not also have an actual storage maintained by them. > > again, what I mean is, not _where_ I start crossing them off in a PQ, but > > _when_. The article's code starts crossing them off _at_ p^2 - by adding > > p^2+2p into the PQ - _as_ _soon_ as p itself is reached. It won't surface > > until p^2 will be considered for a prime; it'll lay dormant deep inside the > > queue's guts. When reaching 7919, the thousand (i.e. pi(7919) ) entries > > will hang out inside the PQ - instead of just 24. A memory blowup. (this is > > of course fixed in Melissa's ZIP package). Of course due to the nature of > > PQ it might actually not hurt the performance for a while, depending on > > partcular PQ implementation. Complexity _and_ constant factors. > > > > It will start to have an impact pretty soon. Assuming at least one of the > relevant PQ operations to be Theta(log size), each composite between ~400 > and ~400000 (rough estimates) will take something like twice as long to > handle. It will start to hurt really badly only a while later, though, as > a guesstimate, with more than a million primes in the PQ, memory will have > a hard time. Exactly! > > > If, on the other hand, you start crossung off at 2*p, when the main sieve > > > is at 10^7, the size of the PQ is > 650000, at 10^8, the size is more > > > than 5.5 million. That starts to become a memory problem rather soon. > > > > here you don't have a choice or when to add it - you have to add it at p > > itself - so the problem is clear. But even when you cross at p^2, the > > question remains, of when you add the p^2 entry into the PQ. That was my > > point. > > > > Postponed Filters code makes this clear, and thus hard to err on. > > Unfortunately, it wasn't present _in_ the article. > > > I think that remark was meant to apply to composite removal, not Turner's > > > sieve. > > > > It is right there on page 2, right when the Turner's sieve is presented and > > discussed. The only explanation that I see is that she thought of it in > > regards to the imperative code, just as her analysis concentrates only on > > calculation aspects of the imperative code itself. > > > > To be fair, she writes: > > "Let us ?rst describe the original ?by hand? sieve algorithm as practiced by > Eratosthenes. > ... > The starting point of p^2 is a pleasing but minor optimization, which can > be made > because lower multiples will have already been crossed o? when we found > the primes prior to p. > ... (This optimization does not a?ect the time complexity of the sieve, > however, so its absence from the code in Section 1 > *is not our cause for worry*.)" A-HA! But its absense from _*that*_ _*code*_ WAS the *major* cause for worry, as dealing with it worked wonders on its complexity and constant factors. This remark only makes sense in the imperative, mutable-storage setting, as we've already estalished. > So it's in context of the imperative code (although rather numbers on paper > than bits in RAM). > For imperative (be it array or paper), it is indeed minor; for her PQ sieve, > it can be considered minor from a theoretical point of view (doesn't change > time complexity), but practically, anything that changes performance by a > factor of two or more is only 'minor' for hopelessly inadequate algorithms > (whether a computation would take ten or twenty billion years is indeed a > minor difference; one hour or two is a major difference). ++ > However, as you say, the important point is not whether p's multiples get > crossed off starting from 2*p or from p^2, but whether p's multiples get > inserted into the queue *when* you look at p or at p^2. Exactly! Not _where_, but _when_ (in a lifetime of a computational process). And this (I would say, important) observation was missing from the article precisely because of her focusing on the analysis of the _imperative_ algorithm. But if we focus on functional, it is a logical thing to realise, and when implemented shows us the road to the next improvement by a gradual stepwise development. A matter of personal preference. :) > > > ... the cost for > > > identifying p_k is pi(sqrt p_k) [trial division by all primes less than > > > sqrt p_k]. > > > p_k is approximately k*log k, so pi(sqrt p_k) is approximately > > > (sqrt $ k* log k)/log (sqrt $ k*log k) ~ 2*sqrt (k/log k). > > > Summing that, the cost for identifying the first n primes is > > > Theta(n^1.5/log n). > > > > that would correspond to what I've seen much better. > > > > It should. :) > > The quesion of a memory blowup with the treefolding merge still remains. > > For some reason using its second copy for a feeder doesn't reduce the > > memory (as reported by standalone compiled program, GHCi reported values > > are useless) - it causes it to increase twice..... > > > > I have a partial solution. The big problem is that the feeder holds on to > the beginning of comps while the main runner holds on to a later part. > Thus the entire segment between these two points must be in memory. > So have two lists of composites (yeah, you know that, but it didn't > work so far). I did. I duplicated everything. The reported memory was twice bigger. :| > But you have to force the compiler not to share them: enter -fno-cse. > The attached code does that (I've also expanded the wheel), it reduces the > memory requirements much (a small part is due to the larger wheel, a factor > of ~5 due to the non-sharing). > It still uses much more memory than the PQ, and while the PQ's memory > requirements grow very slowly, the tree-fold merge's still grow rather > fast (don't go much beyond the 10,000,000th prime), I'm not sure why. > Great! I will look into the code. Thanks! :) :) > > > > Attachment (V13Primes.hs): text/x-haskell, 3621 bytes > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From apfelmus at quantentunnel.de Mon Jan 4 07:51:03 2010 From: apfelmus at quantentunnel.de (Heinrich Apfelmus) Date: Mon Jan 4 07:24:36 2010 Subject: [Haskell-cafe] Re: Space Efficiency When Sorting a List of Many Lists In-Reply-To: <90427C13-F6A7-48E1-B169-35942CA81636@me.com> References: <7ca3f0160912310238t7bdefdd4xeac221d792ac03bc@mail.gmail.com> <90427C13-F6A7-48E1-B169-35942CA81636@me.com> Message-ID: Peter Green wrote: > Luke Palmer wrote: >> Yes, by a lot. Sorting requires keeping the entire list in memory. >> And Haskell lists, unfortunately, are not that cheap in terms of space >> usage (I think [Int] uses 3 words per element). >> >>> but my questions are: >>> (1) Am I doing anything terribly stupid/naive here? >>> (2) If so, what can I do to improve space efficiency? > > I think I should re-state the problem and provide more background info. > In answer to the poster who suggested using a Trie, there *is* > a real world application for what I'm attempting to do. > I'll also hint at that below: > > { Begin Aside on Why I Would Want to do Such a Silly Thing: > > 'Compressed lists' are in fact compressed wager combinations for > multi-leg exotic horse racing events. 'Exploded lists' are the single > wager combinations covered by the grouped combinations. > > [...] Thanks for describing the background of this problem in detail! I was mainly asking because I'm always looking for interesting Haskell topics that can be turned into a tutorial of sorts, and this problem makes a great example. Concerning optimization, the background also reveals some additional informations, namely * The single wager combinations are short lists * and each list element is small, i.e. `elem` [1..20] * No duplicate single wagers * You are free to choose another ordering than lexicographic > I need to explode these compressed wagers back to single combinations > because, I need to (eventually) do set comparisons on collections of > single combinations. i.e. given File A and File B of compressed wagers, > I need to be able to answer questions like: > > (1) How many single combinations are common to File A and File B > (2) How many single combinations in File A are missing from File B > .. > .. > etc. i.e a few of the common set comparison operations. > > And the dumbest, quickest and dirtiest and most idiot-proof way of doing > this as a baseline approach before I start using maps, tries, etc... is > to explode Files A and B into lex sorted single combinations order and > then use diff -y with judicious grepping for '>' and <'' Looks good to me, sorted lists are a fine data structure for set operations. > I'm probably going to go with an external sort for starters to keep > memory usage down. For most use-cases, I can get away with my current > in-memory sort - just have to beware edge cases. Using an out-of-the box external sort library is probably the path of least resistance, provided the library works as it should. However, your problem has a very special structure; you can interleave explode and sort and turn the algorithm into one that is partially on-line, which will save you a lot of memory. I've tried to show how to do this in my previous post; the resulting code will look something like this {-# LANGUAGE NoMonomorphismRestriction #-} import qualified Data.Map import Control.Arrow (second) newtype Map a b = Map { unMap :: [(a,b)] } deriving (Eq, Show) instance Functor (Map a) where fmap f = Map . (map . second) f . unMap hylo :: (Map a b -> b) -> (c -> Map a c) -> (c -> b) hylo f g = f . fmap (hylo f g) . g type Row a = [a] headsOut :: Map a [Row a] -> [Row a] headsOut (Map []) = [[]] headsOut m = [x:row | (x,rows) <- unMap m, row <- rows] explode1 :: [Row [a]] -> Map a [Row [a]] explode1 rows = Map [(x,[row]) | (xs:row) <- rows, x <- xs] sort1 :: Ord a => Map a [b] -> Map a [b] sort1 = Map . Data.Map.toList . Data.Map.fromListWith (++) . unMap sortExplode = hylo headsOut (sort1 . explode1) example = [[[8,12],[11],[7,13],[10]], [[1,2,3],[1,9],[3,6],[4]]] test = sortExplode example main = interact (unlines . toCSV . sortExplode . fromCSV . lines) In other words, sortExplode will "stream" the sorted single wagers on demand, unlike the monolithic sort . explode which has to produce all single wagers before sorting them. > However, later on, I'm keen to do everything with set theoretic > operations and avoid writing large files of single combinations to disk. Note that there's also the possibility of not expanding the compressed wagers at all, and perform set operations directly. For instance, it is straightforward to intersect two such sets of size n in O(n^2) time. Since n ~ 5000 , n^2 is about the same ballpark as the exploded single wager combinations. > So, I guess the things I'd like to get a feel for are: > > (1) Is it realistic to expect to do in-memory set comparisons on sets > with ~1M elements where each element is a (however-encoded) list of > (say) 6 integers? I mean realistic in terms of execution time and space > usage, of course. > > (2) What would be a good space-efficient encoding for these single > combinations? I know that there will never be more than 8 integers in a > combination, and none of these values will be < 1 or > 20. So perhaps I > should map them to ByteString library Word8 strings? Presumably sorting > a big list of ByteStrings is going to be faster than sorting a big list > of lists of int? The overhead for lists and sets are quite high, it's not uncommon for 1M elements to occupy 10M-100M of memory. Not to mention that your elements are, in fact, small lists, introducing another factor of 10-100. But this can indeed be ameliorated considerably by representing your elements in a packed format like ByteStrings or a Word64. Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com From apfelmus at quantentunnel.de Mon Jan 4 08:29:19 2010 From: apfelmus at quantentunnel.de (Heinrich Apfelmus) Date: Mon Jan 4 08:03:34 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001030508.46357.daniel.is.fischer@web.de> <201001040129.22689.daniel.is.fischer@web.de> Message-ID: Will Ness wrote: > > I keep thinking that storage duplication with span, filter etc. is not really > necessary, and can be replaced with some pointer chasing - especially when > there's only one consumer present for the generated values. > > What I mean is thinking of lists in terms of produce/consumer paradigm, as > objects supporting the { pull, peek } interface, keeping the generator inside > that would produce the next value on 'pull' request and keep it ready for > any 'peek's. > > Euler's sieve is > > sieve (p:ps) xs = h ++ sieve ps (t `minus` map (p*) [p,p+2..]) > where (h,t) = span (< p*p) xs > > [...] > > The real difference here is between those producers whose values will only be > consumed once, by one specific consumer, and those which values may be needed > more than once, so need really to be maintained in some storage. If not - span, > filter, map, whatever - they all are just little modifiers on top of the real > producers, which may or may not also have an actual storage maintained by them. (I haven't followed the whole thread, but hopefully I have enough grasp of it to make a useful remark. :)) Concerning lists as producer/consumer, I think that's exactly what lazy evaluation is doing. Neither filter , map or span evaluate and store more list elements that strictly necessary. Sure, creating a list head only to immediately consume it is somewhat inefficient -- and the target of stream fusion[1] -- but this is an overhead of how list elements are stored, not how many. You can try to implement the Euler sieve with producers by using a type like data Producer a = forall s. Producer { state :: !s, next :: s -> s, value :: s -> a } but I think this will be quite difficult; it's not clear what and thus how big the state will be. (See [1] for choosing a good type.) Concerning the sieves, there is a fundamental difference between the imperative sieve and the functional sieves, regardless of whether the latter start at p or p^2 or use a priority queue. Namely, the imperative sieve makes essential use of *pointer arithmetic*. The key point is that in order to cross off the multiples p, 2*p, 3*p, ... of a prime, the algorithm can directly jump from the (k*p)-th to the (k*p+p)-th array element by adding p to the index. The functional versions can never beat that because they can't just jump over p constructors of a data structure in O(1) time. [1]: http://www.cse.unsw.edu.au/~dons/papers/CLS07.html Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com From uzytkownik2 at gmail.com Mon Jan 4 08:51:13 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Mon Jan 4 08:25:38 2010 Subject: [Haskell-cafe] Re: Data.Ring -- Pre-announce In-Reply-To: References: Message-ID: <1262613072.13413.64.camel@picard> On Thu, 2009-12-31 at 04:59 -0500, John Van Enk wrote: > Hi List, > > I recently needed a ring structure (circular list with bi-directional > access) and didn't see anything obvious on Hackage. I threw something > together fairly quickly and would like some feedback before tossing it > on Hackage. > > I'd really appreciate if some one would: > 1. make sure the code looks goodish (127 lines with full docs) > 2. make sure my tests look saneish > If I hear nothing, I'll assume wild support and push to Hackage. > > Code: http://github.com/sw17ch/data-ring/blob/master/src/Data/Ring.hs > Tests: > http://github.com/sw17ch/data-ring/blob/master/tests/quickcheck.hs > Package Root: http://github.com/sw17ch/data-ring > > Thanks ahead of time, > John Van Enk Monad, MonadPlus, Applicative, Alternative, Foldable and Traversable. About comonad - not exactly as every comonad is copointed and the only possible way is extract Empty = _|_ Regards -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-Added-Monad-instance.patch Type: text/x-patch Size: 796 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/3f540487/0001-Added-Monad-instance.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: 0002-Added-MonadPlus-instance.patch Type: text/x-patch Size: 990 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/3f540487/0002-Added-MonadPlus-instance.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: 0003-Added-Applicative-instance.patch Type: text/x-patch Size: 1038 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/3f540487/0003-Added-Applicative-instance.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: 0004-Added-Alternative-instance.patch Type: text/x-patch Size: 1004 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/3f540487/0004-Added-Alternative-instance.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: 0005-Added-Foldable-instance.patch Type: text/x-patch Size: 1117 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/3f540487/0005-Added-Foldable-instance.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: 0006-Added-Traversable-instance.patch Type: text/x-patch Size: 1071 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/3f540487/0006-Added-Traversable-instance.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: 0007-Added-Pointed-instance.patch Type: text/x-patch Size: 1193 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/3f540487/0007-Added-Pointed-instance.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: 0008-Added-Copointed-instance.patch Type: text/x-patch Size: 850 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/3f540487/0008-Added-Copointed-instance.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: 0009-Added-Comonad-instance.patch Type: text/x-patch Size: 1248 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/3f540487/0009-Added-Comonad-instance.bin From lrpalmer at gmail.com Mon Jan 4 09:17:09 2010 From: lrpalmer at gmail.com (Luke Palmer) Date: Mon Jan 4 08:50:10 2010 Subject: [Haskell-cafe] Re: Data.Ring -- Pre-announce In-Reply-To: <1262613072.13413.64.camel@picard> References: <1262613072.13413.64.camel@picard> Message-ID: <7ca3f0161001040617w1a67529crb513c4c926564c6a@mail.gmail.com> On Mon, Jan 4, 2010 at 6:51 AM, Maciej Piechotka wrote: > About comonad - not exactly as every comonad is copointed and the only > possible way is extract Empty = _|_ I think this module could be cleaned up by disallowing empty lists. You have this nice semantic property that "every clist has a focus", but when you add empty you have to add "unless it's empty". focus returns a Maybe, isEmpty is necessary. I mean, it could be that your use case requires empty clists and would be uglier without empty, but think about it. I find in Haskell that simplicity breeds simplicity; i.e. I'm willing to wager that whatever algorithm you are using clist for will actually be cleaner if you got rid of empty and modify the algorithm accordingly. We shall see though... Luke From vanenkj at gmail.com Mon Jan 4 09:19:53 2010 From: vanenkj at gmail.com (John Van Enk) Date: Mon Jan 4 08:52:56 2010 Subject: [Haskell-cafe] Re: Data.Ring -- Pre-announce In-Reply-To: <7ca3f0161001040617w1a67529crb513c4c926564c6a@mail.gmail.com> References: <1262613072.13413.64.camel@picard> <7ca3f0161001040617w1a67529crb513c4c926564c6a@mail.gmail.com> Message-ID: I've heard this a few times and am slowly becoming convinced of it. I'll try my current use without the Empty and see how it goes. Given that I've heard this from several places, I'll probably drop Empty. On Mon, Jan 4, 2010 at 9:17 AM, Luke Palmer wrote: > On Mon, Jan 4, 2010 at 6:51 AM, Maciej Piechotka > wrote: > > About comonad - not exactly as every comonad is copointed and the only > > possible way is extract Empty = _|_ > > I think this module could be cleaned up by disallowing empty lists. > You have this nice semantic property that "every clist has a focus", > but when you add empty you have to add "unless it's empty". focus > returns a Maybe, isEmpty is necessary. > > I mean, it could be that your use case requires empty clists and would > be uglier without empty, but think about it. I find in Haskell that > simplicity breeds simplicity; i.e. I'm willing to wager that whatever > algorithm you are using clist for will actually be cleaner if you got > rid of empty and modify the algorithm accordingly. We shall see > though... > > Luke > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/8681bb70/attachment.html From daniel.is.fischer at web.de Mon Jan 4 10:05:45 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Jan 4 09:40:25 2010 Subject: [Haskell-cafe] Interpreting profiling results In-Reply-To: References: Message-ID: <201001041605.45336.daniel.is.fischer@web.de> Am Montag 04 Januar 2010 02:17:06 schrieb Patrick LeBoutillier: > Hi, > > This question didn't get any replies on the beginners list, I thought > I'd try it here... Sorry, been occupied with other things. I already took a look, but hadn't anything conclusive enough to reply yet. > > I've written (and improved using other solutions I've found on the > net) a simple sudoku solver which I'm trying to profile. Here is the > code: > > > import Array Better import Data.Array.Unboxed *much* faster > import List (transpose, nub, (\\)) > import Data.List > > data Sudoku = Sudoku { unit :: Int, cells :: Array (Int, Int) Int, cells :: UArray (Int,Int) Int > holes :: [(Int, Int)] } > > cell :: Sudoku -> (Int, Int) -> Int > cell s i = (cells s) ! i > > instance Read Sudoku where > ?readsPrec _ s = [(Sudoku unit cells holes, "")] > ? ?where unit = length . words . head . lines $ s > ? ? ? ? ?cells = listArray ((1, 1), (unit, unit)) (map read . words $ s) > ? ? ? ? ?holes = [ c | c <- indices cells, (cells ! c) == 0] > > instance Show Sudoku where > ?show s = unlines [unwords [show $ cell s (x,y) | x <- [1 .. unit s]] > > | y <- [1 .. unit s]] > > genNums :: Sudoku -> (Int, Int) -> [Int] > genNums s c@(i,j) = ([1 .. u] \\) . nub $ used > ?where nub isn't nice. It's quadratic in the length of the list. Use e.g. map head . group . sort or Data.[Int]Set.toList . Data.[Int]Set.fromList if the type is in Ord (and you don't need the distinct elements in the order they come in). That gives an O(n*log n) nub with a sorted result. And (\\) isn't particularly fast either (O(m*n), where m and n are the lengths of the lists). If you use one of the above instead of nub, you can use the O(min m n) 'minus' for sorted lists: xxs@(x:xs) `minus` yys@(y:ys) | x < y = x : xs `minus` yys | x == y = xs `minus` ys | otherwise = xxs `minus` ys xs `minus` _ = xs Here, you can do better: genNums s c@(i,j) = nums where nums = [n | n <- [1 .. u], arr!n] arr :: [U]Array Int Bool arr = accumArray (\_ _ -> False) True (0,u) used > ? ?used = (row s u i j) ++ (col s u i j) ++ (square s sq u i j) > ? ?u = unit s Not good to calculate sq here. You'll use it many times, calculate once and store it in s. > ? ?sq = truncate . sqrt . fromIntegral $ u > > row s u i j = [cell s (i, y) | y <- [1 .. u]] > > col s u i j = [cell s (x, j) | x <- [1 .. u]] > > square s sq u i j = [cell s (x, y) | y <- [1 .. u], x <- [1 .. u], f x i, f > y j] where f a b = div (a-1) sq == div (b-1) sq Test for f y j before you generate x to skip early. square s sq u i j = [cell s (ni+x,nj+y) | x <- [1 .. sq], y <- [1 .. sq]] where qi = (i-1) `div` sq qj = (j-1) `div` sq ni = qi*sq nj = qj*sq > > solve :: Sudoku -> [Sudoku] > solve s = > ?case holes s of > ? ?[] -> [s] > ? ?(h:hs) -> do > ? ? ?n <- genNums s h > ? ? ?let s' = Sudoku (unit s) ((cells s) // [(h, n)]) hs > ? ? ?solve s' > > main = print . head . solve . read =<< getContents > > > When I compile as such: > > $ ghc -O2 --make Sudoku.hs -prof -auto-all -caf-all -fforce-recomp > > and run it on the following puzzle: > > 0 2 3 4 > 3 4 1 0 > 2 1 4 0 > 0 3 2 1 > > I get the following profiling report: > > ? ? ? ?Fri Jan ?1 10:34 2010 Time and Allocation Profiling Report ?(Final) > > ? ? ? ? ? Sudoku +RTS -p -RTS > > ? ? ? ?total time ?= ? ? ? ?0.00 secs ? (0 ticks @ 20 ms) That means the report is basically useless. Not entirely, because the allocation figures may already contain useful information. Run on a 9x9 puzzle (a not too hard one, but not trivial either). Also, run the profiling with -P instead of -p, you'll get more info about time and allocation then. > ? ? ? ?total alloc = ? ? 165,728 bytes ?(excludes profiling overheads) > > COST CENTRE ? ? ? ? ? ? ? ? ? ?MODULE ? ? ? ? ? ? ? %time %alloc > > CAF ? ? ? ? ? ? ? ? ? ? ? ? ? ?GHC.Handle ? ? ? ? ? ? 0.0 ? 10.7 > CAF ? ? ? ? ? ? ? ? ? ? ? ? ? ?Text.Read.Lex ? ? ? ? ?0.0 ? ?2.1 > CAF ? ? ? ? ? ? ? ? ? ? ? ? ? ?GHC.Read ? ? ? ? ? ? ? 0.0 ? ?1.2 > square ? ? ? ? ? ? ? ? ? ? ? ? Main ? ? ? ? ? ? ? ? ? 0.0 ? ?2.8 > solve ? ? ? ? ? ? ? ? ? ? ? ? ?Main ? ? ? ? ? ? ? ? ? 0.0 ? ?1.3 > show_aVx ? ? ? ? ? ? ? ? ? ? ? Main ? ? ? ? ? ? ? ? ? 0.0 ? ?3.7 > readsPrec_aYF ? ? ? ? ? ? ? ? ?Main ? ? ? ? ? ? ? ? ? 0.0 ? 60.6 > main ? ? ? ? ? ? ? ? ? ? ? ? ? Main ? ? ? ? ? ? ? ? ? 0.0 ? ?9.6 > genNums ? ? ? ? ? ? ? ? ? ? ? ?Main ? ? ? ? ? ? ? ? ? 0.0 ? ?5.0 > cell ? ? ? ? ? ? ? ? ? ? ? ? ? Main ? ? ? ? ? ? ? ? ? 0.0 ? ?1.2 > > > > ? ? ? ? ? ? ? ? ? ? ? ?individual ? ?inherited > COST CENTRE ? ? ? ? ? ? ?MODULE > ? ? ? no. ? ?entries ?%time %alloc ? %time %alloc > > MAIN ? ? ? ? ? ? ? ? ? ? MAIN > ? ? ? ? 1 ? ? ? ? ? 0 ? 0.0 ? ?0.3 ? ? 0.0 ?100.0 > ?main ? ? ? ? ? ? ? ? ? ?Main > ? ? ? 186 ? ? ? ? ? 1 ? 0.0 ? ?9.6 ? ? 0.0 ? 85.6 > ?show_aVx ? ? ? ? ? ? ? Main > ? ? ? 196 ? ? ? ? ? 2 ? 0.0 ? ?3.7 ? ? 0.0 ? ?3.7 > ? cell ? ? ? ? ? ? ? ? ?Main > ? ? ? 197 ? ? ? ? ?16 ? 0.0 ? ?0.0 ? ? 0.0 ? ?0.0 > ?solve ? ? ? ? ? ? ? ? ?Main > ? ? ? 188 ? ? ? ? ? 5 ? 0.0 ? ?1.3 ? ? 0.0 ? 11.8 > ? genNums ? ? ? ? ? ? ? Main > ? ? ? 189 ? ? ? ? ? 8 ? 0.0 ? ?5.0 ? ? 0.0 ? 10.4 > ? ?square ? ? ? ? ? ? ? Main > ? ? ? 194 ? ? ? ? ?88 ? 0.0 ? ?2.8 ? ? 0.0 ? ?3.2 > ? ? cell ? ? ? ? ? ? ? ?Main > ? ? ? 195 ? ? ? ? ?16 ? 0.0 ? ?0.4 ? ? 0.0 ? ?0.4 > ? ?col ? ? ? ? ? ? ? ? ?Main > ? ? ? 192 ? ? ? ? ? 4 ? 0.0 ? ?0.7 ? ? 0.0 ? ?1.1 > ? ? cell ? ? ? ? ? ? ? ?Main > ? ? ? 193 ? ? ? ? ?16 ? 0.0 ? ?0.4 ? ? 0.0 ? ?0.4 > ? ?row ? ? ? ? ? ? ? ? ?Main > ? ? ? 190 ? ? ? ? ? 4 ? 0.0 ? ?0.7 ? ? 0.0 ? ?1.1 > ? ? cell ? ? ? ? ? ? ? ?Main > ? ? ? 191 ? ? ? ? ?16 ? 0.0 ? ?0.4 ? ? 0.0 ? ?0.4 > ?readsPrec_aYF ? ? ? ? ?Main > ? ? ? 187 ? ? ? ? ? 3 ? 0.0 ? 60.6 ? ? 0.0 ? 60.6 > ?CAF ? ? ? ? ? ? ? ? ? ? GHC.Read > ? ? ? 151 ? ? ? ? ? 1 ? 0.0 ? ?1.2 ? ? 0.0 ? ?1.2 > ?CAF ? ? ? ? ? ? ? ? ? ? Text.Read.Lex > ? ? ? 144 ? ? ? ? ? 8 ? 0.0 ? ?2.1 ? ? 0.0 ? ?2.1 > ?CAF ? ? ? ? ? ? ? ? ? ? GHC.Handle > ? ? ? 128 ? ? ? ? ? 4 ? 0.0 ? 10.7 ? ? 0.0 ? 10.7 > ?CAF ? ? ? ? ? ? ? ? ? ? GHC.Conc > ? ? ? 127 ? ? ? ? ? 1 ? 0.0 ? ?0.0 ? ? 0.0 ? ?0.0 > > Does the column 'entries' represent the number of times the function > was called? Number of times it was 'entered', not quite the same as the number of times it was called. I think (Warning: speculation ahead, I don't *know* how the profiles are generated) it's thus: Say you call a function returning a list. One call, first entry. It finds the beginning of the list, the first k elements and hands them to the caller. Caller processes these, asks "can I have more, or was that it?". Same call, second entry: f looks for more, finds the next m elements, hands them to caller. Caller processes. Repeat until whatever happens first, caller doesn't ask whether there's more or callee finds there's nothing more (or hits bottom). > If so, I don't understand how the 'square' function could > be called 88 times when it's caller is only called 8 times. Same thing > with 'genNums' (called 8 times, and solve called 5 times) > > What am I missing here? > > Patrick -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/44306f6b/attachment-0001.html From will_n48 at yahoo.com Mon Jan 4 10:30:18 2010 From: will_n48 at yahoo.com (Will Ness) Date: Mon Jan 4 10:03:55 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001030508.46357.daniel.is.fischer@web.de> <201001040129.22689.daniel.is.fischer@web.de> Message-ID: Heinrich Apfelmus quantentunnel.de> writes: > > Will Ness wrote: > > > > I keep thinking that storage duplication with span, filter etc. is not > > really > > necessary, and can be replaced with some pointer chasing - especially when > > there's only one consumer present for the generated values. > > > > What I mean is thinking of lists in terms of produce/consumer paradigm, as > > objects supporting the { pull, peek } interface, keeping the generator > > inside that would produce the next value on 'pull' request and keep it > > ready for any 'peek's. > > > > Euler's sieve is > > > > sieve (p:ps) xs = h ++ sieve ps (t `minus` map (p*) [p,p+2..]) > > where (h,t) = span (< p*p) xs > > > > [...] > > > > The real difference here is between those producers whose values will > > only be consumed once, by one specific consumer, and those which values > > may be needed more than once, so need really to be maintained in some > > storage. If not - span, filter, map, whatever - they all are just little > > modifiers on top of the real producers, which may or may not also have > > an actual storage maintained by them. > > (I haven't followed the whole thread, but hopefully I have enough grasp > of it to make a useful remark. :)) > > Concerning lists as producer/consumer, I think that's exactly what lazy > evaluation is doing. Neither filter , map or span evaluate and > store more list elements that strictly necessary. I laways suspected as much, but was once told that Chris Okasaki has shown that any filter etc must allocate its own storage. With the peek/pull they don't have to, if they are nested, and the deepest one from the real storage gets pulled through some pointer chasing eventually. Span isn't so easily compiled out too or is it? But that might be a minor point. For me, a real smart compiler is one that would take in e.g. (sum $ take n $ cycle $ [1..m]) and spill out a straight up math formula, inside a few ifs maybe (just an aside). Such a smart compiler might even be able to derive a well performing code right from the Turner's sieve. :) > Sure, creating a list head only to immediately consume it is somewhat > inefficient -- and the target of stream fusion[1] -- but this is an > overhead of how list elements are stored, not how many. it might be equivalent to the (imagined) producer's storing its 'current' value inside its frame. How much can we rely on the run-time to actually destroy all the passed-over elements and not hang on to them for some time? Is this that compiler switch that Daniel mentioned? Is it reliable? > > You can try to implement the Euler sieve with producers by using a type like > > data Producer a = forall s. Producer { > state :: !s, next :: s -> s, value :: s -> a } > > but I think this will be quite difficult; it's not clear what and thus > how big the state will be. (See [1] for choosing a good type.) I did that once in Scheme, as per SICP, with 'next' hanging in a stream's tail. Put filters and maps on top of that (inside the new 'next' actually). But that used the Scheme's lists as sorage. Another one was actual producers/modifiers with {pull,peek} interface. It even produced some primes, and some Hamming numbers. Then I saw Haskell, and thought I'd get all that for free with its equational reasoning. But I get the impression that GHC isn't working through equational reasoning?.. I see all this talk about thunks etc. > Concerning the sieves, there is a fundamental difference between the > imperative sieve and the functional sieves, regardless of whether the > latter start at p or p^2 or use a priority queue. Namely, the imperative > sieve makes essential use of *pointer arithmetic*. The key point is that > in order to cross off the multiples > > p, 2*p, 3*p, ... > > of a prime, the algorithm can directly jump from the (k*p)-th to the > (k*p+p)-th array element by adding p to the index. The functional > versions can never beat that because they can't just jump over p > constructors of a data structure in O(1) time. We can directy jump to the next multiple too, it is called (+). :) :) But seriously, the real issue is that we have to merge the produced streams of multiples, while the mutable-storage code works on same one, so its "merging cost" is zero. And even if we are smart to merge them in a tree-like fashion, we still have no (or little) control over the compiler's representation of lists and retention of their content and whether it performs stream fusion or not (if we use lists). If you could take a look at the tree-merging primes and why it uses too much memory, it would be great. The code is in Daniel's post to which I replied, or on haselwiki Prime_numbers page (there in its rudimentary form). It's a tangent to your VIP code, where instead of People structure an ordered list is just maintained as a split pair, of its known (so far, finite) prefix and the rest of it. Then under merging these split pairs form a monoid, s can be rearranged in a tree. If you have'nt seen it yet, it uses a different folding structure to your code, with a lower total cost of multiples production (estimated as Sum (1/p)*depth): tfold f (x:y:z:xs) = (x `f` (y `f` z)) `f` pairwise f xs comps = tfold $ pairwise mergeSP multips But aside from the memory problem (about 50M vs Melissa's 2M), for the first few million primes produced it has almost exactly the same asymptotics as her PQ code and runs on par with it, compiled (and 2.5x faster when interpreted, in GHCi). It is also clear and concise. :) :) I think I'll have to try out your code (amended with a new folding structure) and see if it has less memory problems maybe. I assume it is your code on the haskellwiki page. (?) Cheers, > > [1]: http://www.cse.unsw.edu.au/~dons/papers/CLS07.html > > Regards, > Heinrich Apfelmus > > -- > http://apfelmus.nfshost.com > From gue.schmidt at web.de Mon Jan 4 10:55:44 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Mon Jan 4 10:31:36 2010 Subject: [Haskell-cafe] curl on windows? Message-ID: <4B420F80.8070706@web.de> Hi, how can I install curl on windows (XP)? G?nther From kinch1967 at me.com Mon Jan 4 11:34:05 2010 From: kinch1967 at me.com (Peter Green) Date: Mon Jan 4 11:07:30 2010 Subject: [Haskell-cafe] Space Efficiency When Sorting a List of Many Lists In-Reply-To: <20100104144030.949BD3244D3@www.haskell.org> References: <20100104144030.949BD3244D3@www.haskell.org> Message-ID: Heinrich, thanks for some great help and food for thought! (More on performance of your solution below) > Thanks for describing the background of this problem in detail! I was > mainly asking because I'm always looking for interesting Haskell > topics > that can be turned into a tutorial of sorts, and this problem makes a > great example. Another interesting problem is starting from a file of single wagers and trying to compress them (i.e. inverse of 'explosion'. I believe this problem is analogous to Set Cover and therefore NP-Complete. Heuristics are the order of the day here. (OT, but might also make an interesting multi-part tutorial question/ topic: A simpler (fairly unrelated problem) is doing exact k-means clustering of a list of n items (i.e. single dimension data) via the k- segmentations of a (sorted by values one is clustering on) list of n items. The number of k-segmentations of an n-list is (n-1) Choose (k-1). One generates all the k-segmentations and each set of k- segments constitutes a candidate clustering solution. One selects the candidate solution which minimises the 'goodness of fit criterion' used in k-means clustering (easily found in the literature). Needless to say, this is only feasible for smallish n and for values of k closer to the LHS and RHS of Pascal's triangle. K-means clustering in more than one dimension is NP-Complete.) > Concerning optimization, the background also reveals some additional > informations, namely > > * The single wager combinations are short lists > * and each list element is small, i.e. `elem` [1..20] > * No duplicate single wagers > * You are free to choose another ordering than lexicographic > >> I need to explode these compressed wagers back to single combinations >> because, I need to (eventually) do set comparisons on collections of >> single combinations. i.e. given File A and File B of compressed >> wagers, >> I need to be able to answer questions like: >> >> (1) How many single combinations are common to File A and File B >> (2) How many single combinations in File A are missing from File B >> .. >> .. >> etc. i.e a few of the common set comparison operations. >> >> And the dumbest, quickest and dirtiest and most idiot-proof way of >> doing >> this as a baseline approach before I start using maps, tries, >> etc... is >> to explode Files A and B into lex sorted single combinations order >> and >> then use diff -y with judicious grepping for '>' and <'' > > Looks good to me, sorted lists are a fine data structure for set > operations. > >> I'm probably going to go with an external sort for starters to keep >> memory usage down. For most use-cases, I can get away with my current >> in-memory sort - just have to beware edge cases. > > Using an out-of-the box external sort library is probably the path of > least resistance, provided the library works as it should. Seems to be some issue with the external-sort package. As it currently exists, it blows up on my [[Int]] data and exhibits more memory usage than vanilla sort! I'm keen to look into fixing this as might be one small way I can give back, but still taking baby steps with Haskell. > However, your problem has a very special structure; you can interleave > explode and sort and turn the algorithm into one that is partially > on-line, which will save you a lot of memory. I've tried to show how > to > do this in my previous post; the resulting code will look something > like > this > > {-# LANGUAGE NoMonomorphismRestriction #-} > import qualified Data.Map > import Control.Arrow (second) > > newtype Map a b = Map { unMap :: [(a,b)] } deriving (Eq, Show) > > instance Functor (Map a) where > fmap f = Map . (map . second) f . unMap > > hylo :: (Map a b -> b) -> (c -> Map a c) -> (c -> b) > hylo f g = f . fmap (hylo f g) . g > > type Row a = [a] > > headsOut :: Map a [Row a] -> [Row a] > headsOut (Map []) = [[]] > headsOut m = [x:row | (x,rows) <- unMap m, row <- rows] > > explode1 :: [Row [a]] -> Map a [Row [a]] > explode1 rows = Map [(x,[row]) | (xs:row) <- rows, x <- xs] > > sort1 :: Ord a => Map a [b] -> Map a [b] > sort1 = Map . Data.Map.toList . Data.Map.fromListWith (++) . unMap > > sortExplode = hylo headsOut (sort1 . explode1) > > example = [[[8,12],[11],[7,13],[10]], [[1,2,3],[1,9],[3,6],[4]]] > test = sortExplode example > > main = interact (unlines . toCSV . sortExplode . fromCSV . lines) > > In other words, sortExplode will "stream" the sorted single wagers > on > demand, unlike the monolithic sort . explode which has to produce > all > single wagers before sorting them. Thank you *very* much for this code! I will try to get my head around it. I understand the broad outline you posted elsewhere, but will take me a while to fully grasp the above as I'm only up to ~p200 in Real World Haskell :). As for performance of your code above on my file of compressed wagers which expands to 3.7M single wagers: (My original version posted here and using vanilla sort) 541 MB total memory in use (5 MB lost due to fragmentation) INIT time 0.00s ( 0.01s elapsed) MUT time 13.98s ( 15.82s elapsed) GC time 8.69s ( 9.64s elapsed) EXIT time 0.00s ( 0.00s elapsed) Total time 22.67s ( 25.47s elapsed) (Your much improved version) 10 MB total memory in use (1 MB lost due to fragmentation) INIT time 0.00s ( 0.00s elapsed) MUT time 7.61s ( 9.38s elapsed) GC time 3.48s ( 3.58s elapsed) EXIT time 0.00s ( 0.00s elapsed) Total time 11.08s ( 12.95s elapsed) Very impressive and thanks again! >> However, later on, I'm keen to do everything with set theoretic >> operations and avoid writing large files of single combinations to >> disk. > > Note that there's also the possibility of not expanding the compressed > wagers at all, and perform set operations directly. For instance, it > is > straightforward to intersect two such sets of size n in O(n^2) time. > Since n ~ 5000 , n^2 is about the same ballpark as the exploded single > wager combinations. Not sure I quite understand you here. In my mind, set elements *are* single combinations. It is possible for two quite different-looking files of compressed wagers to contain exactly the same single wager elements. So I'm not sure how to compare without some notion of explosion to single combinations. >> So, I guess the things I'd like to get a feel for are: >> >> (1) Is it realistic to expect to do in-memory set comparisons on sets >> with ~1M elements where each element is a (however-encoded) list of >> (say) 6 integers? I mean realistic in terms of execution time and >> space >> usage, of course. >> >> (2) What would be a good space-efficient encoding for these single >> combinations? I know that there will never be more than 8 integers >> in a >> combination, and none of these values will be < 1 or > 20. So >> perhaps I >> should map them to ByteString library Word8 strings? Presumably >> sorting >> a big list of ByteStrings is going to be faster than sorting a big >> list >> of lists of int? > > The overhead for lists and sets are quite high, it's not uncommon > for 1M > elements to occupy 10M-100M of memory. > > Not to mention that your elements are, in fact, small lists, > introducing > another factor of 10-100. But this can indeed be ameliorated > considerably by representing your elements in a packed format like > ByteStrings or a Word64. I haven't tried packing ByteStrings yet in this context, but *did* get some improvement in external-sort performance when using ByteStrings instead of [[Int]]. Presumably because it somewhat ameliorated the effects of a bug in external-sort where blocks are fully compared rather than just the heads of blocks. I'll be interested to play around with your version more and see if it benefits much from ByteString. It's already very good now in terms of space usage, but perhaps can speed up the I/O (output dominates, of course). I'll be learning from your post for a long time. So thanks again! -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/80386ac0/attachment.html From emax at chalmers.se Mon Jan 4 11:41:58 2010 From: emax at chalmers.se (Emil Axelsson) Date: Mon Jan 4 11:15:00 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001030508.46357.daniel.is.fischer@web.de> <201001040129.22689.daniel.is.fischer@web.de> Message-ID: <4B421A56.5050707@chalmers.se> > For me, a real smart compiler is one that would take in e.g. (sum $ take n $ > cycle $ [1..m]) and spill out a straight up math formula, inside a few ifs > maybe (just an aside). (Also an aside, I couldn't resist...) Then I'm sure you'd say that Feldspar [1] has a smart compiler :) The above expression written in Feldspar and the resulting C code can be found here: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=15592#a15593 The C code is somewhat complicated by the fact that Feldspar doesn't have infinite vectors. Feldspar usually works well on small examples like this one, but we're very much lacking bigger examples, so I can't advise you to use it for prime numbers just yet. / Emil [1] http://feldspar.sourceforge.net/ From brandon.m.simmons at gmail.com Mon Jan 4 11:50:57 2010 From: brandon.m.simmons at gmail.com (Brandon Simmons) Date: Mon Jan 4 11:24:18 2010 Subject: [Haskell-cafe] Why can't we make an instance declaration on a type synonym? In-Reply-To: <87tyv3fy9d.fsf@gmail.com> References: <303b11b2-337b-4115-86ea-dfee96f329c2@3g2000vbp.googlegroups.com> <87tyv3fy9d.fsf@gmail.com> Message-ID: On Sun, Jan 3, 2010 at 2:22 AM, Ivan Lazar Miljenovic wrote: > jberryman writes: > >> This may be a dumb question, but why can we not declare a Monad >> instance of a type synonym? This question came to me while working >> with the State monad recently and feeling that the requirement that we >> wrap our functions in the State constructor is a bit... kludgy. >> > > Because type defines an _alias_. ?If you define "type Foo = Maybe Int", > then everywhere you have a "Foo" the compiler should be able to replace > it with "Maybe Int". > > As such, if you have a custom instance on your type synonym (say a > custom Show instance for Foo), then which instance will the compiler > use? Thanks. I guess what I'm really asking is if there is any way to redefine the monad instance for (->) such that we can have a State monad without the data constructor wrapper. It sounds like there probably isn't, but it seems like that would be a pretty useful thing to be able to do generally. From daniel.is.fischer at web.de Mon Jan 4 12:02:35 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Jan 4 11:37:14 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001040129.22689.daniel.is.fischer@web.de> Message-ID: <201001041802.35854.daniel.is.fischer@web.de> Am Montag 04 Januar 2010 13:25:47 schrieb Will Ness: > Daniel Fischer web.de> writes: > > Am Sonntag 03 Januar 2010 09:54:37 schrieb Will Ness: > > > Daniel Fischer web.de> writes: > > > > But there's a lot of list constructuion and deconstruction necessary > > > > for the Euler sieve. > > > > > > yes. Unless, of course, s smart compiler recognizes there's only one > > > consumer for the values each multiples-list is producing, and keeps it > > > stripped down to a generator function, and its current value. I keep > > > thinkig a smart compiler could eliminate all these "span" calls and > > > replace them with just some pointers manipulating... > > > > Of course I'm no smart compiler, but I don't see how it could be even > > possible to replace the span calls with pointer manipulation when dealing > > with lazily generated (infinite, if we're really mean) lists. Even when > > you're dealing only with strict finite lists, it's not trivial to do > > efficiently. > > I keep thinking that storage duplication with span, filter etc. is not > really necessary, and can be replaced with some pointer chasing - > especially when there's only one consumer present for the generated values. > > What I mean is thinking of lists in terms of produce/consumer paradigm, as > objects supporting the { pull, peek } interface, keeping the generator > inside that would produce the next value on 'pull' request and keep it > ready for any 'peek's. > > Euler's sieve is > > sieve (p:ps) xs = h ++ sieve ps (t `minus` map (p*) [p,p+2..]) > where (h,t) = span (< p*p) xs Not quite. That's a variant of the postponed filters, it crosses off e.g. 45 twice, once as 3*15 and once as 5*9 (okay, it has already been removed by the first, so let's say 45 appears in two lists of numbers to be removed if present). Euler's sieve is never attempting to remove a number more than once, that's the outstanding feature of it. Unfortunately, that also makes it hard to implement efficiently. The problem is that you can't forget the primes between p and p^2, you must remember them for the removal of multiples of p later on. An (inefficient but faithful) implementation would be euler ks@(p:rs) = p : euler (rs `minus` map (*p) ks) Its performance is really horrible though. A much better implementation is primes = 2:3:euler hprs [] (scanl (+) 5 (cycle [2,4])) where hprs = 5:drop 3 primes euler (p:ps) acc cs = h ++ euler ps (tail (acc ++ h)) (t `minus` comps) where (h,t) = span (< p*p) cs comps = map (*p) (acc ++ cs) still really bad. I don't yet see how to eat the cake and have it here. > > > > I think that remark was meant to apply to composite removal, not > > > > Turner's sieve. > > > > > > It is right there on page 2, right when the Turner's sieve is presented > > > and discussed. The only explanation that I see is that she thought of > > > it in regards to the imperative code, just as her analysis concentrates > > > only on calculation aspects of the imperative code itself. > > > > To be fair, she writes: > > > > "Let us ?rst describe the original ?by hand? sieve algorithm as practiced > > by Eratosthenes. > > ... > > The starting point of p^2 is a pleasing but minor optimization, which can > > be made > > because lower multiples will have already been crossed o? when we found > > the primes prior to p. > > ... (This optimization does not a?ect the time complexity of the sieve, > > however, so its absence from the code in Section 1 > > *is not our cause for worry*.)" > > A-HA! > > But its absense from _*that*_ _*code*_ WAS the *major* cause for worry, as > dealing with it worked wonders on its complexity and constant factors. I think you're overinterpreting it. Sure, it's not perfectly worded, but her concern was primarily that it's not an Eratosthenes sieve but trial division (and woefully inefficient at that), I think. Now, because it's trial division and not Eratosthenes, it has a major impact, thus the absence of the optimisation is a reinforcing consequence of the original cause for worry. I may be overdefending her, though, we can't really know what she meant. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/005c3ae7/attachment.html From will_n48 at yahoo.com Mon Jan 4 12:08:42 2010 From: will_n48 at yahoo.com (Will Ness) Date: Mon Jan 4 11:42:07 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001030508.46357.daniel.is.fischer@web.de> <201001040129.22689.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > Am Sonntag 03 Januar 2010 09:54:37 schrieb Will Ness: > > > > The quesion of a memory blowup with the treefolding merge still remains. > > For some reason using its second copy for a feeder doesn't reduce the > > memory (as reported by standalone compiled program, GHCi reported values > > are useless) - it causes it to increase twice..... > > > > I have a partial solution. The big problem is that the feeder holds on to > the beginning of comps while the main runner holds on to a later part. Thus > the entire segment between these two points must be in memory. > > So have two lists of composites (yeah, you know that, but it didn't work > so far). > > But you have to force the compiler not to share them: enter -fno-cse. > The attached code does that (I've also expanded the wheel), it reduces the > memory requirements much (a small part is due to the larger wheel, a factor > of ~5 due to the non-sharing). I don't understand. What is there to be shared? Each multiples list is consumed only at one point; there's nothing to be shared. Do you mean the compiler still hangs on to them? If so, why?? I used the switch; it didn't help at all. The only thing I can see is different is that all my interim data which I named with inner vars you moved out to the top level as functions. Is that what did the trick? What would be the reason to hang on to the already consumed data that is inaccessible to any active consumer? Why not make the forgetful behaviour the norm - especially where remembering is pointless?? > It still uses much more memory than the PQ, and while the PQ's memory > requirements grow very slowly, the tree-fold merge's still grow rather fast > (don't go much beyond the 10,000,000th prime), I'm not sure why. You did it! It's now 7M for 1,000,000th prime, instead of 52M before. Making the pattern lazy in mergeSP was probably an important fix too. :) Unfortunately it grows, as you've said - 23MB for 2 mln. :| PQ stays at just 2MB. > > Attachment (V13Primes.hs): text/x-haskell, 3621 bytes > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From rwbarton at math.harvard.edu Mon Jan 4 12:11:38 2010 From: rwbarton at math.harvard.edu (Reid Barton) Date: Mon Jan 4 11:44:36 2010 Subject: [Haskell-cafe] Why can't we make an instance declaration on a type synonym? In-Reply-To: References: <303b11b2-337b-4115-86ea-dfee96f329c2@3g2000vbp.googlegroups.com> <87tyv3fy9d.fsf@gmail.com> Message-ID: <20100104171138.GA12245@rwbarton.mit.edu> On Mon, Jan 04, 2010 at 11:50:57AM -0500, Brandon Simmons wrote: > On Sun, Jan 3, 2010 at 2:22 AM, Ivan Lazar Miljenovic > wrote: > > jberryman writes: > > > >> This may be a dumb question, but why can we not declare a Monad > >> instance of a type synonym? This question came to me while working > >> with the State monad recently and feeling that the requirement that we > >> wrap our functions in the State constructor is a bit... kludgy. > >> > > > > Because type defines an _alias_. ?If you define "type Foo = Maybe Int", > > then everywhere you have a "Foo" the compiler should be able to replace > > it with "Maybe Int". > > > > As such, if you have a custom instance on your type synonym (say a > > custom Show instance for Foo), then which instance will the compiler > > use? > > > Thanks. I guess what I'm really asking is if there is any way to > redefine the monad instance for (->) such that we can have a State > monad without the data constructor wrapper. It would be a nightmare for type inference. Consider: return "foo" :: String -> (String, String) -- \x -> ("foo", x) which would be valid in a language where we can do what you suggest. `return` has type `a -> m a`, so `a` must be `String`, and now we need to unify `String -> m String` with `String -> String -> (String, String)`. In Haskell, these just don't unify because there are no type-level lambdas. Even if there were, how is the typechecker supposed to know that we want the solution `m a = String -> (a, String)` and not `m a = a -> (a, a)` or many other possibilites? The purpose of the newtype State is to have something to unify `m` with: return "foo" :: State String String We can unify `String -> m String` with `String -> State String String` by setting `m` to `State String`. Regards, Reid Barton From ck_kashyap at yahoo.com Mon Jan 4 12:14:26 2010 From: ck_kashyap at yahoo.com (CK Kashyap) Date: Mon Jan 4 11:47:27 2010 Subject: [Haskell-cafe] A question on DSL's Message-ID: <218657.56688.qm@web112514.mail.gq1.yahoo.com> Hi, I am not sure if I'm using DSL in the right context here but I am referring to those solutions that allow us to write code in Haskell and generate a target code source code of another language or even object code for that matter. I am aware of two ways of achieving this - 1. Implement functions that emit the target code - that is, when the Haskell code is compiled and run, the target code is emitted 2. Modify the Haskell compiler's back end to emit the code - that is when the Haskell code is compiled the target code is emitted I am not sure if there are more ways (hybrid perhaps) ... My question is, when would I chose one approach over the other? Regards, Kashyap From jaspervdj at gmail.com Mon Jan 4 12:20:30 2010 From: jaspervdj at gmail.com (Jasper Van der Jeugt) Date: Mon Jan 4 11:53:51 2010 Subject: [Haskell-cafe] A question on DSL's In-Reply-To: <218657.56688.qm@web112514.mail.gq1.yahoo.com> References: <218657.56688.qm@web112514.mail.gq1.yahoo.com> Message-ID: Hello, I see no real reason to use the second approach, unless you're doing something tremendously new and big. Besides, the first solution is much easier and will be easier to maintain (in case the back end changes). Kind regards, Jasper Van der Jeugt On Mon, Jan 4, 2010 at 6:14 PM, CK Kashyap wrote: > Hi, > I am not sure if I'm using DSL in the right context here but I am referring > to those solutions that allow us to write code in Haskell and generate a > target code source code of another language or even object code for that > matter. I am aware of two ways of achieving this - > 1. Implement functions that emit the target code - that is, when the > Haskell code is compiled and run, the target code is emitted > 2. Modify the Haskell compiler's back end to emit the code - that is when > the Haskell code is compiled the target code is emitted > > I am not sure if there are more ways (hybrid perhaps) ... > > My question is, when would I chose one approach over the other? > > Regards, > Kashyap > > > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/f041d8c0/attachment.html From vanenkj at gmail.com Mon Jan 4 12:21:06 2010 From: vanenkj at gmail.com (John Van Enk) Date: Mon Jan 4 11:54:12 2010 Subject: [Haskell-cafe] A question on DSL's In-Reply-To: <218657.56688.qm@web112514.mail.gq1.yahoo.com> References: <218657.56688.qm@web112514.mail.gq1.yahoo.com> Message-ID: To start with, can you clarify that you are looking for an Embedded DSL (sometimes called Light Weight DSL)? A _proper_ DSL has its own interpreter/compiler where an EDSL/LwDSL leverages the compiler of a host language (in this case, Haskell). Assuming you're referring to an EDSL, I'll respond. :) I don't think the second option is ever used. Modifying the compiler backend doesn't seem to make a lot of sense to me. I'm not aware of any circumstance where this has been done. Your first option is closer. Generally, when emitting some sort of target code from a large EDSL, you'll have two stages. Your first takes the embedded syntax of your EDSL and converts it to an Abstract Syntax Tree. Your second stage accepts the AST as input and emits target code. Take Tom Hawkins' Atom EDSL as an example. When we write Atom code, we're building up an AST. After the AST is built up, the "compile" function converts the AST to C code. For smaller EDSLs, it's more than possible to have the functions themselves emit the code we're after (rather than relying on an AST and compile function). Is this what you're looking for? /jve On Mon, Jan 4, 2010 at 12:14 PM, CK Kashyap wrote: > Hi, > I am not sure if I'm using DSL in the right context here but I am referring > to those solutions that allow us to write code in Haskell and generate a > target code source code of another language or even object code for that > matter. I am aware of two ways of achieving this - > 1. Implement functions that emit the target code - that is, when the > Haskell code is compiled and run, the target code is emitted > 2. Modify the Haskell compiler's back end to emit the code - that is when > the Haskell code is compiled the target code is emitted > > I am not sure if there are more ways (hybrid perhaps) ... > > My question is, when would I chose one approach over the other? > > Regards, > Kashyap > > > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/60c1c2b8/attachment.html From ck_kashyap at yahoo.com Mon Jan 4 12:47:02 2010 From: ck_kashyap at yahoo.com (CK Kashyap) Date: Mon Jan 4 12:20:06 2010 Subject: [Haskell-cafe] A question on DSL's In-Reply-To: References: <218657.56688.qm@web112514.mail.gq1.yahoo.com> Message-ID: <141272.82203.qm@web112509.mail.gq1.yahoo.com> Thanks Jasper ... Thanks John, While most of the use case I had in mind seems to fit the EDSL description, I had some in the proper DSL category as well... So, my prejudice had been towards option one - and I was unable to visualize a situation where option 1 would not work - or become too problematic or option 2 becomes too simple. I was just thinking of implementing an OS kernel (monolithic to start with) using Haskell - via option 1. Then again, if I understand right, House was done by modifying GHC ... So, I guess it'll help me if I can see some example situations where modifying GHC's back end would be a better/only option. The main reason I am asking this is to make sure I don't miss out some obvious pitfall in my OS implementation via option 1. Regards, Kashyap > >From: John Van Enk >To: CK Kashyap >Cc: haskell-cafe@haskell.org >Sent: Mon, January 4, 2010 10:51:06 PM >Subject: Re: [Haskell-cafe] A question on DSL's > > >To start with, can you clarify that you are looking for an Embedded DSL (sometimes called Light Weight DSL)? > > >A _proper_ DSL has its own interpreter/compiler where an EDSL/LwDSL leverages the compiler of a host language (in this case, Haskell). > > >Assuming you're referring to an EDSL, I'll respond. :) > >I don't think the second option is ever used. Modifying the compiler backend doesn't seem to make a lot of sense to me. I'm not aware of any circumstance where this has been done. > > >Your first option is closer. Generally, when emitting some sort of target code from a large EDSL, you'll have two stages. Your first takes the embedded syntax of your EDSL and converts it to an Abstract Syntax Tree. Your second stage accepts the AST as input and emits target code. > > >Take Tom Hawkins' Atom EDSL as an example. When we write Atom code, we're building up an AST. After the AST is built up, the "compile" function converts the AST to C code. > > >For smaller EDSLs, it's more than possible to have the functions themselves emit the code we're after (rather than relying on an AST and compile function). > > >Is this what you're looking for? > > >/jve > > >On Mon, Jan 4, 2010 at 12:14 PM, CK Kashyap wrote: > >>>Hi, >>>>I am not sure if I'm using DSL in the right context here but I am referring to those solutions that allow us to write code in Haskell and generate a target code source code of another language or even object code for that matter. I am aware of two ways of achieving this - >>>> >>1. Implement functions that emit the target code - that is, when the Haskell code is compiled and run, the target code is emitted >>>>2. Modify the Haskell compiler's back end to emit the code - that is when the Haskell code is compiled the target code is emitted >> >>>>I am not sure if there are more ways (hybrid perhaps) ... >> >>>>My question is, when would I chose one approach over the other? >> >>>>Regards, >>>>Kashyap >> >> >> >> >> >>>>_______________________________________________ >>>>Haskell-Cafe mailing list >>Haskell-Cafe@haskell.org >>http://www.haskell.org/mailman/listinfo/haskell-cafe >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/b6cadc17/attachment-0001.html From brandon.m.simmons at gmail.com Mon Jan 4 12:57:38 2010 From: brandon.m.simmons at gmail.com (Brandon Simmons) Date: Mon Jan 4 12:30:59 2010 Subject: [Haskell-cafe] Why can't we make an instance declaration on a type synonym? In-Reply-To: <20100104171138.GA12245@rwbarton.mit.edu> References: <303b11b2-337b-4115-86ea-dfee96f329c2@3g2000vbp.googlegroups.com> <87tyv3fy9d.fsf@gmail.com> <20100104171138.GA12245@rwbarton.mit.edu> Message-ID: On Mon, Jan 4, 2010 at 12:11 PM, Reid Barton wrote: > On Mon, Jan 04, 2010 at 11:50:57AM -0500, Brandon Simmons wrote: >> On Sun, Jan 3, 2010 at 2:22 AM, Ivan Lazar Miljenovic >> wrote: >> > jberryman writes: >> > >> >> This may be a dumb question, but why can we not declare a Monad >> >> instance of a type synonym? This question came to me while working >> >> with the State monad recently and feeling that the requirement that we >> >> wrap our functions in the State constructor is a bit... kludgy. >> >> >> > >> > Because type defines an _alias_. ?If you define "type Foo = Maybe Int", >> > then everywhere you have a "Foo" the compiler should be able to replace >> > it with "Maybe Int". >> > >> > As such, if you have a custom instance on your type synonym (say a >> > custom Show instance for Foo), then which instance will the compiler >> > use? >> >> >> Thanks. I guess what I'm really asking is if there is any way to >> redefine the monad instance for (->) such that we can have a State >> monad without the data constructor wrapper. > > It would be a nightmare for type inference. ?Consider: > > return "foo" :: String -> (String, String) ? ?-- \x -> ("foo", x) > > which would be valid in a language where we can do what you suggest. > `return` has type `a -> m a`, so `a` must be `String`, and now we need > to unify `String -> m String` with `String -> String -> (String, String)`. > In Haskell, these just don't unify because there are no type-level lambdas. > Even if there were, how is the typechecker supposed to know that we want > the solution `m a = String -> (a, String)` and not `m a = a -> (a, a)` > or many other possibilites? > > The purpose of the newtype State is to have something to unify `m` with: > > return "foo" :: State String String > > We can unify `String -> m String` with `String -> State String String` > by setting `m` to `State String`. > > Regards, > Reid Barton > Thanks, that makes a lot of sense. Brandon From will_n48 at yahoo.com Mon Jan 4 13:16:32 2010 From: will_n48 at yahoo.com (Will Ness) Date: Mon Jan 4 12:49:57 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001040129.22689.daniel.is.fischer@web.de> <201001041802.35854.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > > Am Montag 04 Januar 2010 13:25:47 schrieb Will Ness: > > > Euler's sieve is > > > > sieve (p:ps) xs = h ++ sieve ps (t `minus` map (p*) [p,p+2..]) > > where (h,t) = span (< p*p) xs > > Not quite. That's a variant of the postponed filters, it crosses off e.g. > 45 twice, once as 3*15 and once as 5*9 (okay, it has already been removed by > the first, so let's say 45 appears in two lists of numbers to be removed if > present). there won't be any such. whatever is removed first, is just skipped second (and third, etc). 45 does appear twice on the two multiples ists (3- and 5-). But it is "removed" by first, and skipped by second. And there's no removal here in the first place. There is no pre-filled storage. All there is, is some lists comparison, and lists are just generators (I so keep hoping). I don't see any problem here. As Melissa (and yourself, I think) have shown, double hits on multiples are few and far between. Also, it uses no filters, i.e. no individual number divisibility testing. The "filters" refers first of all to testing an individual number to decide whether to keep it in or not. Euler's sieve removes multiples in advance, so there's no testing and no filtering, only comparison. It follows the _Postponed_ Filter's framework in postponing the action until the right moment; the action itself is two lists comparison and skipping of the equals (i.e. the "minus" action). > Euler's sieve is never attempting to remove a number more than once, that's How's that possible? On wikipedia is says, it removes multiples of 3; then multiples of 5; etc. So it just looks for each number it is removing, if it is there, and if so, removes it. I would argue that looking whether to remove or not, is part of attempting to remove. It can't have foresight, right? > the outstanding feature of it. Unfortunately, that also makes it hard to > implement efficiently. The problem is that you can't forget the primes > between p and p^2, you must remember them for the removal of multiples of p > later on. you're right, every formulation of these algorithms is always done in the imperative, mutable-storage setting. They always speak of "removing" numbers etc. The more pressing problem with that code is its linear structure of course which gets addressed by the tree-folding merge etc. > An (inefficient but faithful) implementation would be > > euler ks@(p:rs) = p : euler (rs `minus` map (*p) ks) I think it does exactly the same thing, computationally, except it does so, again, _prematurely_ exactly in Turner's sieve's fashion - for each prime found, _as_ _soon_ as it is found. If it is faithful, so is my code. :) > Its performance is really horrible though. makes sense, as for Turner's. See, the _when_ thing really helps to see what's going on here. > A much better implementation is > > primes = 2:3:euler hprs [] (scanl (+) 5 (cycle [2,4])) > where > hprs = 5:drop 3 primes > euler (p:ps) acc cs = h ++ euler ps (tail (acc ++ h)) (t `minus` comps) > where > (h,t) = span (< p*p) cs > comps = map (*p) (acc ++ cs) this look like {2,3} wheel reimplemented and inlined. No point in improving anything until the linear structure isn't turned into a tree. > > > > > > To be fair, she writes: > > > > > > ... (This optimization does not a?ect the time complexity of the sieve, > > > however, so its absence from _the_ _code_ in Section 1 > > > is _not_ our cause for worry.)" > > > > A-HA! > > > > But its absense from _*that*_ _*code*_ WAS the *major* cause for worry, as > > dealing with it worked wonders on its complexity and constant factors. > > I think you're overinterpreting it. I might have. I don't mean to neatpick, honest. It's just how it looked to me: "Turner's? - bad. Squares? - won't help, it's a _minor_ thing; don't even go there!" etc. As I've said, geniuses leap, and fly. I just wanted to _walk_ down that road, not skipping any steps. And it turned out, the very first step _really_ pays up _big_. So big in fact, it might be argued that any subsequent improvement is just an advanced optimization, in terms of presenting an introductory code which isn't horribly inefficient and yet is short and clear. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From will_n48 at yahoo.com Mon Jan 4 13:25:24 2010 From: will_n48 at yahoo.com (Will Ness) Date: Mon Jan 4 12:58:55 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001030508.46357.daniel.is.fischer@web.de> <201001040129.22689.daniel.is.fischer@web.de> <4B421A56.5050707@chalmers.se> Message-ID: Emil Axelsson chalmers.se> writes: > > > For me, a real smart compiler is one that would take in e.g. (sum $ > > take n $ > > cycle $ [1..m]) and spill out a straight up math formula, inside a few ifs > > maybe (just an aside). > > (Also an aside, I couldn't resist...) > > Then I'm sure you'd say that Feldspar [1] has a smart compiler :) but it didn't produce f n m = if n < m then n*(n+1)/2 else let (q,r)=quotRem n m in q*(m*(m+1)/2) + r*(r+1)/2 :) > The above expression written in Feldspar and the resulting C code can be > found here: > > http://hpaste.org/fastcgi/hpaste.fcgi/view?id=15592#a15593 > > > / Emil > > [1] http://feldspar.sourceforge.net/ > From tomahawkins at gmail.com Mon Jan 4 14:16:04 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Mon Jan 4 13:49:05 2010 Subject: [Haskell-cafe] A question on DSL's In-Reply-To: References: <218657.56688.qm@web112514.mail.gq1.yahoo.com> Message-ID: <594c1e831001041116k466407f5n7841b5a7a22784c3@mail.gmail.com> One argument for option 2 is to carry forward datatypes to the target language. For example, if you want to describe a state machine with the state as a type: data StopLightState = Red | Yellow | Green With option 1, values of type StopLightState will be resolved at compile-time, not run-time. (yes, there's tricks to get around this, but they're ugly) I experimented briefly with option 2 using YHC, but quickly threw in the cards for option 1. It would be nice if GHC's internals were more accessible for this type of work. On Mon, Jan 4, 2010 at 6:20 PM, Jasper Van der Jeugt wrote: > Hello, > I see no real reason to use the second approach, unless you're doing > something tremendously new and big. Besides, the first solution is much > easier and will be easier to maintain (in case the back end changes). > Kind regards, > Jasper Van der Jeugt > > On Mon, Jan 4, 2010 at 6:14 PM, CK Kashyap wrote: >> >> Hi, >> I am not sure if I'm using DSL in the right context here but I am >> referring to those solutions that allow us to write code in Haskell and >> generate a target code source code of another language or even object code >> for that matter. I am aware of two ways of achieving this - >> 1. Implement functions that emit the target code - that is, when the >> Haskell code is compiled and run, the target code is emitted >> 2. Modify the Haskell compiler's back end to emit the code - that is when >> the Haskell code is compiled the target code is emitted >> >> I am not sure if there are more ways (hybrid perhaps) ... >> >> My question is, ?when would I chose one approach over the other? >> >> Regards, >> Kashyap >> >> >> >> >> >> _______________________________________________ >> 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 > > From gue.schmidt at web.de Mon Jan 4 14:23:11 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Mon Jan 4 13:56:36 2010 Subject: [Haskell-cafe] HXT XSLT example? Message-ID: <4B42401F.4000400@web.de> Hi, is there a simple example for XSLT via HXT? You know something like take this xml file, apply this xsl file, dump to stdout. G?nther From uzytkownik2 at gmail.com Mon Jan 4 15:13:23 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Mon Jan 4 14:46:47 2010 Subject: [Haskell-cafe] Re: Re: Data.Ring -- Pre-announce In-Reply-To: <7ca3f0161001040617w1a67529crb513c4c926564c6a@mail.gmail.com> References: <1262613072.13413.64.camel@picard> <7ca3f0161001040617w1a67529crb513c4c926564c6a@mail.gmail.com> Message-ID: <1262636003.13413.74.camel@picard> On Mon, 2010-01-04 at 07:17 -0700, Luke Palmer wrote: > On Mon, Jan 4, 2010 at 6:51 AM, Maciej Piechotka wrote: > > About comonad - not exactly as every comonad is copointed and the only > > possible way is extract Empty = _|_ > > I think this module could be cleaned up by disallowing empty lists. > You have this nice semantic property that "every clist has a focus", > but when you add empty you have to add "unless it's empty". focus > returns a Maybe, isEmpty is necessary. > > I mean, it could be that your use case requires empty clists and would > be uglier without empty, but think about it. I find in Haskell that > simplicity breeds simplicity; i.e. I'm willing to wager that whatever > algorithm you are using clist for will actually be cleaner if you got > rid of empty and modify the algorithm accordingly. We shall see > though... > > Luke However then we lost the monoid (ok. I haven't send patch but please accept[1]) along with alternative/monad plus - which is much more popular, standard and useful then Copointed/Comonad. Additionally it would introduce: fromList [] = _|_ Is is somehow similar to 0 \in N - sometimes it is better to include it sometimes to not include it. Regards [1] > instance Monoid CList where > mempty = Empry > mappend = mplus From ndmitchell at gmail.com Mon Jan 4 15:14:51 2010 From: ndmitchell at gmail.com (Neil Mitchell) Date: Mon Jan 4 14:47:52 2010 Subject: [Haskell-cafe] Significant slow-down in parallel code? In-Reply-To: References: Message-ID: <404396ef1001041214t1ef9b497qdf598f6cb8686fd2@mail.gmail.com> Hi Jamie, First question, what version of GHC are you using? There are significant performance improvements to parallel code in GHC 6.12, so it's worth an upgrade. Once you've upgraded you might want to try out threadscope which is designed to help track down these sorts of problems. If you are using 6.10, I recommend turning off parallel garbage collection with the RTS flags (see the manual) as that can cause slowdowns. Thanks, Neil 2010/1/4 Jamie Morgenstern : > Hello; > > ?I have a piece of code in which I employ the `par` construct to add some implicit parallelism > to a theorem prover. However, when running the *same* code with > > +RTS -N1 > +RTS -N5 > +RTS -N10 > > I see a huge slowdown (a factor of 50 with 5 processes and a factor of 100 for 10 on an 8-core machine). > > Very little time is being spent using the garbage collector. Any suggestions? > > Thanks, > -Jamie > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From lrpalmer at gmail.com Mon Jan 4 15:41:37 2010 From: lrpalmer at gmail.com (Luke Palmer) Date: Mon Jan 4 15:14:38 2010 Subject: [Haskell-cafe] A question on DSL's In-Reply-To: <594c1e831001041116k466407f5n7841b5a7a22784c3@mail.gmail.com> References: <218657.56688.qm@web112514.mail.gq1.yahoo.com> <594c1e831001041116k466407f5n7841b5a7a22784c3@mail.gmail.com> Message-ID: <7ca3f0161001041241g48e61868hc641fc4aaf5c568@mail.gmail.com> On Mon, Jan 4, 2010 at 12:16 PM, Tom Hawkins wrote: > One argument for option 2 is to carry forward datatypes to the target > language. ?For example, if you want to describe a state machine with > the state as a type: What do you mean "carry forward". Can you elaborate on your simple example? What about it requires option 2? > > data StopLightState = Red | Yellow | Green > > With option 1, values of type StopLightState will be resolved at > compile-time, not run-time. ?(yes, there's tricks to get around this, > but they're ugly) > > I experimented briefly with option 2 using YHC, but quickly threw in > the cards for option 1. > > It would be nice if GHC's internals were more accessible for this type of work. > > > > On Mon, Jan 4, 2010 at 6:20 PM, Jasper Van der Jeugt > wrote: >> Hello, >> I see no real reason to use the second approach, unless you're doing >> something tremendously new and big. Besides, the first solution is much >> easier and will be easier to maintain (in case the back end changes). >> Kind regards, >> Jasper Van der Jeugt >> >> On Mon, Jan 4, 2010 at 6:14 PM, CK Kashyap wrote: >>> >>> Hi, >>> I am not sure if I'm using DSL in the right context here but I am >>> referring to those solutions that allow us to write code in Haskell and >>> generate a target code source code of another language or even object code >>> for that matter. I am aware of two ways of achieving this - >>> 1. Implement functions that emit the target code - that is, when the >>> Haskell code is compiled and run, the target code is emitted >>> 2. Modify the Haskell compiler's back end to emit the code - that is when >>> the Haskell code is compiled the target code is emitted >>> >>> I am not sure if there are more ways (hybrid perhaps) ... >>> >>> My question is, ?when would I chose one approach over the other? >>> >>> Regards, >>> Kashyap >>> >>> >>> >>> >>> >>> _______________________________________________ >>> 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 mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From daniel.is.fischer at web.de Mon Jan 4 16:25:28 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Jan 4 16:00:08 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001040129.22689.daniel.is.fischer@web.de> Message-ID: <201001042225.29189.daniel.is.fischer@web.de> Am Montag 04 Januar 2010 18:08:42 schrieb Will Ness: > Daniel Fischer web.de> writes: > > Am Sonntag 03 Januar 2010 09:54:37 schrieb Will Ness: > > > The quesion of a memory blowup with the treefolding merge still > > > remains. For some reason using its second copy for a feeder doesn't > > > reduce the memory (as reported by standalone compiled program, GHCi > > > reported values are useless) - it causes it to increase twice..... > > > > I have a partial solution. The big problem is that the feeder holds on to > > the beginning of comps while the main runner holds on to a later part. > > Thus the entire segment between these two points must be in memory. > > > > So have two lists of composites (yeah, you know that, but it didn't work > > so far). > > > > But you have to force the compiler not to share them: enter -fno-cse. > > The attached code does that (I've also expanded the wheel), it reduces > > the memory requirements much (a small part is due to the larger wheel, a > > factor of ~5 due to the non-sharing). > > I don't understand. What is there to be shared? Each multiples list is > consumed only at one point; there's nothing to be shared. Do you mean the > compiler still hangs on to them? If so, why?? Okay, let's look at the code. Your Primes.hs says {-# SPECIALIZE primes :: () -> [Int] #-} {-# SPECIALIZE primes :: () -> [Integer] #-} primes :: Integral a => () -> [a] primes () = 2:3:5:7:primes' ?? where ??? primes' = [11,13] ++ drop 2 (rollFrom 11) `minus` comps ??? (comps,_)? = tfold mergeSP (pairwise mergeSP mults) ??? mults?? = map (\p-> fromList $ map (p*) $ rollFrom p) $ primes' ??? fromList (x:xs) = ([x],xs) What's going on evaluating primes'? First, we know primes' is 11 : 13 : more. Then we can start looking at 'more'. For that, we need rollFrom 11 `minus` comps. rollFrom 11 is easy. What about comps? We need the start of primes' for that. Cool, we already know the first two elements, start tfolding, we know comps is 121:143:169:notYetKnown So the rollFrom 11 produces happily, minus doesn't veto anything for a while, then says no to 121, 143, 169. Now rollFrom 11 says "look at 173". Fine, what's next in comps? To find that out, we need the multiples of 17 and 19 (and 23 and 29, but those can still be deferred for a while). That gives ([289,323,361],whatever), then the mergeSP with the merged multiples of 11 and 13 produces (187:209:221:...) for notYetKnown. Everything's going on fine, but the problem is, when primes' produces primes in the region of n, it needs the comps in that region. Those contain the multiples of primes in the region of sqrt n, thus the small primes cannot yet be released. Bottom line, to produce p, all the primes from about sqrt p to p must be in memory. Oops. Enter the feeder. Say primes :: Integral a => () -> [a] primes () = 2:3:5:7:primes' ?? where ??? primes' = (rollFrom 11) `minus` comps ??? primes'' = [11,13] ++ drop 2 (rollFrom 11) `minus` comps ??? (comps,_)? = tfold mergeSP (pairwise mergeSP mults) ??? mults?? = map (\p-> fromList $ map (p*) $ rollFrom p) $ primes'' ??? fromList (x:xs) = ([x],xs) Now primes'', the feeder of composites advances much more slowly and for primes' to produce p, primes'' must produce the next prime after sqrt p, thus holds on to all primes between sqrt (sqrt p) and sqrt p - not much of a problem. primes' doesn't hold on to smaller primes, great. But! primes' needs the part of comps around p. primes'' needs the part of comps around sqrt p. That means we must keep the part of the list of composites from sqrt p to p in memory. Even after removing the multiples of 2, 3, 5 and 7, it doesn't take long until there are far more composites between sqrt p and p than primes. Double oops. So we must make sure that the list of composites that primes' consumes is not the same as that which primes'' consumes. You can try primes :: Integral a => () -> [a] primes () = 2:3:5:7:primes' ?? where ??? primes' = (rollFrom 11) `minus` comps ??? primes'' = [11,13] ++ drop 2 (rollFrom 11) `minus` comps2 ??? (comps,_)? = tfold mergeSP (pairwise mergeSP mults) ??? mults?? = map (\p-> fromList $ map (p*) $ rollFrom p) $ primes'' ??? (comps2,_)? = tfold mergeSP (pairwise mergeSP mults2) ??? mults2?? = map (\p-> fromList $ map (p*) $ rollFrom p) $ primes'' ??? fromList (x:xs) = ([x],xs) If you compile without optimisations, it works. It just is rather slow. Unfortunately, the optimiser sees that comps2 and comps are the same and thinks, "why should I produce it twice if they're the same?" - whoops, back to square two. Tell the compiler that you do *not* want it shared via -fno-cse and it isn't shared, you really have two distinct lists of composites, happiness ensues - almost. > > I used the switch; it didn't help at all. The only thing I can see is > different is that all my interim data which I named with inner vars you > moved out to the top level as functions. Is that what did the trick? Not really, the above works too, with inner local bindings. If you introduce separate names for the lists of multiples and for the lists of composites, -fno-cse ought to do the trick. Maybe it would even work with one list of multiples. Can I see what you did that -fno-cse didn't manage to separate the lists? > What would be the reason to hang on to the already consumed data that is > inaccessible to any active consumer? No reason. And that's not what happened. We always had two consumers gnawing on the same list, one proceeding fast, the other slow. The part the slow consumer was done with could be dropped (and probably was) - the part between the slow and the fast: Not. > Why not make the forgetful behaviour the norm - > especially where remembering is pointless?? It is. > > > It still uses much more memory than the PQ, and while the PQ's memory > > requirements grow very slowly, the tree-fold merge's still grow rather > > fast (don't go much beyond the 10,000,000th prime), I'm not sure why. > > You did it! It's now 7M for 1,000,000th prime, instead of 52M before. > Making the pattern lazy in mergeSP was probably an important fix too. :) Did I forget to remove them? (checks) Yes. No, I put them in without thinking, then realised "Hey, stupid, where-bindings *are* already lazy!" But somehow I have forgotten to remove them. Since let- and where-bindings are lazy, all those could do is make the compiler say "Sheesh". > > Unfortunately it grows, as you've said - 23MB for 2 mln. :| And I've found out why. Change the definition of tfold to tfold f (a: ~(b: ~(c:xs))) ???????????????????? = (a `f` (b `f` c)) `f` tfold f xs and memory stays low (things are going much slower, though). By always doing a (pairwise f xs), you're getting the composites faster, but at the expense of pretty huge thunks (I think, if the merging isn't lazy enough, you get some pretty long lists). You can make a compromise by using the above tfold (which is no longer a tree-fold) and grouping (and merging) the multiples in a slower-growing manner, e.g. compos ps = fst (tfold mergeSP $ nwise 1 mergeSP (pairwise mergeSP (multip ps))) tfold f (a: ~(b: ~(c:xs))) ???????????????????? = (a `f` (b `f` c)) `f` tfold f xs nwise k f xs = let (ys,zs) = splitAt k xs in rfold f ys : nwise (k+1) f zs rfold f [x] = x rfold f (x:xs) = x `f` rfold f xs memory still grows, but much slower, in my tests, due to the much smaller GC time, it's a bit faster than the version with the original tfold. > > PQ stays at just 2MB. > No doubling the size of merge trees, no big thunks, just occasionally add a filter to the PQ. Memory requirements are O(pi(sqrt n)) [off the top of my head, may be wrong again], -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/bec158ae/attachment.html From paul.brauner at loria.fr Mon Jan 4 17:14:53 2010 From: paul.brauner at loria.fr (Paul Brauner) Date: Mon Jan 4 16:47:55 2010 Subject: [Haskell-cafe] lawless instances of Functor Message-ID: <20100104221453.GC19757@inria.fr> Hi, I'm trying to get a deep feeling of Functors (and then pointed Functors, Applicative Functors, etc.). To this end, I try to find lawless instances of Functor that satisfy one law but not the other. I've found one instance that satisfies fmap (f.g) = fmap f . fmap g but not fmap id = id: data Foo a = A | B instance Functor Foo where fmap f A = B fmap f B = B -- violates law 1 fmap id A = B -- respects law 2 fmap (f . g) A = (fmap f . fmap g) A = B fmap (f . g) B = (fmap f . fmap g) B = B But I can't come up with an example that satifies law 1 and not law 2. I'm beginning to think this isn't possible but I didn't read anything saying so, neither do I manage to prove it. I'm sure someone knows :) Paul From hjgtuyl at chello.nl Mon Jan 4 17:20:59 2010 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Mon Jan 4 16:54:02 2010 Subject: [Haskell-cafe] curl on windows? In-Reply-To: <4B420F80.8070706@web.de> References: <4B420F80.8070706@web.de> Message-ID: On Mon, 04 Jan 2010 16:55:44 +0100, G?nther Schmidt wrote: > Hi, > > how can I install curl on windows (XP)? Download the C code for cURL from: http://curl.haxx.se/download.html Unpack the source; to avoid problems with scripts, use paths without spaces. See the instructions at: http://www.haskell.org/haskellwiki/Windows#Tools_for_compilation Compile with: make Finally, give command: cabal install curl -- Met vriendelijke groet, Henk-Jan van Tuyl -- http://Van.Tuyl.eu/ http://members.chello.nl/hjgtuyl/tourdemonad.html -- From sschuldenzucker at uni-bonn.de Mon Jan 4 17:49:33 2010 From: sschuldenzucker at uni-bonn.de (Steffen Schuldenzucker) Date: Mon Jan 4 17:22:49 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <20100104221453.GC19757@inria.fr> References: <20100104221453.GC19757@inria.fr> Message-ID: <4B42707D.5010009@uni-bonn.de> Hi Paul, Paul Brauner wrote: > Hi, > > I'm trying to get a deep feeling of Functors (and then pointed Functors, > Applicative Functors, etc.). To this end, I try to find lawless > instances of Functor that satisfy one law but not the other. > > I've found one instance that satisfies fmap (f.g) = fmap f . fmap g > but not fmap id = id: > [...] > But I can't come up with an example that satifies law 1 and not law 2. > I'm beginning to think this isn't possible but I didn't read anything > saying so, neither do I manage to prove it. > > I'm sure someone knows :) data Foo a = Foo a instance Functor Foo where fmap f (Foo x) = Foo . f . f $ x Then: fmap id (Foo x) == Foo . id . id $ x == Foo x fmap (f . g) (Foo x) == Foo . f . g . f . g $ x fmap f . fmap g $ (Foo x) == Foo . f . f . g . g $ x Now consider Foo Int and fmap ((+1) . (*3)) (Foo x) == Foo $ (x * 3 + 1) * 3 + 1 == Foo $ x * 9 + 4 fmap (+1) . fmap (*3) $ (Foo x) == Foo $ x * 3 * 3 + 1 + 1 == Foo $ x * 9 + 2 -- Steffen From derek.a.elkins at gmail.com Mon Jan 4 17:52:45 2010 From: derek.a.elkins at gmail.com (Derek Elkins) Date: Mon Jan 4 17:25:45 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <4B42707D.5010009@uni-bonn.de> References: <20100104221453.GC19757@inria.fr> <4B42707D.5010009@uni-bonn.de> Message-ID: <61f84eff1001041452x4a7fad75j2ccb7a69a9fc7eec@mail.gmail.com> On Tue, Jan 5, 2010 at 7:49 AM, Steffen Schuldenzucker wrote: > Hi Paul, > > Paul Brauner wrote: >> Hi, >> >> I'm trying to get a deep feeling of Functors (and then pointed Functors, >> Applicative Functors, etc.). To this end, I try to find lawless >> instances of Functor that satisfy one law but not the other. >> >> I've found one instance that satisfies fmap (f.g) = fmap f . fmap g >> but not fmap id = id: >> [...] >> But I can't come up with an example that satifies law 1 and not law 2. >> I'm beginning to think this isn't possible but I didn't read anything >> saying so, neither do I manage to prove it. >> >> I'm sure someone knows :) > > data Foo a = Foo a > > instance Functor Foo where > ? ?fmap f (Foo x) = Foo . f . f $ x And what is the type of f here? From jochem at functor.nl Mon Jan 4 17:53:16 2010 From: jochem at functor.nl (Jochem Berndsen) Date: Mon Jan 4 17:26:18 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <4B42707D.5010009@uni-bonn.de> References: <20100104221453.GC19757@inria.fr> <4B42707D.5010009@uni-bonn.de> Message-ID: <4B42715C.9010407@functor.nl> Steffen Schuldenzucker wrote: > data Foo a = Foo a > > instance Functor Foo where > fmap f (Foo x) = Foo . f . f $ x I think this doesn't typecheck. Cheers, Jochem -- Jochem Berndsen | jochem@functor.nl | jochem@????.com From derek.a.elkins at gmail.com Mon Jan 4 18:01:46 2010 From: derek.a.elkins at gmail.com (Derek Elkins) Date: Mon Jan 4 17:34:46 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <20100104221453.GC19757@inria.fr> References: <20100104221453.GC19757@inria.fr> Message-ID: <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> On Tue, Jan 5, 2010 at 7:14 AM, Paul Brauner wrote: > Hi, > > I'm trying to get a deep feeling of Functors (and then pointed Functors, > Applicative Functors, etc.). To this end, I try to find lawless > instances of Functor that satisfy one law but not the other. > > I've found one instance that satisfies fmap (f.g) = fmap f . fmap g > but not fmap id = id: > > data Foo a = A | B > > instance Functor Foo where > ?fmap f A = B > ?fmap f B = B > > -- violates law 1 > fmap id A = B > > -- respects law 2 > fmap (f . g) A = (fmap f . fmap g) A = B > fmap (f . g) B = (fmap f . fmap g) B = B > > But I can't come up with an example that satifies law 1 and not law 2. > I'm beginning to think this isn't possible but I didn't read anything > saying so, neither do I manage to prove it. > > I'm sure someone knows :) Ignoring bottoms the free theorem for fmap can be written: If h . p = q . g then fmap h . fmap p = fmap q . fmap g Setting p = id gives h . id = h = q . g && fmap h . fmap id = fmap q . fmap g Using fmap id = id and h = q . g we get, fmap h . fmap id = fmap h . id = fmap h = fmap (q . g) = fmap q . fmap g So without doing funky stuff involving bottoms and/or seq, I believe that fmap id = id implies the other functor law (in this case, not in the case of the general categorical notion of functor.) From tomahawkins at gmail.com Mon Jan 4 18:14:27 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Mon Jan 4 17:47:31 2010 Subject: [Haskell-cafe] A question on DSL's In-Reply-To: <7ca3f0161001041241g48e61868hc641fc4aaf5c568@mail.gmail.com> References: <218657.56688.qm@web112514.mail.gq1.yahoo.com> <594c1e831001041116k466407f5n7841b5a7a22784c3@mail.gmail.com> <7ca3f0161001041241g48e61868hc641fc4aaf5c568@mail.gmail.com> Message-ID: <594c1e831001041514u217a828fs53fe1d68f7e1c092@mail.gmail.com> On Mon, Jan 4, 2010 at 9:41 PM, Luke Palmer wrote: > On Mon, Jan 4, 2010 at 12:16 PM, Tom Hawkins wrote: >> One argument for option 2 is to carry forward datatypes to the target >> language. ?For example, if you want to describe a state machine with >> the state as a type: > > What do you mean "carry forward". ?Can you elaborate on your simple > example? ?What about it requires option 2? Well in the case of Atom, it would be very convenient to write code like this: data StopLight = Red | Yellow | Green changeLight :: V StopLight -> Atom () changeLight light = light <== light' where light' = case value light of Red -> Green Yellow -> Red Green -> Yellow The problem is the case expression is evaluated at compile-time, when what we really want is to "carry forward" the case expression to the run-time environment (aka. the generated code). This example illustrates the use of a simple enumerated type. But full-blown algebraic data types would also be useful in the run-time. For example, a Maybe type could be used to represent a valid signal: Just validValue or Nothing if the signal is invalid. Of course this is not a limitation if the run-time and compile-time is the same environment, i.e. Haskell. However, if the target is a different language, such as C in the case of Atom, then the full power of algebraic data types are lost with light embedded domain specific languages. From derek.a.elkins at gmail.com Mon Jan 4 18:14:56 2010 From: derek.a.elkins at gmail.com (Derek Elkins) Date: Mon Jan 4 17:47:55 2010 Subject: [Haskell-cafe] Re: Re: Data.Ring -- Pre-announce In-Reply-To: <1262636003.13413.74.camel@picard> References: <1262613072.13413.64.camel@picard> <7ca3f0161001040617w1a67529crb513c4c926564c6a@mail.gmail.com> <1262636003.13413.74.camel@picard> Message-ID: <61f84eff1001041514y615828eied0b4f156af78543@mail.gmail.com> On Tue, Jan 5, 2010 at 5:13 AM, Maciej Piechotka wrote: > On Mon, 2010-01-04 at 07:17 -0700, Luke Palmer wrote: >> On Mon, Jan 4, 2010 at 6:51 AM, Maciej Piechotka wrote: >> > About comonad - not exactly as every comonad is copointed and the only >> > possible way is extract Empty = _|_ >> >> I think this module could be cleaned up by disallowing empty lists. >> You have this nice semantic property that "every clist has a focus", >> but when you add empty you have to add "unless it's empty". ?focus >> returns a Maybe, isEmpty is necessary. >> >> I mean, it could be that your use case requires empty clists and would >> be uglier without empty, but think about it. ?I find in Haskell that >> simplicity breeds simplicity; i.e. I'm willing to wager that whatever >> algorithm you are using clist for will actually be cleaner if you got >> rid of empty and modify the algorithm accordingly. ?We shall see >> though... >> >> Luke > > However then we lost the monoid (ok. I haven't send patch but please > accept[1]) along with alternative/monad plus - which is much more > popular, standard and useful then Copointed/Comonad. > > Additionally it would introduce: > fromList [] = _|_ This isn't a big deal, it just means fromList is not appropriate (which it is not, it should be fromNonEmptyList in this case. We can of course, also, simply return Maybe (NonEmptyCList a) which works out. > Is is somehow similar to 0 \in N - sometimes it is better to include it > sometimes to not include it. > > Regards > > [1] >> instance Monoid CList where >> ? mempty = Empry >> ? mappend = mplus This is a bigger issue, however, given a type with a associative binary operation, a semigroup, we can complete it to a monoid using a Maybe-like type constructor to formally attach a unit. data AddUnit a = Unit | Value a class SemiGroup a where op :: a -> a -> a -- associative instance (SemiGroup a) => Monoid (AddUnit a) where mempty = Unit Unit `mappend` y = y x `mappend` Unit = x Val x `mappend` Val y = Val (x `op` y) We then have, type CList a = AddUnit (NonEmptyCList a) From dpiponi at gmail.com Mon Jan 4 18:15:20 2010 From: dpiponi at gmail.com (Dan Piponi) Date: Mon Jan 4 17:48:25 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> References: <20100104221453.GC19757@inria.fr> <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> Message-ID: <625b74081001041515u4c00f8fei4a2f6c8dea48e70a@mail.gmail.com> On Mon, Jan 4, 2010 at 3:01 PM, Derek Elkins wrote: > Ignoring bottoms the free theorem for fmap can be written: > > If h . p = q . g then fmap h . fmap p = fmap q . fmap g When I play with http://haskell.as9x.info/ft.html I get examples that look more like: If fmap' has the same signature as the usual fmap for a type and h . p = q . g then fmap h . fmap' p = fmap' q . fmap g >From which it follows that if fmap' id = id then fmap' is fmap. But I don't know how to prove that uniformly for all types, just the ones I generated free theorems for. -- Dan From byorgey at seas.upenn.edu Mon Jan 4 18:22:48 2010 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Mon Jan 4 17:55:47 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <4B42707D.5010009@uni-bonn.de> References: <20100104221453.GC19757@inria.fr> <4B42707D.5010009@uni-bonn.de> Message-ID: <20100104232248.GA6757@seas.upenn.edu> On Mon, Jan 04, 2010 at 11:49:33PM +0100, Steffen Schuldenzucker wrote: > > data Foo a = Foo a > > instance Functor Foo where > fmap f (Foo x) = Foo . f . f $ x > > Then: > > fmap id (Foo x) == Foo . id . id $ x == Foo x > > fmap (f . g) (Foo x) == Foo . f . g . f . g $ x > fmap f . fmap g $ (Foo x) == Foo . f . f . g . g $ x > > Now consider Foo Int and > > fmap ((+1) . (*3)) (Foo x) == Foo $ (x * 3 + 1) * 3 + 1 > == Foo $ x * 9 + 4 > fmap (+1) . fmap (*3) $ (Foo x) == Foo $ x * 3 * 3 + 1 + 1 > == Foo $ x * 9 + 2 As others have pointed out, this doesn't typecheck; but what it DOES show is that if we had a type class class Endofunctor a where efmap :: (a -> a) -> f a -> f a then it would be possible to write an instance for which efmap id = id but efmap (f . g) /= efmap f . efmap g. The difference is that with the normal Functor class, once you have applied your function f :: a -> b to get a b, you can't do anything else with it, since you don't know what b is. With the Endofunctor class, once you have applied f :: a -> a, you CAN do something with the result: namely, apply f again. -Brent From derek.a.elkins at gmail.com Mon Jan 4 18:26:41 2010 From: derek.a.elkins at gmail.com (Derek Elkins) Date: Mon Jan 4 17:59:43 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <625b74081001041515u4c00f8fei4a2f6c8dea48e70a@mail.gmail.com> References: <20100104221453.GC19757@inria.fr> <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> <625b74081001041515u4c00f8fei4a2f6c8dea48e70a@mail.gmail.com> Message-ID: <61f84eff1001041526q45e79130lcf6cf257257de4c7@mail.gmail.com> On Tue, Jan 5, 2010 at 8:15 AM, Dan Piponi wrote: > On Mon, Jan 4, 2010 at 3:01 PM, Derek Elkins wrote: > >> Ignoring bottoms the free theorem for fmap can be written: >> >> If h . p = q . g then fmap h . fmap p = fmap q . fmap g > > When I play with http://haskell.as9x.info/ft.html I get examples that > look more like: > > If fmap' has the same signature as the usual fmap for a type > > and h . p = q . g > > then fmap h . fmap' p = fmap' q . fmap g > > From which it follows that if fmap' id = id then fmap' is fmap. It should not be necessary to prove this as fmap has the appropriate type to be fmap' and therefore fmap' can simply be set to fmap. > But I don't know how to prove that uniformly for all types, just the > ones I generated free theorems for. Yes, I have the same problem. I generated a few examples using pretty much that site and generalized, but I haven't proven the general statement, though I'm pretty confident that it holds. Basically, I'm pretty sure the construction of that free theorem doesn't rely on any of the actual details of the type constructor and probably by using a higher-order notion of free theorem this could be formalized and then used to prove the above result. At this point, though, I haven't put much effort into proving that the free theorem holds uniformly (enough.) From derek.a.elkins at gmail.com Mon Jan 4 18:29:03 2010 From: derek.a.elkins at gmail.com (Derek Elkins) Date: Mon Jan 4 18:02:02 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <20100104232248.GA6757@seas.upenn.edu> References: <20100104221453.GC19757@inria.fr> <4B42707D.5010009@uni-bonn.de> <20100104232248.GA6757@seas.upenn.edu> Message-ID: <61f84eff1001041529h7e0295d1labc18141ba29a130@mail.gmail.com> On Tue, Jan 5, 2010 at 8:22 AM, Brent Yorgey wrote: > On Mon, Jan 04, 2010 at 11:49:33PM +0100, Steffen Schuldenzucker wrote: >> >> data Foo a = Foo a >> >> instance Functor Foo where >> ? ? fmap f (Foo x) = Foo . f . f $ x >> >> Then: >> >> fmap id (Foo x) == Foo . id . id $ x == Foo x >> >> fmap (f . g) (Foo x) ? ? ?== Foo . f . g . f . g $ x >> fmap f . fmap g $ (Foo x) == Foo . f . f . g . g $ x >> >> Now consider Foo Int and >> >> fmap ((+1) . (*3)) (Foo x) ? ? ?== Foo $ (x * 3 + 1) * 3 + 1 >> ? ? == Foo $ x * 9 + 4 >> fmap (+1) . fmap (*3) $ (Foo x) == Foo $ x * 3 * 3 + 1 + 1 >> ? ? == Foo $ x * 9 + 2 > > As others have pointed out, this doesn't typecheck; but what it DOES > show is that if we had a type class > > ?class Endofunctor a where > ? ?efmap :: (a -> a) -> f a -> f a As an aside, for clarity, this class does NOT correspond to the categorical notion of "endofunctor." I don't think any such identification was Brent's intent, I just want to avoid potential confusion. From daniel.is.fischer at web.de Mon Jan 4 18:33:03 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Jan 4 18:07:39 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001041802.35854.daniel.is.fischer@web.de> Message-ID: <201001050033.03373.daniel.is.fischer@web.de> Am Montag 04 Januar 2010 19:16:32 schrieb Will Ness: > Daniel Fischer web.de> writes: > > Am Montag 04 Januar 2010 13:25:47 schrieb Will Ness: > > > Euler's sieve is > > > > > > sieve (p:ps) xs = h ++ sieve ps (t `minus` map (p*) [p,p+2..]) > > > where (h,t) = span (< p*p) xs > > > > Not quite. That's a variant of the postponed filters, it crosses off e.g. > > 45 twice, once as 3*15 and once as 5*9 (okay, it has already been removed > > by the first, so let's say 45 appears in two lists of numbers to be > > removed if present). > > there won't be any such. whatever is removed first, is just skipped second > (and third, etc). 45 does appear twice on the two multiples ists (3- and > 5-). But it is "removed" by first, and skipped by second. And there's no > removal here in the first place. There is no pre-filled storage. All there > is, is some lists comparison, and lists are just generators (I so keep > hoping). ((45:(offer 47 when demanded)) `minus` (45:(next will be 51 when demanded))) `minus` (45: (next will be 55 when demanded)) So there are two attempts to tell the generator to not output 45. To the second, it answers "I already knew that", but the request is made nevertheless. Lists sometimes are data structures occupying physical storage (cons cell, point to value, pointer to next...), sometimes generators (when asked for the next value, I'll answer this). I say a value is removed from a list regardless of whether it takes relinking pointers in a list of cons cells or it involves telling the generator not to give out that value. I could also say 'eliminated'. There are two attempts to eliminate 45. > > I don't see any problem here. As Melissa (and yourself, I think) have > shown, double hits on multiples are few and far between. It's not a problem, it just means it's not Euler's sieve, because that attempts to eliminate each composite exactly once. > > Also, it uses no filters, i.e. no individual number divisibility testing. > The "filters" refers first of all to testing an individual number to decide > whether to keep it in or not. Umm, the postponed filters says keep everything until p^2, then eliminate (filter out, remove) multiples of p in the remainder, after that, pick next prime. That's precisely what the above does. It doesn't do the filtering out by divisibility testing but by minus (hence more efficiently). I would say that's a variant of the postponed filters. > Euler's sieve removes multiples in advance, > so there's no testing and no filtering, only comparison. It follows the > _Postponed_ Filter's framework in postponing the action until the right > moment; the action itself is two lists comparison and skipping of the > equals (i.e. the "minus" action). > > > Euler's sieve is never attempting to remove a number more than once, > > that's > > How's that possible? http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Euler.27s_Sieve "Euler in his Proof of the Euler product formula for the Riemann zeta function came up with a version of the sieve of Eratosthenes, *better in the sense that each number was eliminated exactly once*." C) The number after the previous prime is also a prime. *Multiply each number in the list starting from this prime by this prime and discard the products*. > On wikipedia is says, it removes multiples of 3; then > multiples of 5; etc. So it just looks for each number it is removing, if it > is there, and if so, removes it. I would argue that looking whether to > remove or not, is part of attempting to remove. It can't have foresight, > right? > But it has :) By only trying to eliminates products of the prime p currently under consideration *with numbers (>= p) which have not yet been eliminated from the list*, it is known in advance that all these products are still in the list. When p is under consideration, the list contains (apart from the primes < p) precisely the numbers whose smallest prime factor is >= p. > > the outstanding feature of it. Unfortunately, that also makes it hard to > > implement efficiently. The problem is that you can't forget the primes > > between p and p^2, you must remember them for the removal of multiples of > > p later on. > > you're right, every formulation of these algorithms is always done in the > imperative, mutable-storage setting. They always speak of "removing" > numbers etc. sed s/remove/eliminate/ ? > > The more pressing problem with that code is its linear structure of course > which gets addressed by the tree-folding merge etc. > Which unfortunately introduces its own space problem :( > > An (inefficient but faithful) implementation would be > > > > euler ks@(p:rs) = p : euler (rs `minus` map (*p) ks) > > I think it does exactly the same thing, computationally, No, in map (*p) ks, there are no numbers with a smaller prime factor than p, while in map (*p) [p, p+2 .. ] there are (for p > 3) > except it does so, > again, _prematurely_ exactly in Turner's sieve's fashion - for each prime > found, _as_ _soon_ as it is found. If it is faithful, so is my code. :) > It is faithful in that it tries to eliminate each composite exactly once. Try a different minus: xxs@(x:xs) `minus` yys@(y:ys) = case compare x y of LT -> x : xs `minus` yys EQ -> xs `minus` ys GT -> error ("trying to remove " ++ show y ++ " a second time") Your code is not. It is, however, much faster. > > Its performance is really horrible though. > > makes sense, as for Turner's. It's far worse than Turner's. The "map (*p) ks" holds on to things really really long. Measure it, just for teh lulz. > See, the _when_ thing really helps to see > what's going on here. > > > A much better implementation is > > > > primes = 2:3:euler hprs [] (scanl (+) 5 (cycle [2,4])) > > where > > hprs = 5:drop 3 primes > > euler (p:ps) acc cs = h ++ euler ps (tail (acc ++ h)) (t `minus` > > comps) where > > (h,t) = span (< p*p) cs > > comps = map (*p) (acc ++ cs) > > this look like {2,3} wheel reimplemented and inlined. The {2,3} wheel thing isn't important. It could equally well (well, a bit slower) be primes = euler hprs [] [2 .. ] where hprs = 2:tail primes It just occured to me that the accumulation list is just (takeWhile (< head cs) (p:ps)), so we could improve it as euler (p:ps) cs = h ++ euler ps (t `minus` comps) where (h,t) = span (< p*p) cs comps = map (*p) (takeWhile (< head cs) (p:ps) ++ cs) Still Bad. > No point in improving > anything until the linear structure isn't turned into a tree. > You're a tree hugger? :D No, the point isn't linear vs. tree, it's that Euler's sieve is a) great for theoretical reasoning (look at a proof of Euler's product formula for the (Riemann) Zeta-function to appreciate it) b) reasonably good for sieving with a list of numbers written on paper, but c) not good to implement on a computer. For the computer, keeping track of which numbers are left is so much more complicated than just ticking off numbers a couple of times that it isn't even worth attempting it. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/3538bf99/attachment.html From dpiponi at gmail.com Mon Jan 4 18:42:13 2010 From: dpiponi at gmail.com (Dan Piponi) Date: Mon Jan 4 18:15:12 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <61f84eff1001041526q45e79130lcf6cf257257de4c7@mail.gmail.com> References: <20100104221453.GC19757@inria.fr> <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> <625b74081001041515u4c00f8fei4a2f6c8dea48e70a@mail.gmail.com> <61f84eff1001041526q45e79130lcf6cf257257de4c7@mail.gmail.com> Message-ID: <625b74081001041542u68a94499xb17995f42b590fd8@mail.gmail.com> On Mon, Jan 4, 2010 at 3:26 PM, Derek Elkins wrote: > Yes, I have the same problem...Basically, I'm > pretty sure the construction of that free theorem doesn't rely on any > of the actual details... For a long time I've thought such a higher order free theorem must exist, and I've mentioned it to a few people, and searched hard for a paper on it, but I haven't seen an actual statement and proof. > At this point, though, I haven't put > much effort into proving that the free theorem holds uniformly Well I encourage you to as I've a hunch the correctly generalised theorem will be quite pretty. I'd have a go but the style of proof for these sorts of things is outside of my domain of confidence/experience. -- Dan From paul.brauner at loria.fr Mon Jan 4 19:15:40 2010 From: paul.brauner at loria.fr (Paul Brauner) Date: Mon Jan 4 18:48:41 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> References: <20100104221453.GC19757@inria.fr> <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> Message-ID: <20100105001540.GD19757@inria.fr> Thanks. I was wondering if the free theorem of fmap entailed that implication, but I'm not used enough to decipher the output of the tool, neither am I able to generate it by hand. However, if this holds (law1 => law2), I wonder why this isn't some "classic" category theory result (maybe it is ?). I don't know much about category theory, but it seems to me that functors are pretty central to it. Maybe i'm confusing haskell's notion of Functor and category theory functors. Paul On Tue, Jan 05, 2010 at 08:01:46AM +0900, Derek Elkins wrote: > On Tue, Jan 5, 2010 at 7:14 AM, Paul Brauner wrote: > > Hi, > > > > I'm trying to get a deep feeling of Functors (and then pointed Functors, > > Applicative Functors, etc.). To this end, I try to find lawless > > instances of Functor that satisfy one law but not the other. > > > > I've found one instance that satisfies fmap (f.g) = fmap f . fmap g > > but not fmap id = id: > > > > data Foo a = A | B > > > > instance Functor Foo where > > ?fmap f A = B > > ?fmap f B = B > > > > -- violates law 1 > > fmap id A = B > > > > -- respects law 2 > > fmap (f . g) A = (fmap f . fmap g) A = B > > fmap (f . g) B = (fmap f . fmap g) B = B > > > > But I can't come up with an example that satifies law 1 and not law 2. > > I'm beginning to think this isn't possible but I didn't read anything > > saying so, neither do I manage to prove it. > > > > I'm sure someone knows :) > > Ignoring bottoms the free theorem for fmap can be written: > > If h . p = q . g then fmap h . fmap p = fmap q . fmap g > Setting p = id gives > h . id = h = q . g && fmap h . fmap id = fmap q . fmap g > Using fmap id = id and h = q . g we get, > fmap h . fmap id = fmap h . id = fmap h = fmap (q . g) = fmap q . fmap g > > So without doing funky stuff involving bottoms and/or seq, I believe > that fmap id = id implies the other functor law (in this case, not in > the case of the general categorical notion of functor.) From chris at eidhof.nl Mon Jan 4 19:20:27 2010 From: chris at eidhof.nl (Chris Eidhof) Date: Mon Jan 4 18:53:29 2010 Subject: [Haskell-cafe] Compiling a shared library on MacOS X In-Reply-To: References: <96255e01001030628r7375a866p22cc1b6c3802b6a5@mail.gmail.com> Message-ID: <2BB98AC4-6F80-43B8-90C2-F69011277B96@eidhof.nl> I'm not sure if it is of any help, but at the haskell-wiki there's an article about how to communicate between Haskell and Objective-C using XCode: http://haskell.org/haskellwiki/Using_Haskell_in_an_Xcode_Cocoa_project -chris On 4 jan 2010, at 00:36, Ivan Miljenovic wrote: > If I recall correctly, dynamic linking/shared library support is not > yet available for OSX, as the Industrial Haskell Group does not have > any knowledge of OSX (but is willing to pay someone who does to do the > work). > > 2010/1/4 Jean-Denis Koeck : >> Hello, >> I'm using the following cabal file to build a shared library with ghc: >> >> Build-Type: Simple >> Executable libmylibrary.dll >> If os(windows) >> CPP-Options: -DWIN32 >> Extensions: ForeignFunctionInterface >> Build-Depends: ... >> Main-Is: libmylibrary.hs >> Ghc-Options: -W --make -no-hs-main -optl-shared -optl-s -O2 >> >> The resulting library is called from a C++ graphical user interface (using >> Qt), >> which worked great so far on Windows and Linux. >> >> However, the compilation fails on MacOS X: >> >> Undefined symbols: >> "_ZCMain_main_closure", referenced from: >> _ZCMain_main_closure$non_lazy_ptr in libHSrts.a(Main.o) >> "___stginit_ZCMain", referenced from: >> ___stginit_ZCMain$non_lazy_ptr in libHSrts.a(Main.o) >> ld: symbol(s) not found >> collect2: ld returned 1 exit status >> >> I don't know much about shared libraries, even less about them on MacOS X :( >> Any idea ? >> >> Jean-Denis Koeck >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> >> > > > > -- > Ivan Lazar Miljenovic > Ivan.Miljenovic@gmail.com > IvanMiljenovic.wordpress.com > Joan Crawford - "I, Joan Crawford, I believe in the dollar. > Everything I earn, I spend." - > http://www.brainyquote.com/quotes/authors/j/joan_crawford.html > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From mwotton at gmail.com Mon Jan 4 19:38:08 2010 From: mwotton at gmail.com (Mark Wotton) Date: Mon Jan 4 19:11:08 2010 Subject: [Haskell-cafe] Compiling a shared library on MacOS X In-Reply-To: References: <96255e01001030628r7375a866p22cc1b6c3802b6a5@mail.gmail.com> Message-ID: <9ea53ad51001041638s67a0e18anbe16ec3d8fda5fd3@mail.gmail.com> There's a patch for it in GHC HEAD by Stephen Blackheath and me, and an accompanying patch for Cabal. http://hackage.haskell.org/trac/ghc/ticket/3550 http://hackage.haskell.org/trac/hackage/ticket/591 has the details. mark On Mon, Jan 4, 2010 at 10:36 AM, Ivan Miljenovic wrote: > If I recall correctly, dynamic linking/shared library support is not > yet available for OSX, as the Industrial Haskell Group does not have > any knowledge of OSX (but is willing to pay someone who does to do the > work). > > 2010/1/4 Jean-Denis Koeck : >> Hello, >> I'm using the following cabal file to build a shared library with ghc: >> >> Build-Type:??? ??????? Simple >> Executable libmylibrary.dll >> ? If os(windows) >> ??? CPP-Options:??????? -DWIN32 >> ? Extensions:?????????? ForeignFunctionInterface >> ? Build-Depends:??????? ... >> ? Main-Is:????????????? libmylibrary.hs >> ? Ghc-Options:????????? -W --make -no-hs-main -optl-shared -optl-s -O2 >> >> The resulting library is called from a C++ graphical user interface (using >> Qt), >> which worked great so far on Windows and Linux. >> >> However, the compilation fails on MacOS X: >> >> Undefined symbols: >> ? "_ZCMain_main_closure", referenced from: >> ????? _ZCMain_main_closure$non_lazy_ptr in libHSrts.a(Main.o) >> ? "___stginit_ZCMain", referenced from: >> ????? ___stginit_ZCMain$non_lazy_ptr in libHSrts.a(Main.o) >> ld: symbol(s) not found >> collect2: ld returned 1 exit status >> >> I don't know much about shared libraries, even less about them on MacOS X :( >> Any idea ? >> >> Jean-Denis Koeck >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> >> > > > > -- > Ivan Lazar Miljenovic > Ivan.Miljenovic@gmail.com > IvanMiljenovic.wordpress.com > Joan Crawford ?- "I, Joan Crawford, I believe in the dollar. > Everything I earn, I spend." - > http://www.brainyquote.com/quotes/authors/j/joan_crawford.html > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- A UNIX signature isn't a return address, it's the ASCII equivalent of a black velvet clown painting. It's a rectangle of carets surrounding a quote from a literary giant of weeniedom like Heinlein or Dr. Who. -- Chris Maeda From dpiponi at gmail.com Mon Jan 4 19:38:19 2010 From: dpiponi at gmail.com (Dan Piponi) Date: Mon Jan 4 19:11:22 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <20100105001540.GD19757@inria.fr> References: <20100104221453.GC19757@inria.fr> <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> <20100105001540.GD19757@inria.fr> Message-ID: <625b74081001041638r204b57ffu9eda0e0176ef43bb@mail.gmail.com> On Mon, Jan 4, 2010 at 4:15 PM, Paul Brauner wrote: > I wonder why this isn't some "classic" category theory result (maybe it is ?) It doesn't hold in category theory in general. Haskell (or at least a certain subset) is special - many things that just *look* category theoretical turn out to actually *be* category theoretical. That's quite a strong statement. So, for example, functions that have the type signature of a natural transformation are in fact natural transformations (which tells you non-trivial facts about the function). And you've found that things that are only half-defined functors are actually full-blown functors (subject to someone providing a rigorous proof of this...). This is useful. If you're using QuickCheck to convince yourself you've implemented a functor correctly, you only need to test it on id. -- Dan From daniel.is.fischer at web.de Mon Jan 4 19:50:00 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Jan 4 19:24:36 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: Message-ID: <201001050150.01117.daniel.is.fischer@web.de> Am Montag 04 Januar 2010 16:30:18 schrieb Will Ness: > Heinrich Apfelmus quantentunnel.de> writes: > > > > (I haven't followed the whole thread, but hopefully I have enough grasp > > of it to make a useful remark. :)) > > > > Concerning lists as producer/consumer, I think that's exactly what lazy > > evaluation is doing. Neither filter , map or span evaluate and > > store more list elements that strictly necessary. > > I laways suspected as much, but was once told that Chris Okasaki has shown > that any filter etc must allocate its own storage. With the peek/pull they > don't have to, if they are nested, and the deepest one from the real > storage gets pulled through some pointer chasing eventually. Span isn't so > easily compiled out too or is it? But that might be a minor point. > > For me, a real smart compiler is one that would take in e.g. (sum $ take n > $ cycle $ [1..m]) and spill out a straight up math formula, inside a few > ifs maybe (just an aside). Such things just aren't common enough. If you start letting the compiler look for patterns such as this which can be transformed into a simple formula, compile times would explode. > > Such a smart compiler might even be able to derive a well performing code > right from the Turner's sieve. :) > > > Sure, creating a list head only to immediately consume it is somewhat > > inefficient -- and the target of stream fusion[1] -- but this is an > > overhead of how list elements are stored, not how many. > > it might be equivalent to the (imagined) producer's storing its 'current' > value inside its frame. > > How much can we rely on the run-time to actually destroy all the > passed-over elements and not hang on to them for some time? If they're really passed over, they very probably won't survive the next GC. > Is this that compiler switch that Daniel mentioned? Is it reliable? > No, it's something different. Not entirely unrelated. The -fno-cse turns off Common Subexpression Elimination (rather sharing than elimination). That is, if you have f x = g (expensive x) y z (h (expensive x)) the compiler can see the common subexpression (expensive x) on the RHS and decide to share it, i.e. calculate it only once: f x = let e = expensive x in g e y z (h e) That may or may not be a good idea. If e is small (say an Int) and expensive isn't a blatant lie, it is a *very* good idea. But if e is a loong list that expensive x lazily produces and that is consumed by g and h in the right manner, it is often a bad idea because h might not start to consume before g has demanded a long prefix of the list and kaboom, Heap exhausted. If you turn on optimisations, the compiler does some looking for common subexpressions to share. There are some heuristics to decide when to share, but they're far from infallible. So, if you have a situation like above, and the compiler heuristics indicate that sharing would be good although it isn't, you're hosed. So you have the option to tell the compiler "try hard to optimise, but don't do CSE (because I know it would be bad here)" {- that can be done on a per-file basis, it would be cool if it could be done on a per-function basis -}. Now if you have a list producer and a consumer, without fusion, it goes like Consumer: Gimme Producer: creates cons cell, puts value, next cons cell (how to produce more) Consumer: takes value, does something with it, gimme more. Stream fusion is about eliminating the cons cell creating and value passing, to fuse production and consumption into a nice loop. That is of course impossible if the produced list is shared between two (or more) consumers. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/09f01630/attachment.html From Andrejs.Sisojevs at nextmail.ru Mon Jan 4 20:26:30 2010 From: Andrejs.Sisojevs at nextmail.ru (Andrey Sisoyev) Date: Mon Jan 4 19:59:30 2010 Subject: [Haskell-cafe] HackageDB is not for ... ? Message-ID: <27022312.post@talk.nabble.com> Hello everybody! I'm planning not a small project, and intuition suggests me, that I should use heavily the rule "separate and rule". So I must separate the project into many maximum independent and general pieces (packages), make them, and finally glue it into my project. The pieces and their dependencies will form an oriented graph without cycles and with overall path finishing into the final project. So far so good I have made two pieces: ** http://hackage.haskell.org/package/PCLT-DB ** http://hackage.haskell.org/package/PriorityChansConverger But I'm coming to understand, that it's not polite to other community members to publish just every package my project will consist of, because we do not want to garbage HackageDB. ------------------------------------- Consider cases: (1) I don't want to publish package A, because I doubt anyone will find it useful. But I develop independent packages B and C, that will be usefull for the community, and want to publish them on Hackage, but they require package A! [Solution] Publish package A, but make it maximum general and complete in itself. (2) I don't want to publish package A, because it's tiny. Well imagine something same popular and useful, like Ord class. 10 lines of code. But I don't want to repeat these lines in every other package. [Solution] Same as for (1) I guess. (3) I don't want to publish package A, because it's about adjacent system. I'm making 3 packages, that all use DBMS (PostgreSQL). All three are thught to be independent. But! They all in their DDL scripts use table inheritance from a common ancestor table "nameables", which is everywhere defined the same: > CREATE TABLE nameables ( -- an ancestor table > name varchar NOT NULL DEFAULT '' > , description varchar NULL > , comments varchar NULL > ) TABLESPACE tabsp_pcltcatalogs; > GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE nameables TO > user_someCurrentSchema_data_admin; > GRANT SELECT ON TABLE nameables TO user_someCurrentSchema_data_reader; Now what do I do with that?? The problem gets even more complicated be the fact, that dependent packages may use different DB schemes, so DDL sql script from Nameables will have to be run additionally for them. But that's easy to solve - just decide, whether to add or not by build-depends a comment "-- with DDL init", and maybe additional instruction in README. [Solution] ??? [Solution A] Well, of course, I can pretend that this package may be is Haskellish enough, by inventing something which I don't really need: > data Name = Name { nName :: String, nDescription :: Maybe String, > nComments :: Maybe String } > > class Nameables a where > getName :: a -> Name > > class HasPrimaryKey a => NameableInDBOnly a where > getNameFromDB :: Connection -> a -> IO Name This + sql script and instruction, how to initialize DB. Is it okay to publish this? Looks like garbage... [Solution B] Do my own version control and add same pieces to every package that use Nameable. Don't like this solution. May be I should start using other repository systems like github or darcs, and then this solution will seem more natural to me?.. ---------------------------------- These are my thoughts on the theme. In any case I come to wanting to publish the packages anyway. Probably I miss something in ideology and methodology of using Hackage as community repository. And what do you think about it? Regards, Andrey -- View this message in context: http://old.nabble.com/HackageDB-is-not-for-...---tp27022312p27022312.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From dalej at alum.mit.edu Mon Jan 4 20:31:20 2010 From: dalej at alum.mit.edu (Dale Jordan) Date: Mon Jan 4 20:13:37 2010 Subject: [Haskell-cafe] Why doesn't laziness save the day here? Message-ID: Kind and Generous Haskellers: I am ensnared in a briar patch of infinite lists and Random gnerators trying to use laziness to advantage. Here's my code: ----------------- 8< -------------------- import Control.Applicative import Control.Monad import Control.Monad.Random import Control.Monad.State import System.Random.Mersenne.Pure64 -- Specialized iterator for running actions in Rand monad, to thread -- the generator. The idea is that the action returns a finite list -- of random values and iterateR lazily creates an infinite list of -- values. iterateR act = do gen <- get let (as,gen') = runRand act gen put $! gen' (as ++) <$> iterateR act -- A simple example of a finite action something :: (RandomGen g) => Int -> Int -> Rand g [Int] something n m = sequence . replicate n $ getRandomR (m,m+9) run1 = evalState (take 10 <$> (iterateR (something 2 0))) $ pureMT 42 run2 = evalState (take 10 <$> (iterateR (something 2 0) >> iterateR (something 3 10))) $ pureMT 42 run3 = evalState (take 10 <$> (iterateR (something 2 0) >>= iterateR . (something 3 . head))) $ pureMT 42 ------------------- >8 ---------------------- Evaluating run1 works fine (ghci 10.3): *Main> run1 [1,9,5,3,6,9,1,5,1,8] Evaluating run2 or run3 loops and quickly exhausts the heap. (Using Control.Monad.State.Strict causes stack overflow, though) The motivation for iterateR is to be able to have the ultimate consumer determine how many random values to force, but still have a single random generator used throughout the computation. My intuition tells me that since the infinite list is produced in finite batches, the generator shouldn't be tangled up in an infinite list such as produced by MonadRandom's getRandoms, but I only have a pink belt in Haskell-fu. Can anyone explain why this is looping or point out a better way to generate an arbitrary-length random list while still being able to reuse the generator? (I'd rather not use split since this generator doesn't support it and its of dubious soundness.) Dale Jordan From daniel.is.fischer at web.de Mon Jan 4 20:43:42 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Jan 4 20:18:19 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: <201001042225.29189.daniel.is.fischer@web.de> References: <201001042225.29189.daniel.is.fischer@web.de> Message-ID: <201001050243.43208.daniel.is.fischer@web.de> Am Montag 04 Januar 2010 22:25:28 schrieb Daniel Fischer: > compos ps = fst (tfold mergeSP $ nwise 1 mergeSP (pairwise mergeSP (multip > ps))) > > tfold f (a: ~(b: ~(c:xs))) > ???????????????????? = (a `f` (b `f` c)) `f` tfold f xs > > nwise k f xs = let (ys,zs) = splitAt k xs in rfold f ys : nwise (k+1) f zs > > rfold f [x] = x > rfold f (x:xs) = x `f` rfold f xs > > memory still grows, but much slower, in my tests, due to the much smaller > GC time, it's a bit faster than the version with the original tfold. Not for larger inputs (but not so large that the tree-fold dies OOM). Fix rfold: rfold f [x] = x rfold f xs = rfold f (pairwise f xs) and it's faster also for those. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/a8bb9b45/attachment-0001.html From uzytkownik2 at gmail.com Mon Jan 4 20:51:09 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Mon Jan 4 20:24:32 2010 Subject: [Haskell-cafe] Re: HackageDB is not for ... ? In-Reply-To: <27022312.post@talk.nabble.com> References: <27022312.post@talk.nabble.com> Message-ID: <1262656269.13413.85.camel@picard> On Mon, 2010-01-04 at 17:26 -0800, Andrey Sisoyev wrote: > Hello everybody! > Hello > ------------------------------------- > Consider cases: > (1) > I don't want to publish package A, because I doubt anyone will find it > useful. > But I develop independent packages B and C, that will be usefull for the > community, and want to publish them on Hackage, but they require package A! > > [Solution] Publish package A, but make it maximum general and complete in > itself. > > (2) > I don't want to publish package A, because it's tiny. Well imagine something > same popular and useful, like Ord class. 10 lines of code. But I don't want > to repeat these lines in every other package. > > [Solution] Same as for (1) I guess. > Find other package and send a patch (like category-extras) if it applies? > > [Solution B] Do my own version control and add same pieces to every package > that use Nameable. Don't like this solution. May be I should start using > other repository systems like github or darcs, and then this solution will > seem more natural to me?.. [Solution C] Create package. Don't publish it but install locally. I'm not proposing the Solution C as I'm not host of hackage. But it is also possible. Regards From daniel.is.fischer at web.de Mon Jan 4 21:04:53 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Jan 4 20:39:28 2010 Subject: [Haskell-cafe] Why doesn't laziness save the day here? In-Reply-To: References: Message-ID: <201001050304.53717.daniel.is.fischer@web.de> Am Dienstag 05 Januar 2010 02:31:20 schrieb Dale Jordan: > Kind and Generous Haskellers: > > I am ensnared in a briar patch of infinite lists and Random gnerators > trying to use laziness to advantage. Here's my code: > > ----------------- 8< -------------------- > import Control.Applicative > import Control.Monad > import Control.Monad.Random > import Control.Monad.State > import System.Random.Mersenne.Pure64 > > -- Specialized iterator for running actions in Rand monad, to thread > -- the generator. The idea is that the action returns a finite list > -- of random values and iterateR lazily creates an infinite list of > -- values. > > iterateR act = do > gen <- get > let (as,gen') = runRand act gen > put $! gen' > (as ++) <$> iterateR act > > -- A simple example of a finite action > something :: (RandomGen g) => Int -> Int -> Rand g [Int] > something n m = sequence . replicate n $ getRandomR (m,m+9) > > run1 = evalState (take 10 <$> (iterateR (something 2 0))) $ pureMT 42 > > run2 = evalState > (take 10 <$> (iterateR (something 2 0) >> iterateR (something > 3 10))) > $ pureMT 42 > > run3 = evalState > (take 10 <$> (iterateR (something 2 0) >>= iterateR . > (something 3 . head))) > $ pureMT 42 > ------------------- >8 ---------------------- > > Evaluating run1 works fine (ghci 10.3): > *Main> run1 > [1,9,5,3,6,9,1,5,1,8] > > Evaluating run2 or run3 loops and quickly exhausts the heap. > > (Using Control.Monad.State.Strict causes stack overflow, though) > > The motivation for iterateR is to be able to have the ultimate > consumer determine how many random values to force, but still have a > single random generator used throughout the computation. > > My intuition tells me that since the infinite list is produced in > finite batches, the generator shouldn't be tangled up in an infinite > list such as produced by MonadRandom's getRandoms, but I only have a > pink belt in Haskell-fu. > > Can anyone explain why this is looping Rand g is basically State g (or, rather StateT g Identity). Looking at the definition of (>>=) for that: instance (Monad m) => Monad (StateT s m) where return a = StateT $ \s -> return (a, s) m >>= k = StateT $ \s -> do ~(a, s') <- runStateT m s runStateT (k a) s' in a1 >> a2, if a2 wants to use the state, it can't do that before a1 is done. iterateR is never finished, so iterateR act >> otherAct can only work if otherAct doesn't use the state (or puts a state before using it). > or point out a better way to > generate an arbitrary-length random list while still being able to > reuse the generator? Sorry, no. > (I'd rather not use split since this generator > doesn't support it and its of dubious soundness.) > > Dale Jordan -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/e01be6dc/attachment.html From cantthinkthinkpink at gmail.com Mon Jan 4 21:23:14 2010 From: cantthinkthinkpink at gmail.com (Jamie Morgenstern) Date: Mon Jan 4 20:56:14 2010 Subject: [Haskell-cafe] Significant slow-down in parallel code? In-Reply-To: <404396ef1001041214t1ef9b497qdf598f6cb8686fd2@mail.gmail.com> References: <404396ef1001041214t1ef9b497qdf598f6cb8686fd2@mail.gmail.com> Message-ID: I am using 6.12... are there any good pointers as to how one uses threadscope? On Mon, Jan 4, 2010 at 3:14 PM, Neil Mitchell wrote: > Hi Jamie, > > First question, what version of GHC are you using? There are > significant performance improvements to parallel code in GHC 6.12, so > it's worth an upgrade. Once you've upgraded you might want to try out > threadscope which is designed to help track down these sorts of > problems. > > If you are using 6.10, I recommend turning off parallel garbage > collection with the RTS flags (see the manual) as that can cause > slowdowns. > > Thanks, Neil > > 2010/1/4 Jamie Morgenstern : > > Hello; > > > > I have a piece of code in which I employ the `par` construct to add some > implicit parallelism > > to a theorem prover. However, when running the *same* code with > > > > +RTS -N1 > > +RTS -N5 > > +RTS -N10 > > > > I see a huge slowdown (a factor of 50 with 5 processes and a factor of > 100 for 10 on an 8-core machine). > > > > Very little time is being spent using the garbage collector. Any > suggestions? > > > > Thanks, > > -Jamie > > > > _______________________________________________ > > Haskell-Cafe mailing list > > Haskell-Cafe@haskell.org > > http://www.haskell.org/mailman/listinfo/haskell-cafe > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100104/5efb71ab/attachment.html From uzytkownik2 at gmail.com Mon Jan 4 21:25:22 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Mon Jan 4 20:59:32 2010 Subject: [Haskell-cafe] Re: lawless instances of Functor In-Reply-To: <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> References: <20100104221453.GC19757@inria.fr> <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> Message-ID: <1262658322.13413.116.camel@picard> On Tue, 2010-01-05 at 08:01 +0900, Derek Elkins wrote: > On Tue, Jan 5, 2010 at 7:14 AM, Paul Brauner wrote: > > Hi, > > > > I'm trying to get a deep feeling of Functors (and then pointed Functors, > > Applicative Functors, etc.). To this end, I try to find lawless > > instances of Functor that satisfy one law but not the other. > > > > I've found one instance that satisfies fmap (f.g) = fmap f . fmap g > > but not fmap id = id: > > > > data Foo a = A | B > > > > instance Functor Foo where > > fmap f A = B > > fmap f B = B > > > > -- violates law 1 > > fmap id A = B > > > > -- respects law 2 > > fmap (f . g) A = (fmap f . fmap g) A = B > > fmap (f . g) B = (fmap f . fmap g) B = B > > > > But I can't come up with an example that satifies law 1 and not law 2. > > I'm beginning to think this isn't possible but I didn't read anything > > saying so, neither do I manage to prove it. > > > > I'm sure someone knows :) > > Ignoring bottoms the free theorem for fmap can be written: > > If h . p = q . g then fmap h . fmap p = fmap q . fmap g > Setting p = id gives > h . id = h = q . g && fmap h . fmap id = fmap q . fmap g > Using fmap id = id and h = q . g we get, > fmap h . fmap id = fmap h . id = fmap h = fmap (q . g) = fmap q . fmap g > > So without doing funky stuff involving bottoms and/or seq, I believe > that fmap id = id implies the other functor law (in this case, not in > the case of the general categorical notion of functor.) Hmm. Not quite a proff as we want to use: For all f g fmap (f . g) = fmap f . fmap g. So we need to operate on arbitrary f and g. Also in first line conclusion is used - at this stage we don't know if h . p = p . q -> fmap h . fmap p = fmap q . fmap g. Especially that (A->B) functions is |A|^|B| (and in haskell |A| >= 1, | B| >= 1). Now imagine that (in pseudocode[1]): rho :: (A -> B) -> A -> B rho f | f is A -> A = id | f is Integral -> Integral = (+1) . fromIntegral | otherise = f then instance Functor Foo where fmap f (Something a) = Something $ rho f a then fmap id = id but if f = (+1) . fromIntegral :: Integer -> Int g = (-1) . fromIntegral :: Int -> Integer then fmap (f . g) = fmap id but fmap f . fmap g = fmap (+2) Regards [1] It can nearly be written in Haskell+Rules but rules does not have precedence. From ajb at spamcop.net Mon Jan 4 21:47:23 2010 From: ajb at spamcop.net (ajb@spamcop.net) Date: Mon Jan 4 21:17:58 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> References: <20100104221453.GC19757@inria.fr> <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> Message-ID: <20100104214723.s7n99jng8wk0soow-nwo@webmail.spamcop.net> G'day all. Quoting Derek Elkins : > Ignoring bottoms the free theorem for fmap can be written: > > If h . p = q . g then fmap h . fmap p = fmap q . fmap g > Setting p = id gives > h . id = h = q . g && fmap h . fmap id = fmap q . fmap g > Using fmap id = id and h = q . g we get, > fmap h . fmap id = fmap h . id = fmap h = fmap (q . g) = fmap q . fmap g Dan Piponi points out: > When I play with http://haskell.as9x.info/ft.html I get examples that > look more like: > > If fmap' has the same signature as the usual fmap for a type > and h . p = q . g > then fmap h . fmap' p = fmap' q . fmap g > > From which it follows that if fmap' id = id then fmap' is fmap. The free theorem for: fmap' :: forall a b. (a -> b) -> F a -> F b assumes that F is already a Functor. That is, it shows that if there exists a valid fmap instance for F, then for any other function fmap' with the same signature as fmap, fmap' id = id implies fmap' = fmap. So if you want to invent a data type and fmap instance which satisfies law 1 but not law 2, then it needs to be a data type for which no valid fmap instance is possible *at all*. So it doesn't rule out the possibility completely, but it narrows down the search space considerably. Cheers, Andrew Bromage From Andrejs.Sisojevs at nextmail.ru Tue Jan 5 00:17:43 2010 From: Andrejs.Sisojevs at nextmail.ru (Andrey Sisoyev) Date: Mon Jan 4 23:50:44 2010 Subject: [Haskell-cafe] HackageDB is not for ... ? In-Reply-To: <1262656269.13413.85.camel@picard> References: <27022312.post@talk.nabble.com> <1262656269.13413.85.camel@picard> Message-ID: <27023914.post@talk.nabble.com> > Find other package and send a patch (like category-extras) if it > applies? That is good, if I find other package, that satisfies my requirements (or does, with my patch). But that's a solution for a different case. Consider (1) and (2) to be conceptually unique. > [Solution C] Create package. Don't publish it but install locally. That's what I meant by [Solution B]. Let's name this package A. The problem arises when I want to publish something, that depends on A. And if I publish 3 such packages, that depend on A? Then I have to merge A with all three. I also have to do my own versions control, because some may requier newer A, some - older A. That's a lot of manual administration. Andrey -- View this message in context: http://old.nabble.com/HackageDB-is-not-for-...---tp27022312p27023914.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From lrpalmer at gmail.com Tue Jan 5 02:53:49 2010 From: lrpalmer at gmail.com (Luke Palmer) Date: Tue Jan 5 02:26:49 2010 Subject: [Haskell-cafe] Re: Re: Data.Ring -- Pre-announce In-Reply-To: <1262636003.13413.74.camel@picard> References: <1262613072.13413.64.camel@picard> <7ca3f0161001040617w1a67529crb513c4c926564c6a@mail.gmail.com> <1262636003.13413.74.camel@picard> Message-ID: <7ca3f0161001042353v3bf28512m52caa27f82d14939@mail.gmail.com> On Mon, Jan 4, 2010 at 1:13 PM, Maciej Piechotka wrote: > However then we lost the monoid (ok. I haven't send patch but please > accept[1]) along with alternative/monad plus - which is much more > popular, standard and useful then Copointed/Comonad. This point is a self-fulfilling prophecy. We don't have very much experience working with copointeds and comonads, but I don't think that makes them useless, just unfamiliar. "One must never confuse what is natural with what is habitual." -- Mahatma Gandhi Luke From lrpalmer at gmail.com Tue Jan 5 03:03:33 2010 From: lrpalmer at gmail.com (Luke Palmer) Date: Tue Jan 5 02:36:33 2010 Subject: [Haskell-cafe] Why doesn't laziness save the day here? In-Reply-To: References: Message-ID: <7ca3f0161001050003o731a5973h3485865c02583c9d@mail.gmail.com> On Mon, Jan 4, 2010 at 6:31 PM, Dale Jordan wrote: > Can anyone explain why this is looping or point out a better way to > generate an arbitrary-length random list while still being able to > reuse the generator? ?(I'd rather not use split since this generator > doesn't support it and its of dubious soundness.) Well there is more than one way to split. You don't have to split the generator -- if you act on a stream of random numbers, you can split the stream also: split :: [a] -> ([a],[a]) split (x:xs) = (x:bs,as) where (as,bs) = split xs However too much splitting in this case causes a performance penalty, since you start discarding large portions of the stream. If you don't want to split the generator, this is the only way I can think of that is deterministic in the random seed. If determinism is not required, as many times it is not with *random* computations, you can use the value-supply package on hackage, which uses a bit of unsafePerformIO magic to turn a serial stream into a splittable stream. But you lose composable repeatability. Luke From lrpalmer at gmail.com Tue Jan 5 03:23:14 2010 From: lrpalmer at gmail.com (Luke Palmer) Date: Tue Jan 5 02:56:14 2010 Subject: [Haskell-cafe] Re: lawless instances of Functor In-Reply-To: <1262658322.13413.116.camel@picard> References: <20100104221453.GC19757@inria.fr> <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> <1262658322.13413.116.camel@picard> Message-ID: <7ca3f0161001050023h3226df64m68918e76f477a94f@mail.gmail.com> On Mon, Jan 4, 2010 at 7:25 PM, Maciej Piechotka wrote: > On Tue, 2010-01-05 at 08:01 +0900, Derek Elkins wrote: >> If h . p = q . g then fmap h . fmap p = fmap q . fmap g >> Setting p = id gives >> h . id = h = q . g && fmap h . fmap id = fmap q . fmap g >> Using fmap id = id and h = q . g we get, >> fmap h . fmap id = fmap h . id = fmap h = fmap (q . g) = fmap q . fmap g >> > Hmm. Not quite a proff as we want to use: For all f g fmap (f . g) = > fmap f . fmap g. So we need to operate on arbitrary f and g. Also in > first line conclusion is used - at this stage we don't know if h . p = > p . q -> fmap h . fmap p = fmap q . fmap g. No, the first line is the "free theorem" -- i.e. the parametericity theorem -- for the type. It holds for any Haskell value with this type, coming essentially from the fact that downcasts are not possible in Haskell. You can play with free theorems here: http://linux.tcs.inf.tu-dresden.de/~voigt/ft/. See Wadler's paper "Theorem's for free!" for more about them. > Especially that (A->B) functions is |A|^|B| (and in haskell |A| >= 1, | > B| >= 1). Now imagine that (in pseudocode[1]): > rho :: (A -> B) -> A -> B > rho f | f is A -> A = id > ? ? ?| f is Integral -> Integral = (+1) . fromIntegral > ? ? ?| otherise = f Haskell's inability to write this function is exactly where free theorems come from. Luke From stephen.tetley at gmail.com Tue Jan 5 03:34:35 2010 From: stephen.tetley at gmail.com (Stephen Tetley) Date: Tue Jan 5 03:07:34 2010 Subject: [Haskell-cafe] Why doesn't laziness save the day here? In-Reply-To: References: Message-ID: <5fdc56d71001050034y7d8f2f49we83f2adfe7ef083c@mail.gmail.com> 2010/1/5 Dale Jordan : > The motivation for iterateR is to be able to have the ultimate > consumer determine how many random values to force, but still have a > single random generator used throughout the computation. Hi Dale If you want the producer and consumer to run at different speeds with something in-between to synchronize them (velomorphisms anyone?), you might want to look at Jeremy Gibbons's spigot algorithm for pi and also his metamorphisms paper. http://www.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/spigot.pdf http://www.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/metamorphisms-scp.pdf That said, I've personally found it hard to frame code in the spigot style so I couldn't readily offer any tips on the code you've presented. Best wishes Stephen From will_n48 at yahoo.com Tue Jan 5 04:33:19 2010 From: will_n48 at yahoo.com (Will Ness) Date: Tue Jan 5 04:06:44 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001050150.01117.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > > Am Montag 04 Januar 2010 16:30:18 schrieb Will Ness: > > > > For me, a real smart compiler is one that would take in e.g. (sum $ take n > > $ cycle $ [1..m]) and spill out a straight up math formula, inside a few > > ifs maybe (just an aside). > > Such things just aren't common enough. If you start letting the compiler > look for patterns such as this which can be transformed into a simple > formula, compile times would explode. I was thinking more along the lines of inferencing compiler, proving new theorems about the types and applying that knowledge in simplifying the expressions. This would take time, so it should be a part of some interactive system, maybe kind of like Lisp has. In such a setting, the underlying compiler could first produce quick-n-dirty version, and would continue working in the background whenever the system is not busy, trying to improve the executable. Such a system would probably have to distinguish, at the type level, between [1..m] ; cycle [1..m] ; take n [1..m] ; etc. These would all be not just fuctions, but parts of a type's (here list) behaviour with automatically deduced semantics. What would such a type system be called? > The -fno-cse turns off Common Subexpression Elimination (rather sharing > than elimination). > That is, if you have > > f x = g (expensive x) y z (h (expensive x)) > > the compiler can see the common subexpression (expensive x) on the RHS and > decide to share it, i.e. calculate it only once: > > f x = let e = expensive x in g e y z (h e) > > ........ thanks for the in-depth explanation! :) > Now if you have a list producer and a consumer, without fusion, it goes like > Consumer: Gimme > Producer: creates cons cell, puts value, next cons cell (how to produce more) > Consumer: takes value, does something with it, gimme more. > > Stream fusion is about eliminating the cons cell creating and value > passing, to fuse production and consumption into a nice loop. That is of > course impossible if the produced list is shared between two (or more) > consumers. I would imagine so. Do I get this fusion on lists for free from the compiler, or do I have to recode for that? (haven't yet time to look into the article mentioned). > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From uzytkownik2 at gmail.com Tue Jan 5 04:55:12 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Tue Jan 5 04:28:37 2010 Subject: [Haskell-cafe] Using Haskell to write dbus server Message-ID: <1262685311.15115.1.camel@picard> How to write (is it possible) a dbus server in Haskell? Regards From emax at chalmers.se Tue Jan 5 05:00:27 2010 From: emax at chalmers.se (Emil Axelsson) Date: Tue Jan 5 04:33:27 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001030508.46357.daniel.is.fischer@web.de> <201001040129.22689.daniel.is.fischer@web.de> <4B421A56.5050707@chalmers.se> Message-ID: <4B430DBB.30102@chalmers.se> Will Ness skrev: > Emil Axelsson chalmers.se> writes: > >>> For me, a real smart compiler is one that would take in e.g. (sum $ >>> take n $ >>> cycle $ [1..m]) and spill out a straight up math formula, inside a few ifs >>> maybe (just an aside). >> (Also an aside, I couldn't resist...) >> >> Then I'm sure you'd say that Feldspar [1] has a smart compiler :) > > > but it didn't produce > > f n m = if n < m then n*(n+1)/2 else > let (q,r)=quotRem n m > in q*(m*(m+1)/2) + r*(r+1)/2 > > :) Ah, I see... Yes, that would be a very smart compiler :) / Emil From daniel.is.fischer at web.de Tue Jan 5 05:31:13 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Tue Jan 5 05:05:49 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001050150.01117.daniel.is.fischer@web.de> Message-ID: <201001051131.13591.daniel.is.fischer@web.de> Am Dienstag 05 Januar 2010 10:33:19 schrieb Will Ness: > Such a > system would probably have to distinguish, at the type level, between > [1..m] ; cycle [1..m] ; take n [1..m] ; etc. These would all be not just > fuctions, but parts of a type's (here list) behaviour with automatically > deduced semantics. > > What would such a type system be called? > Seriously complicated, I think. Don't get me wrong, a system with such capabilities would be A.W.E.S.O.M.E. I just can't see it happening anytime soon. > > I would imagine so. Do I get this fusion on lists for free from the > compiler, or do I have to recode for that? (haven't yet time to look into > the article mentioned). > Without optimisations, hardly ever if at all (needs a compiler expert to know). With optimisations, sometimes. But it doesn't always see the possibility where it would with recoding in the right style (dons is expert in that). With stream fusion, more often. But I think it would again be not very hard to hide opportunities for fusion by your coding style. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100105/44a1c385/attachment.html From S.J.Thompson at kent.ac.uk Tue Jan 5 07:17:54 2010 From: S.J.Thompson at kent.ac.uk (S.J.Thompson) Date: Tue Jan 5 06:50:53 2010 Subject: [Haskell-cafe] Book reviews for the Journal of Functional Programming Message-ID: If you would be interested in reviewing books for the journal of functional programming you can find a list of currently available books at http://www.cs.kent.ac.uk/people/staff/sjt/JFP/ Please let me know if you would be interested in taking on any of these reviewing assignments. Kind regards, Simon Thompson Book Reviews Editor Journal of Functional Programming From oleg at okmij.org Tue Jan 5 07:17:36 2010 From: oleg at okmij.org (oleg@okmij.org) Date: Tue Jan 5 06:52:02 2010 Subject: [Haskell-cafe] Re: Why doesn't laziness save the day here? Message-ID: <20100105121736.92293173C9@Adric.ern.nps.edu> Dale Jordan wrote: > The motivation for iterateR is to be able to have the ultimate > consumer determine how many random values to force, but still have a > single random generator used throughout the computation. > > My intuition tells me that since the infinite list is produced in > finite batches, ... > > Can anyone explain why this is looping or point out a better way to > generate an arbitrary-length random list while still being able to > reuse the generator? The others have already pointed out the problem with the imperative solution, which used the mutation of the global state with the new random seed. Imperative approach is indeed often a problem. There is a simple solution however. In fact, your message already described it. The key phrase is ``the infinite list is produced in finite batches.'' We merely need to define a list-like data structure that matches our intuitions. The complete code follows. All three run functions, run1 through run3, produce a finite result (shown in the comments after the definition). module RList where -- I don't have Mersenne Twistor installed; so I'll use the stdGen... import System.Random import Control.Monad.State data RList m a = RList [a] -- known finite prefix [m [a]] -- a stream of producing actions pullR :: Monad m => RList m a -> m (RList m a) pullR (RList p (x:xs)) = x >>= \p' -> return $ RList (p++p') xs headR :: Monad m => RList m a -> m a headR (RList (x:_) _) = return x headR x = pullR x >>= headR tailR :: Monad m => RList m a -> m (RList m a) tailR (RList (_:xs) ms) = return $ RList xs ms tailR x = pullR x >>= tailR -- appendR doesn't have to have the monadic type. We go for uniformity with -- the headR appendR :: Monad m => RList m a -> RList m a -> m (RList m a) appendR (RList p1 ms1) (RList p2 ms2) = return $ RList p1 (ms1 ++ (return p2):ms2) takeR :: Monad m => Int -> RList m a -> m (RList m a) takeR 0 l = return l takeR n (RList p ms) | length p >= n = return $ RList (take n p) [] takeR n l = pullR l >>= takeR n -- quite inefficient, but short -- Other list library functions can be implemented in terms of head, tail -- the evaluator, so to speak. It is possibly strict, use it at the -- very end toList :: (Functor m, Monad m) => RList m a -> m [a] toList (RList p []) = return p toList (RList p ms) = pullR (RList [] ms) >>= fmap (p ++) . toList -- Dale Jordan's library, slightly re-written -- Specialized iterator for running actions in Rand monad, to thread -- the generator. The idea is that the action returns a finite list -- of random values and iterateR lazily creates an infinite list of -- values. -- Again, the monadic type is unncessary; given for the sake of -- uniformity iterateR :: Monad m => m [a] -> m (RList m a) iterateR act = return $ RList [] (repeat act) type Rand r a = State r a -- A simple example of a finite action something :: (RandomGen g) => Int -> Int -> Rand g [Int] something n m = sequence . replicate n . State $ randomR (m,m+9) run1 = evalState (toList =<< takeR 10 =<< (iterateR (something 2 0))) $ mkStdGen 42 -- [1,1,7,4,6,1,8,1,8,5] run2 = evalState (toList =<< takeR 10 =<< (iterateR (something 2 0) >> iterateR (something 3 10))) $ mkStdGen 42 -- [11,11,17,14,16,11,18,11,18,15] run3 = evalState (toList =<< (takeR 10 =<< (iterateR (something 2 0) >>= headR >>= iterateR . something 3))) $ mkStdGen 42 -- [8,5,7,2,9,2,9,6,6,10] From will_n48 at yahoo.com Tue Jan 5 08:49:58 2010 From: will_n48 at yahoo.com (Will Ness) Date: Tue Jan 5 08:25:33 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001041802.35854.daniel.is.fischer@web.de> <201001050033.03373.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > > Am Montag 04 Januar 2010 19:16:32 schrieb Will Ness: > > Daniel Fischer web.de> writes: > > > Am Montag 04 Januar 2010 13:25:47 schrieb Will Ness: > > > > Euler's sieve is > > > > > > > > sieve (p:ps) xs = h ++ sieve ps (t `minus` map (p*) [p,p+2..]) > > > > where (h,t) = span (< p*p) xs > > > > > > Not quite. That's a variant of the postponed filters, it crosses off e.g. > > > 45 twice, once as 3*15 and once as 5*9 (okay, it has already been removed > > > by the first, so let's say 45 appears in two lists of numbers to be > > > removed if present). > > > > there won't be any such. whatever is removed first, is just skipped second > > (and third, etc). > > ((45:(offer 47 when demanded)) `minus` (45:(next will be 51 when demanded))) > `minus` (45:(next will be 55 when demanded)) > > So there are two attempts to tell the generator to not output 45. To the > second, it answers "I already knew that", but the request is made > nevertheless. yes, of course. > ... There are two attempts to eliminate 45. I would say there are two requests to not have 45 in the output. > > I don't see any problem here. As Melissa (and yourself, I think) have > > shown, double hits on multiples are few and far between. > > It's not a problem, it just means it's not Euler's sieve, because that > attempts to eliminate each composite exactly once. yes I see now. My bad. Wasn't reading that wikipedia page with enough attention to detail. It uses the modified (culled, so far) numbers to find out the next multiples to be eliminated, not just the prime itself like my code does. You solution is indeed, exponential: euler ks@(p:rs) = p : euler (rs `minus` map (*p) ks) primes = 2:euler [3,5..] primes = 2:euler (as@[3,5..]) 3:euler (bs@(tail as `minus` map (3*) as)) 5:euler (cs@(tail bs `minus` map (5*) bs)) There are two separate look-back pointers to /as/ in /bs/, and there are two such in /cs/, to /bs/. The book-keeping machinery explodes. > > Also, it uses no filters, i.e. no individual number divisibility testing. > > The "filters" refers first of all to testing an individual number to decide > > whether to keep it in or not. > > Umm, the postponed filters says keep everything until p^2, then eliminate > (filter out, remove) multiples of p in the remainder, after that, pick next > prime. > That's precisely what the above does. It doesn't do the filtering out by > divisibility testing but by minus (hence more efficiently). I would say > that's a variant of the postponed filters. > Filter is usually (as in Haskell's 'filter') is about testing individual elements by a predicate function. There is of course a filtering effect in two lists elts' comparison that 'minus' performs, so that's debatable. Even the PQ code performs "filtering" in this wider sense. > > > Euler's sieve is never attempting to remove a number more than once, > > > that's > > > > How's that possible? > > http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Euler.27s_Sieve > > C) The number after the previous prime is also a prime. *Multiply each > number /that's left/ > in the list starting from this prime by this prime and discard the products*. yes. Wasn't paying attention to that, more to the "intent" of it. There's of course enourmous vagueness in how exactly it is to be performed, in the unbounded case, which you uncovered here. > > It can't have foresight, right? > > > > But it has :) By only trying to eliminates products of the prime p > currently under consideration *with numbers (>= p) /which have not/ > /yet been eliminated/ from the list*, it is known in advance that all these > products are still in the list. missed that. > When p is under consideration, the list contains (apart from the primes < p) precisely the numbers whose smallest prime factor is >= p. > > > > the outstanding feature of it. Unfortunately, that also makes it hard to > > > implement efficiently. The problem is that you can't forget the primes > > > between p and p^2, you must remember them for the removal of multiples of > > > p later on. not just primes - all the composites not yet removed, too. So it can't even be implemented on shared mutable storage if we want to delay the removal (as we must, in unbounded case) - the composites will get removed so their multiples must actually all be produced first! > > The more pressing problem with that code is its linear structure of course > > which gets addressed by the tree-folding merge etc. > > > > Which unfortunately introduces its own space problem :( > Try a different minus: > > xxs (x:xs) `minus` yys (y:ys) > = case compare x y of > LT -> x : xs `minus` yys > EQ -> xs `minus` ys > GT -> error ("trying to remove " ++ show y ++ " a second time") > > Your code is not. It is, however, much faster. I understand now. Thanks! > > > Its performance is really horrible though. exponential, empyrically as well. > It just occured to me that the accumulation list is just > (takeWhile (< head cs) (p:ps)), so we could improve it as > > euler (p:ps) cs = h ++ euler ps (t `minus` comps) > where > (h,t) = span (< p*p) cs > comps = map (*p) (takeWhile (< head cs) (p:ps) ++ cs) > > Still Bad. yes, _both_ /t/ and /comps/ have their back-pointers into cs. > > No point in improving > > anything until the linear structure isn't turned into a tree. > > > You're a tree hugger? :D > No, the point isn't linear vs. tree, it's that Euler's sieve is a) great for > theoretical reasoning (look at a proof of Euler's product formula for the > (Riemann) Zeta-function to appreciate it) b) reasonably good for sieving > with a list of numbers written on paper, but c) not good to implement on a > computer. For the computer, keeping track of which numbers are left is so > much more complicated than just ticking off numbers a couple of times that > it isn't even worth attempting it. > > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From daniel.is.fischer at web.de Tue Jan 5 09:36:08 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Tue Jan 5 09:10:47 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001050033.03373.daniel.is.fischer@web.de> Message-ID: <201001051536.09008.daniel.is.fischer@web.de> Am Dienstag 05 Januar 2010 14:49:58 schrieb Will Ness: > > ... There are two attempts to eliminate 45. > > I would say there are two requests to not have 45 in the output. > Thers are many possible ways to phrase it. > > > I don't see any problem here. As Melissa (and yourself, I think) have > > > shown, double hits on multiples are few and far between. > > > > It's not a problem, it just means it's not Euler's sieve, because that > > attempts to eliminate each composite exactly once. > > yes I see now. My bad. Wasn't reading that wikipedia page with enough > attention to detail. It uses the modified (culled, so far) numbers to find > out the next multiples to be eliminated, Minor factual error, no big deal. > not just the prime itself like my code does. Which is operationally far better because it's much simpler :) > > You solution is indeed, exponential: > > euler ks@(p:rs) = p : euler (rs `minus` map (*p) ks) > primes = 2:euler [3,5..] > > > primes > = 2:euler (as@[3,5..]) > 3:euler (bs@(tail as `minus` map (3*) as)) > 5:euler (cs@(tail bs `minus` map (5*) bs)) > > > There are two separate look-back pointers to /as/ in /bs/, and there are > two such in /cs/, to /bs/. The book-keeping machinery explodes. > > > > Also, it uses no filters, i.e. no individual number divisibility > > > testing. The "filters" refers first of all to testing an individual > > > number to decide whether to keep it in or not. > > > > Umm, the postponed filters says keep everything until p^2, then eliminate > > (filter out, remove) multiples of p in the remainder, after that, pick > > next prime. > > That's precisely what the above does. It doesn't do the filtering out by > > divisibility testing but by minus (hence more efficiently). I would say > > that's a variant of the postponed filters. > > Filter is usually (as in Haskell's 'filter') is about testing individual > elements by a predicate function. There is of course a filtering effect in > two lists elts' comparison that 'minus' performs, so that's debatable. Even > the PQ code performs "filtering" in this wider sense. > I understood the 'filters' in postponed filters in that wider sense. And I would also find it perfectly acceptable to say that the PQ code filters out the composites from the stream. Of course if you're used to using 'filter' only in the stricter sense, you wouldn't call the `minus` thing a variant of the postponed filters. > > not just primes - all the composites not yet removed, too. Between p and p^2, there are only primes left, fortunately. > So it can't even be implemented on shared mutable storage if we > want to delay the removal (as we must, in unbounded case) - Yes. And it's not nice in the bounded case either. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100105/6af47159/attachment-0001.html From vanenkj at gmail.com Tue Jan 5 09:50:32 2010 From: vanenkj at gmail.com (John Van Enk) Date: Tue Jan 5 09:23:33 2010 Subject: [Haskell-cafe] Re: Re: Data.Ring -- Pre-announce In-Reply-To: <7ca3f0161001042353v3bf28512m52caa27f82d14939@mail.gmail.com> References: <1262613072.13413.64.camel@picard> <7ca3f0161001040617w1a67529crb513c4c926564c6a@mail.gmail.com> <1262636003.13413.74.camel@picard> <7ca3f0161001042353v3bf28512m52caa27f82d14939@mail.gmail.com> Message-ID: For those interested, the version of data-clist without Empty is here: http://github.com/sw17ch/data-clist/tree/noEmpty On Tue, Jan 5, 2010 at 2:53 AM, Luke Palmer wrote: > On Mon, Jan 4, 2010 at 1:13 PM, Maciej Piechotka > wrote: > > However then we lost the monoid (ok. I haven't send patch but please > > accept[1]) along with alternative/monad plus - which is much more > > popular, standard and useful then Copointed/Comonad. > > This point is a self-fulfilling prophecy. We don't have very much > experience working with copointeds and comonads, but I don't think > that makes them useless, just unfamiliar. > > "One must never confuse what is natural with what is habitual." -- > Mahatma Gandhi > > Luke > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100105/f656b072/attachment.html From ekmett at gmail.com Tue Jan 5 09:52:58 2010 From: ekmett at gmail.com (Edward Kmett) Date: Tue Jan 5 09:25:57 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <20100104221453.GC19757@inria.fr> References: <20100104221453.GC19757@inria.fr> Message-ID: <7fb8f82f1001050652i20697d4as9a377dcf412e2dfc@mail.gmail.com> Given fmap id = id, fmap (f . g) = fmap f . fmap g follows from the free theorem for fmap. This was published as an aside in a paper a long time back, but I forget where. -Edward Kmett On Mon, Jan 4, 2010 at 5:14 PM, Paul Brauner wrote: > Hi, > > I'm trying to get a deep feeling of Functors (and then pointed Functors, > Applicative Functors, etc.). To this end, I try to find lawless > instances of Functor that satisfy one law but not the other. > > I've found one instance that satisfies fmap (f.g) = fmap f . fmap g > but not fmap id = id: > > data Foo a = A | B > > instance Functor Foo where > fmap f A = B > fmap f B = B > > -- violates law 1 > fmap id A = B > > -- respects law 2 > fmap (f . g) A = (fmap f . fmap g) A = B > fmap (f . g) B = (fmap f . fmap g) B = B > > But I can't come up with an example that satifies law 1 and not law 2. > I'm beginning to think this isn't possible but I didn't read anything > saying so, neither do I manage to prove it. > > I'm sure someone knows :) > > Paul > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100105/3afef664/attachment.html From apfelmus at quantentunnel.de Tue Jan 5 10:16:42 2010 From: apfelmus at quantentunnel.de (Heinrich Apfelmus) Date: Tue Jan 5 09:50:03 2010 Subject: [Haskell-cafe] Re: lawless instances of Functor In-Reply-To: <625b74081001041542u68a94499xb17995f42b590fd8@mail.gmail.com> References: <20100104221453.GC19757@inria.fr> <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> <625b74081001041515u4c00f8fei4a2f6c8dea48e70a@mail.gmail.com> <61f84eff1001041526q45e79130lcf6cf257257de4c7@mail.gmail.com> <625b74081001041542u68a94499xb17995f42b590fd8@mail.gmail.com> Message-ID: Dan Piponi wrote: > Derek Elkins wrote: > >> Yes, I have the same problem...Basically, I'm >> pretty sure the construction of that free theorem doesn't rely on any >> of the actual details... > > For a long time I've thought such a higher order free theorem must > exist, and I've mentioned it to a few people, and searched hard for a > paper on it, but I haven't seen an actual statement and proof. > >> At this point, though, I haven't put >> much effort into proving that the free theorem holds uniformly > > Well I encourage you to as I've a hunch the correctly generalised > theorem will be quite pretty. I'd have a go but the style of proof for > these sorts of things is outside of my domain of > confidence/experience. This looks relevant: Janis Voigtl?nder. Free Theorems Involving Type Constructor Classes. http://wwwtcs.inf.tu-dresden.de/~voigt/icfp09.pdf Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com From ketil+haskell at malde.org Tue Jan 5 10:19:15 2010 From: ketil+haskell at malde.org (Ketil Malde) Date: Tue Jan 5 09:52:05 2010 Subject: [Haskell-cafe] 64-bit Bloom filters? Message-ID: <87hbr0lguk.fsf@malde.org> Hi, I've previously used Bloom filters on 32-bit Linux with some success. However, after upgrading to 64 bit, my Bloom filter applications crash or misbehave in random ways. So: is anybody successfully using Bloom filters on 64 bit computers? Although I'm not clear on why it would cause crashes (SEGV, infinite looping, etc), my prime suspect is the hashing function used. This is from C and returns a uint32, but it is imported to return a CInt, which I suspect is 64 bits. I'll look further into it, but I thought I'd check if anybody else has the same problem, and especially, a solution :-) -k -- If I haven't seen further, it is by standing in the footprints of giants From uzytkownik2 at gmail.com Tue Jan 5 10:49:13 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Tue Jan 5 10:22:34 2010 Subject: [Haskell-cafe] Re: 64-bit Bloom filters? In-Reply-To: <87hbr0lguk.fsf@malde.org> References: <87hbr0lguk.fsf@malde.org> Message-ID: <1262706553.6326.1.camel@picard> On Tue, 2010-01-05 at 16:19 +0100, Ketil Malde wrote: > Hi, > > I've previously used Bloom filters on 32-bit Linux with some success. > However, after upgrading to 64 bit, my Bloom filter applications crash > or misbehave in random ways. > > So: is anybody successfully using Bloom filters on 64 bit computers? > > Although I'm not clear on why it would cause crashes (SEGV, infinite > looping, etc), my prime suspect is the hashing function used. This is > from C and returns a uint32, but it is imported to return a CInt, which > I suspect is 64 bits. > On 64-bits Int can be either 32 or 64-bit. In theory it can be anything. It should use Data.Word.Word32 Regards From nccb2 at kent.ac.uk Tue Jan 5 11:39:19 2010 From: nccb2 at kent.ac.uk (Neil Brown) Date: Tue Jan 5 11:10:35 2010 Subject: [Haskell-cafe] [Very long] (CHP?) Compressing, MD5 and big files In-Reply-To: <1262536492.5358.47.camel@picard> References: <1262536492.5358.47.camel@picard> Message-ID: <4B436B37.408@kent.ac.uk> Hi, Sorry for the slightly delayed reply -- I didn't have time to look through all your code and understand it until just now. Your code has one (no doubt frustratingly!) small problem, which is in the deadlocking pipeline3: Maciej Piechotka wrote: >> pipeline3 :: CHP () >> pipeline3 = enrolling $ do >> file <- oneToManyChannel' $ chanLabel "File" >> fileGZ <- oneToOneChannel' $ chanLabel "File GZ" >> data_ <- oneToManyChannel' $ chanLabel "Data" >> compressed <- oneToManyChannel' $ chanLabel "Data Compressed" >> md5 <- oneToOneChannel' $ chanLabel "MD5" >> md5Compressed <- oneToOneChannel' $ chanLabel "MD5 Compressed" >> fileGZ' <- Enroll (reader file) >> fileData <- Enroll (reader file) >> dataMD5 <- Enroll (reader data_) >> dataCompress <- Enroll (reader data_) >> compressedFile <- Enroll (reader compressed) >> compressedMD5 <- Enroll (reader compressed) >> liftCHP $ runParallel_ [getFiles (writer file), >> (forever $ readChannel fileGZ' >>= >> writeChannel (writer fileGZ) . >> (++".gz")) >> `onPoisonRethrow` >> (poison fileGZ' >> poison (writer fileGZ)), >> readFromFile fileData (writer data_), >> calculateMD5 dataMD5 (writer md5), >> compressCHP dataCompress >> (writer compressed), >> writeToFile (reader fileGZ) compressedFile, >> calculateMD5 compressedMD5 >> (writer md5Compressed), >> forever $ readChannel dataMD5 >>= >> liftIO . print >> >> readChannel compressedMD5 >>= >> liftIO . print] >> > > Problems: > > (CHP) Thread terminated with: thread blocked indefinitely in an STM > transaction > < _b3, _b4, File GZ."test1.gz" > > Where you have "readChannel dataMD5" and "readChannel compressedMD5" in the last few lines, you actually meant to have "readChannel (reader md5)" and "readChannel (reader md5Compressed)". Your mistake meant that the former two channels were being used more times in parallel than you had enrolled and that the latter two channels were being written to but not read from. Either of these mistakes could cause deadlock, so hence why you were getting a strange deadlock. Unfortunately, the type system didn't save you this time, because the channel types happened to be the same. It took me a while to find it, too! On a side note, it would be good to have a static check for these mistakes (using a channel in parallel unsafely, and only using one end of a channel), but the only way I found to use Haskell's type-system for this is a rather nasty type-indexed monad. I guess if you use newChannelRW and name both the results, you would get an unused variable warning if you didn't use either end of the channel. This would fix one issue, but not the other. Hope that helps, Neil. From jmillikin at gmail.com Tue Jan 5 12:37:38 2010 From: jmillikin at gmail.com (John Millikin) Date: Tue Jan 5 12:10:56 2010 Subject: [Haskell-cafe] Using Haskell to write dbus server In-Reply-To: <1262685311.15115.1.camel@picard> References: <1262685311.15115.1.camel@picard> Message-ID: <3283f7fe1001050937r525fb5eav6563384d542e1ee6@mail.gmail.com> Why would you want to? Any conforming D-Bus client can connect to any conforming D-Bus server, so there's no particular advantage to having the same language on both ends of the connection. Additionally, there's a lot of fiddly low-level details (memory management, OS integration) which are difficult to implement in Haskell but relatively easy in C. The reference implementation of D-Bus has had an awful amount of work poured into making it stable and usable even in the face of external errors, such as out of memory -- replicating that work, in any language would be a pain. That isn't a rhetorical question, by the way -- I've written mostly-complete implementation of the client libraries, and intend to write a server at some point. But without a clear reason to write the server, it's just languishing on the TODO list. If you have any use for a Haskell D-Bus server which can't be served by the reference implementation, I'd be glad to hear it. On Tue, Jan 5, 2010 at 01:55, Maciej Piechotka wrote: > How to write (is it possible) a dbus server in Haskell? > > Regards > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From ryani.spam at gmail.com Tue Jan 5 12:59:34 2010 From: ryani.spam at gmail.com (Ryan Ingram) Date: Tue Jan 5 12:32:31 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> References: <20100104221453.GC19757@inria.fr> <61f84eff1001041501l787e5e02oa32a3e7af9876409@mail.gmail.com> Message-ID: <2f9b2d31001050959j689c09eew3a1c5da6daab1251@mail.gmail.com> On Mon, Jan 4, 2010 at 3:01 PM, Derek Elkins wrote: > So without doing funky stuff involving bottoms and/or seq, I believe > that fmap id = id implies the other functor law (in this case, not in > the case of the general categorical notion of functor.) So lets play with bottoms and/or seq. > data X a = X a > instance Functor X where > fmap f x = f `seq` case x of X a -> f a fmap id x = id `seq` case x of X a -> X (id a) = case x of X a -> X a = id x fmap (const () . undefined) x = fmap (\a -> const () (undefined a)) x = fmap (\a -> ()) x = case x of X a -> X () (fmap (const ()) . fmap undefined) x = fmap (const ()) (fmap undefined x) = const () `seq` case (fmap undefined x) of X a -> X () = case (fmap undefined x) of X a -> X ()) = case (undefined `seq` case x of X a -> X (undefined a)) of X a -> X () = case undefined of X a -> X () = undefined From bos at serpentine.com Tue Jan 5 13:02:11 2010 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue Jan 5 12:35:08 2010 Subject: [Haskell-cafe] 64-bit Bloom filters? In-Reply-To: <87hbr0lguk.fsf@malde.org> References: <87hbr0lguk.fsf@malde.org> Message-ID: On Tue, Jan 5, 2010 at 7:19 AM, Ketil Malde > wrote: > I've previously used Bloom filters on 32-bit Linux with some success. > However, after upgrading to 64 bit, my Bloom filter applications crash > or misbehave in random ways. > I'll look into it. Do you have a simple repro? So: is anybody successfully using Bloom filters on 64 bit computers? > I developed all that code on a 64-bit box, but I haven't had occasion to use it recently. Although I'm not clear on why it would cause crashes (SEGV, infinite > looping, etc), my prime suspect is the hashing function used. This is > from C and returns a uint32, but it is imported to return a CInt, which > I suspect is 64 bits. > A CInt is 32 bits on the only 64-bit architecture that anyone really uses (x86_64) :-) -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100105/6f0ec5be/attachment.html From tux_rocker at reinier.de Tue Jan 5 13:18:23 2010 From: tux_rocker at reinier.de (Reinier Lamers) Date: Tue Jan 5 12:51:38 2010 Subject: [Haskell-cafe] darcs 2.4 beta 1 release Message-ID: <201001051918.38069.tux_rocker@reinier.de> Hi all, The darcs team would like to announce the immediate availability of darcs 2.4 beta 1. darcs 2.4 will contain many improvements and bugfixes compared to darcs 2.3.1. Highlights are the fast index-based diffing which is now used by all darcs commands, and the interactive hunk-splitting in darcs record. This beta is your chance to test-drive these improvements and make darcs even better. If you have installed the Haskell Platform or cabal-install, you can install this beta release by doing: $ cabal update $ cabal install --reinstall darcs-beta Alternatively, you can download the tarball from http://darcs.net/releases/darcs-2.3.98.1.tar.gz , and build it by hand as explained in the README file. A list of important changes since 2.3.1 is as follows (please let me know if there's something you miss!): * Use fast index-based diffing everywhere (Petr) * Interactive patch splitting (Ganesh) * An 'optimize --upgrade' option to convert to hashed format in-place (Eric) * Hunk matching (Kamil Dworakowski, tat.wright) * Progress reporting is no longer deceptive (Roman Pl??il) * A 'remove --recursive' option to remove a directory tree from revision control (Roman Pl??il) * A '--remote-darcs' flag for pushing to a host where darcs isn't called darcs * Many miscellaneous Windows improvements (Salvatore, Petr and others) * 'darcs send' now mentions the repository name in the email body (Joachim) * Handle files with boring names in the repository correctly (Petr) * Fix parsing of .authorspellings file (Tom?? Caitt) * Various sane new command-line option names (Florent) * Remove the '--checkpoint' option (Petr) * Use external libraries for all UTF-8 handling (Eric, Reinier) * Use the Haskell zlib package exclusively for compression (Petr) Kind Regards, the darcs release manager, Reinier Lamers -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: This is a digitally signed message part. Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100105/e39a2cd3/attachment.bin From uzytkownik2 at gmail.com Tue Jan 5 13:19:19 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Tue Jan 5 12:52:18 2010 Subject: [Haskell-cafe] Using Haskell to write dbus server In-Reply-To: <3283f7fe1001050937r525fb5eav6563384d542e1ee6@mail.gmail.com> References: <1262685311.15115.1.camel@picard> <3283f7fe1001050937r525fb5eav6563384d542e1ee6@mail.gmail.com> Message-ID: <1262715559.6326.18.camel@picard> On Tue, 2010-01-05 at 09:37 -0800, John Millikin wrote: > Why would you want to? > > Any conforming D-Bus client can connect to any conforming D-Bus > server, so there's no particular advantage to having the same language > on both ends of the connection. Additionally, there's a lot of fiddly > low-level details (memory management, OS integration) which are > difficult to implement in Haskell but relatively easy in C. The > reference implementation of D-Bus has had an awful amount of work > poured into making it stable and usable even in the face of external > errors, such as out of memory -- replicating that work, in any > language would be a pain. > > That isn't a rhetorical question, by the way -- I've written > mostly-complete implementation of the client libraries, and intend to > write a server at some point. But without a clear reason to write the > server, it's just languishing on the TODO list. If you have any use > for a Haskell D-Bus server which can't be served by the reference > implementation, I'd be glad to hear it. Ok. I'll look on it. Maybe then I'll post the bindings (with some template haskell or similar) to hackage. The client have already established API (in terms of DBus) and is not in Haskell. Regards -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100105/dba570f0/attachment.bin From jmillikin at gmail.com Tue Jan 5 13:27:19 2010 From: jmillikin at gmail.com (John Millikin) Date: Tue Jan 5 13:00:36 2010 Subject: [Haskell-cafe] Using Haskell to write dbus server In-Reply-To: <1262715559.6326.18.camel@picard> References: <1262685311.15115.1.camel@picard> <3283f7fe1001050937r525fb5eav6563384d542e1ee6@mail.gmail.com> <1262715559.6326.18.camel@picard> Message-ID: <3283f7fe1001051027h7e96e9bcnaf5e1a09c4cf1ec8@mail.gmail.com> There's already three client libraries: http://hackage.haskell.org/package/dbus-client http://hackage.haskell.org/package/network-dbus http://hackage.haskell.org/package/DBus Perhaps there is some confusion? The D-Bus server, or "bus", is a service which allows many-to-many communication between clients. You do not need an implementation of the server in Haskell to use D-Bus in Haskell applications, and (to my knowledge) there is no API for the reference server. On Tue, Jan 5, 2010 at 10:19, Maciej Piechotka wrote: > On Tue, 2010-01-05 at 09:37 -0800, John Millikin wrote: >> Why would you want to? >> >> Any conforming D-Bus client can connect to any conforming D-Bus >> server, so there's no particular advantage to having the same language >> on both ends of the connection. Additionally, there's a lot of fiddly >> low-level details (memory management, OS integration) which are >> difficult to implement in Haskell but relatively easy in C. The >> reference implementation of D-Bus has had an awful amount of work >> poured into making it stable and usable even in the face of external >> errors, such as out of memory -- replicating that work, in any >> language would be a pain. >> >> That isn't a rhetorical question, by the way -- I've written >> mostly-complete implementation of the client libraries, and intend to >> write a server at some point. But without a clear reason to write the >> server, it's just languishing on the TODO list. If you have any use >> for a Haskell D-Bus server which can't be served by the reference >> implementation, I'd be glad to hear it. > > Ok. I'll look on it. Maybe then I'll post the bindings (with some > template haskell or similar) to hackage. The client have already > established API (in terms of DBus) and is not in Haskell. > > Regards > > From uzytkownik2 at gmail.com Tue Jan 5 13:43:56 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Tue Jan 5 13:17:02 2010 Subject: [Haskell-cafe] Using Haskell to write dbus server client exporting objects In-Reply-To: <3283f7fe1001051027h7e96e9bcnaf5e1a09c4cf1ec8@mail.gmail.com> References: <1262685311.15115.1.camel@picard> <3283f7fe1001050937r525fb5eav6563384d542e1ee6@mail.gmail.com> <1262715559.6326.18.camel@picard> <3283f7fe1001051027h7e96e9bcnaf5e1a09c4cf1ec8@mail.gmail.com> Message-ID: <1262717036.6326.27.camel@picard> On Tue, 2010-01-05 at 10:27 -0800, John Millikin wrote: > There's already three client libraries: > > http://hackage.haskell.org/package/dbus-client > http://hackage.haskell.org/package/network-dbus > http://hackage.haskell.org/package/DBus > > Perhaps there is some confusion? The D-Bus server, or "bus", is a > service which allows many-to-many communication between clients. You > do not need an implementation of the server in Haskell to use D-Bus in > Haskell applications, and (to my knowledge) there is no API for the > reference server. Hmm. Yes. By server I mean client server not the dbus daemon. I.e. the side which exports the objects. I.e. for me (my terminology is network-oriented[1]): - dbus server: something exporting objects. Eg. devkit, hal, nm - dbus client: something connecting to server/listining for signals etc. - dbus daemon: something running in background started by /etc/init.d/dbus start & with session - dbus bus: namespace in which servers and clients operates. Most popular as system and session buses (now I know there is one-to-one correspondence with daemons) I belive that last time I read dbus-client documentation was 'client'-oriented. Regards PS. I hope no ASCII ribbonner will kill me for using HTML in subject [1] Especially that there is xinetd daemon which runs ssh/ftp/... servers -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100105/7a18d3a0/attachment.bin From jmillikin at gmail.com Tue Jan 5 13:56:06 2010 From: jmillikin at gmail.com (John Millikin) Date: Tue Jan 5 13:29:23 2010 Subject: [Haskell-cafe] Using Haskell to write dbus server client exporting objects In-Reply-To: <1262717036.6326.27.camel@picard> References: <1262685311.15115.1.camel@picard> <3283f7fe1001050937r525fb5eav6563384d542e1ee6@mail.gmail.com> <1262715559.6326.18.camel@picard> <3283f7fe1001051027h7e96e9bcnaf5e1a09c4cf1ec8@mail.gmail.com> <1262717036.6326.27.camel@picard> Message-ID: <3283f7fe1001051056j291cb7b8s737b63256477f75a@mail.gmail.com> Ah, the issue is one of terminology. To me, "server" is the central bus, and "client" is any application which connects to the bus. Clients may send or receive any support message type. D-Bus doesn't actually have any mechanism for "exporting" objects; this is an abstraction, layered over the asynchronous message protocol. Any client library can "export" objects. Here is an example of using dbus-core and dbus-client to export some objects /hello and /world on the "org.test.exporting" name. It includes name registration, receiving method calls, sending replies, and sending errors: --------------------------------------------------------------------------------------------------- {-# LANGUAGE OverloadedStrings #-} import DBus.Bus import DBus.Client import DBus.Types import DBus.Constants import qualified Data.Map as Map import Control.Concurrent.MVar a x = LocalObject $ Map.fromList [ (mkInterfaceName' "test.iface_1", Interface $ Map.fromList [ (mkMemberName' "Foo", onFoo "a" x) , (mkMemberName' "Bar", onBar "a" x) ]) ] onFoo :: String -> String -> Member onFoo x y = Method (mkSignature' "") (mkSignature' "s") $ \call -> do putStrLn $ "Foo " ++ x ++ " " ++ y replyReturn call [toVariant $ "Foo " ++ x ++ " " ++ y] onBar :: String -> String -> Member onBar x y = Method (mkSignature' "") (mkSignature' "s") $ \call -> do putStrLn $ "Bar " ++ x ++ " " ++ y replyError call errorFailed [toVariant $ "Bar " ++ x ++ " " ++ y] main = do client <- mkClient =<< getSessionBus requestName client (mkBusName' "org.test.exporting") [] export client (mkObjectPath' "/hello") (a "hello") export client (mkObjectPath' "/world") (a "world") mvar <- newEmptyMVar takeMVar mvar --------------------------------------------------------------------------------------------------- On Tue, Jan 5, 2010 at 10:43, Maciej Piechotka wrote: > On Tue, 2010-01-05 at 10:27 -0800, John Millikin wrote: >> There's already three client libraries: >> >> http://hackage.haskell.org/package/dbus-client >> http://hackage.haskell.org/package/network-dbus >> http://hackage.haskell.org/package/DBus >> >> Perhaps there is some confusion? The D-Bus server, or "bus", is a >> service which allows many-to-many communication between clients. You >> do not need an implementation of the server in Haskell to use D-Bus in >> Haskell applications, and (to my knowledge) there is no API for the >> reference server. > > Hmm. Yes. By server I mean client server not the dbus daemon. I.e. the > side which exports the objects. > > I.e. for me (my terminology is network-oriented[1]): > - dbus server: something exporting objects. Eg. devkit, hal, nm > - dbus client: something connecting to server/listining for signals etc. > - dbus daemon: something running in background started > by /etc/init.d/dbus start & with session > - dbus bus: namespace in which servers and clients operates. Most > popular as system and session buses (now I know there is one-to-one > correspondence with daemons) > > I belive that last time I read dbus-client documentation was > 'client'-oriented. > > Regards > PS. I hope no ASCII ribbonner will kill me for using HTML in subject > > [1] Especially that there is xinetd daemon which runs ssh/ftp/... > servers > From uzytkownik2 at gmail.com Tue Jan 5 14:16:27 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Tue Jan 5 13:51:17 2010 Subject: [Haskell-cafe] Re: 64-bit Bloom filters? In-Reply-To: References: <87hbr0lguk.fsf@malde.org> Message-ID: <1262718987.6326.37.camel@picard> On Tue, 2010-01-05 at 10:02 -0800, Bryan O'Sullivan wrote: > > Although I'm not clear on why it would cause crashes (SEGV, > infinite > looping, etc), my prime suspect is the hashing function used. > This is > from C and returns a uint32, but it is imported to return a > CInt, which > I suspect is 64 bits. > > A CInt is 32 bits on the only 64-bit architecture that anyone really > uses (x86_64) :-) It does not depend on architecture but on compiler/C library: http://en.wikipedia.org/wiki/64-bit#Specific_data_models In most popular models (LLP64/LP64) it is 32-bits. However even SILP64 with 64-byte short is correct. Compiler having 16-bit integer on x86_64 is technically correct AFAIK (althought not on POSIX). Regards PS. Of course it is not the problem but it should not be done. There is nowhere written int's are 32-bits - in fact one of the reason they were left 32-bits (except having something between short and long) was incorrect assumption that they are. From apfelmus at quantentunnel.de Tue Jan 5 15:19:18 2010 From: apfelmus at quantentunnel.de (Heinrich Apfelmus) Date: Tue Jan 5 14:52:42 2010 Subject: [Haskell-cafe] Re: [darcs-users] Iteratees, streams, and mmap In-Reply-To: References: Message-ID: Jason Dagit wrote: > Heinrich Apfelmus wrote: > >> How about tracking the requirement of "bounded" in the type system? In >> particular, I'm thinking of a type class >> >> class NFData a => Small a >> >> where the idea is that all types that can be stored in constant space >> are members of this class. For example, we have >> >> instance Small () >> instance Small Int >> instance Small Char >> instance (Small a, Small b) => Small (a,b) >> instance (Small a, Small b) => Small (Either a b) >> >> but recursive types like [a] or String are not allowed to be members. On second (and late) thought, this idea is not as good as it sounds and needs more thought. The thing is if A is an instance of Small , we are not guaranteed that a value x :: A will take little memory, we are only guaranteed that its *normal form* takes little memory. Now, due to pervasive lazy evaluation, it's quite impossible to track whether a value is in normal form in the type system. > It seems like we also need: > instance Small (IO ()) > > Which is not necessarily bounded due to things like IORefs. [...] In the light of the above, I think this is related to the issue that we can't evaluate IO () to normal form at all, i.e. there is no deepSeq for values of type IO () . > I could also see us needing this: > > bracketSmall :: (Small c) => IO a -> (a -> IO b) -> (a -> IO c) -> IO c > > I'm not sure if b needs to be Small, since it's just supposed to be the > return value of the deallocation step. Thanks to parametricity, we know that b is thrown away, it can never appear in the result type c . > It seems that having functions like bracketSmall are > necessary if we want to hide the stream itself from being exposed outside of > the traversal function. For example, your foldlSmall doesn't leak, but > something at the same level of scope as it could leak the list. Yep, though this does have the unfortunate (?) consequence that we cannot use bracketSmall to return any large values anymore, even if they do not leak the stream. (A notion which literally gets "muddier" in the course of the program because it might be that c does not leak the vanilla stream, but for example every character of it.) Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com From tomahawkins at gmail.com Tue Jan 5 15:35:13 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Tue Jan 5 15:08:10 2010 Subject: [Haskell-cafe] Re: About Atom In-Reply-To: <840958.61670.qm@web112501.mail.gq1.yahoo.com> References: <840958.61670.qm@web112501.mail.gq1.yahoo.com> Message-ID: <594c1e831001051235t418d3b56q9d2b68b693c1e4ff@mail.gmail.com> On Tue, Jan 5, 2010 at 7:05 PM, CK Kashyap wrote: > Hi Tom, > Happy new year :) > I was wondering if I could use Atom for the purpose of an x86 operating system generator? Hi Kashyap, Ironically Atom was intended to eliminate the need for operating systems -- at least on small embedded projects. But yes, maybe it could be use develop an OS. (I've never written one, so I'm speaking way out of my comfort zone.) > I've explored Minix and wanted to get rid of all the noise introduced by C and focus on the logic. > I am sorry, I have not really explored Atom sufficiently but I am just too eager to know :) ... I have installed Atom using cabal - I was just going through Example.hs ... One thing I noticed is that the logic to calculate gcd was not clear from the implementation (Haskell side that is) ... Perhaps I am not reading it with the right perspective - can you elaborate it? > Also, why exactly did you name the whole thing Atom? Because an Atom design is composed of a bunch of small atomic operations. Take the GCD example: -- A rule to modify A. If a > b then set a = a - b. atom "a_minus_b" $ do cond $ value a >. value b a <== value a - value b -- A rule to modify B. If b > a then set b = b - a. atom "b_minus_a" $ do cond $ value b >. value a b <== value b - value a These independent rules periodically wake up and check their guard conditions (cond). If the guard condition is true, it performs the action atomically, in isolation from everything else in the system. In the case of the GCD example, the algorithm converges when a == b, at which point both the "a_minus_b" and "b_minus_a" rules are disabled. -Tom > Regards, > Kashyap > > > > > From tphyahoo at gmail.com Tue Jan 5 15:40:29 2010 From: tphyahoo at gmail.com (Thomas Hartman) Date: Tue Jan 5 15:13:31 2010 Subject: [Haskell-cafe] unexpected behavior / bug in try . System.FilePath.Find.findWithHandler Message-ID: <910ddf451001051240h65986bd8od3835a19af3c06d5@mail.gmail.com> say you want to execute a find function, but abort the computation if it hits any snags, such as an unreadable directory (eg chmod -R a-r dir). Currently try . System.FilePath.Find.findWithHandler will return an exception wrapped in Right, which seems Wrong. For sure it will just get ignored if wrapped in an ErrorT computation and I suspect this could lead to other glitchy/unexpected behavior when used in sysadmin scripts. You do get the expected exception wrapped in Left for certain errors (such as a missing directory), which adds to the confusion. Probable fix: you get the expected behavior if you remove unsafeInterleaveIO from findWithHandler. Does this seem like a reasonable thing to suggest to libraries@haskell? Hacky fix: I haven't actually done this, but I suppose you could trap stdout or stderr, since the exception does get printed although it's not reflected in the result type of the computation. demo of problem: import qualified System.FilePath.Find as F import System.FilePath.Find import System.IO.Error abort path err = fail $ path ++ " , " ++ (show err) prot = "/home/thartman/protected" -- a protected (unreadable) dir {- want result => Left user error (/home/thartman/protected , user error (/home/thartman/protected , /home/thartman/protected: getDirectoryContents: permission denied (Permission denied))) but get result Right *** Exception: user error (/home/thartman/protected , /home/thartman/protected: getDirectoryContents: permission denied (Permission denied)) which means, for example, you would miss the error if you wrapped this in an ErrorT there is probably a workaround from reading stderr, since it does get printed out, but this is awkward compared to just catching the error the right way and certainly feels like unexpected behavior Possible fix: you get the expected behavior if you remove unsafeInterleaveIO from System.FilePath.Find.findWithHandlers don't know why this fixes the problem, I was just messing around I don't know if this breaks anything else, but I was unable to find any breakage when I did a simple test on an unprotected directory What is the gain from unsafeInterleaveIO, and can it be nixed? -} tprot = try . findWithHandler abort (return True) (return True) $ prot tunprot = return . either (error . show) (length) =<< ( try $ findWithHandler abort (return True) (return True) unprot ) unprot = "/home/thartman/unprot" -- Need somewhere to put your code? http://patch-tag.com Want to build a webapp? http://happstack.com From will_n48 at yahoo.com Tue Jan 5 15:43:11 2010 From: will_n48 at yahoo.com (Will Ness) Date: Tue Jan 5 15:16:34 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001050033.03373.daniel.is.fischer@web.de> <201001051536.09008.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > > Am Dienstag 05 Januar 2010 14:49:58 schrieb Will Ness: > > > ... There are two attempts to eliminate 45. > > > > I would say there are two requests to not have 45 in the output. > > > Thers are many possible ways to phrase it. > > > > > You solution is indeed, exponential: > > > > euler ks@(p:rs) = p : euler (rs `minus` map (*p) ks) > > primes = 2:euler [3,5..] > > > > > > primes > > = 2:euler (as@[3,5..]) > > 3:euler (bs@(tail as `minus` map (3*) as)) > > 5:euler (cs@(tail bs `minus` map (5*) bs)) > > > > Re-write: euler s = head s:euler (tail s `minus` map(head s*) s) primes = euler [2..] primes = euler $ rollFrom [2] 1 = 2:euler ( rollFrom [3] 1 `minus` map(2*) (rollFrom [2] 1)) ) rollFrom [3,4] 2 `minus` rollFrom [4] 2 -- rollFrom [3] 2 -- = 2:3:euler (rollFrom [5] 2 `minus` map(3*) (rollFrom [3] 2)) rollFrom [5,7,9] 6 `minus` rollFrom [9] 6 -- rollFrom [5,7] 6 -- = 2:3:5:euler (rollFrom [7,11] 6 `minus` rollFrom [25,35] 30) [7,11, 13,17, 19,23, 25,29, 31,35] 30 -- rollFrom [7,11,13,17,19,23,29,31] 30 -- = ..... where rollOnce (x:xs) by = (x, tail xs ++ [x+by]) rollFrom xs by = concat $ iterate (map (+ by)) (xs) multRoll xs@(x:_) by p = takeWhile (< (x+p*by)) $ rollFrom xs by so, reifying, we get data Roll a = Roll [a] a rollOnce (Roll (x:xs) by) = (x,Roll (xs ++ [x+by]) by) rollFrom (Roll xs by) = concat $ iterate (map (+ by)) (xs) multRoll r@(Roll (x:_) by) p = Roll (takeWhile (< (x+p*by)) $ rollFrom r) (by*p) primes = euler $ Roll [2] 1 euler r@(Roll xs _) = x:euler (Roll (mxs `minus` map (x*) xs) mby) where (x,r') = rollOnce r (Roll mxs mby) = multRoll r' x There's much extra primes pre-calculated inside the Roll, of course (upto p^2 in fact, for p = primes!!n ), so this needs to be somehow tapped into, by writing a specialized nthPrime n = .... to be called instead of (!! n), and also primesUpTo n = .... This calculated primes !! 1000 == 7927 in 3 seconds for me, interpreted, on my old slowish laptop. It's supposed to have all the primes upto 7927^2 = 62837329 inside the Roll (if I'm not mistaken - or is it?). That's about 3.72 millionth prime, according to WolframAlpha. (nah, it cant be that much). But it is surely not horribly slow. Is this, in fact, the wheels' "spiral"? > > > > > not just primes - all the composites not yet removed, too. > > Between p and p^2, there are only primes left, fortunately. but (map (*p) ks) needs access to the original, non-culled numbers - primes, composites and all. (?) > > > So it can't even be implemented on shared mutable storage if we > > want to delay the removal (as we must, in unbounded case) - > > Yes. And it's not nice in the bounded case either. > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From sschuldenzucker at uni-bonn.de Tue Jan 5 16:15:40 2010 From: sschuldenzucker at uni-bonn.de (Steffen Schuldenzucker) Date: Tue Jan 5 15:48:55 2010 Subject: [Haskell-cafe] lawless instances of Functor In-Reply-To: <20100104232248.GA6757@seas.upenn.edu> References: <20100104221453.GC19757@inria.fr> <4B42707D.5010009@uni-bonn.de> <20100104232248.GA6757@seas.upenn.edu> Message-ID: <4B43ABFC.9020100@uni-bonn.de> Brent Yorgey wrote: > On Mon, Jan 04, 2010 at 11:49:33PM +0100, Steffen Schuldenzucker wrote: >> [...] > > As others have pointed out, this doesn't typecheck; but what it DOES > show is that if we had a type class > > class Endofunctor a where > efmap :: (a -> a) -> f a -> f a > > then it would be possible to write an instance for which efmap id = id > but efmap (f . g) /= efmap f . efmap g. The difference is that with > the normal Functor class, once you have applied your function f :: a > -> b to get a b, you can't do anything else with it, since you don't > know what b is. With the Endofunctor class, once you have applied f > :: a -> a, you CAN do something with the result: namely, apply f > again. Oops. Yeah, sorry, it's been ... late and stuff... Steffen From michael at snoyman.com Tue Jan 5 16:57:31 2010 From: michael at snoyman.com (Michael Snoyman) Date: Tue Jan 5 16:30:28 2010 Subject: [Haskell-cafe] GHC 6.12.1 FreeBSD binaries Message-ID: <29bf512f1001051357s3df9d2acs9253d6c52cd9bca4@mail.gmail.com> Does anyone know what the status is of the FreeBSD binaries for the most recent GHC release? In particular, I'm looking or FreeBSD 7.2 binaries. I tried building from source, but it says I don't have iconv library. I'm not enough of a FreeBSD guy to track this one down. Thanks, Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100105/6848a2f0/attachment.html From will_n48 at yahoo.com Tue Jan 5 17:16:35 2010 From: will_n48 at yahoo.com (Will Ness) Date: Tue Jan 5 16:49:57 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001040129.22689.daniel.is.fischer@web.de> <201001042225.29189.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > So we must make sure that the list of composites that primes' consumes is > not the same as that which primes'' consumes. yes that is what I had done too. Duplicated everything. Turns out, it works exactly as you told it would when using the compiler switch, -fno-cse, thanks! > > I used the switch; it didn't help at all. The only thing I can see is wrong. I didn't. When I did, it worked. > > Unfortunately it grows, as you've said - 23MB for 2 mln. :| > > And I've found out why. Change the definition of tfold to > > tfold f (a: ~(b: ~(c:xs))) > ???????????????????? = (a `f` (b `f` c)) `f` tfold f xs > > and memory stays low (things are going much slower, though). (forced by gmane poster to delete unusually many of your comments today...) Interesting... As for the structure, I chose it trying to minimize the estimated average cost of a composite production, Sum (1/p)*depth. > You can make a compromise by using the above tfold (which is no longer a > tree-fold) and grouping (and merging) the multiples in a slower-growing > manner, > ....... > > memory still grows, but much slower, in my tests, due to the much smaller > GC time, it's a bit faster than the version with the original tfold. Great! :) From will_n48 at yahoo.com Tue Jan 5 18:09:07 2010 From: will_n48 at yahoo.com (Will Ness) Date: Tue Jan 5 17:42:30 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001042225.29189.daniel.is.fischer@web.de> <201001050243.43208.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > > Am Montag 04 Januar 2010 22:25:28 schrieb Daniel Fischer: > > memory still grows, but much slower, in my tests, due to the much smaller > > GC time, it's a bit faster than the version with the original tfold. > > Not for larger inputs (but not so large that the tree-fold dies OOM). > Fix rfold: > > rfold f [x] = x > rfold f xs = rfold f (pairwise f xs) > > and it's faster also for those. Niiice!!!! This is just great! :) I tried a two-step feed BTW (that's three separate sets of lists) , with the original structure. It ran with same speed as your new version (10..20% faster) but with the memory of the previous one :) (80M for 8 mil primes vs the new one's 10M). But your new structure is just great! I hoped there is something better, that's why I posted it here in the first place. 'pairwise' puts odd leafs higher on the right. It might be better if it was so on the left, for the frequency of production is higher. Thanks a lot for your comments! > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From markl at glyphic.com Tue Jan 5 19:06:01 2010 From: markl at glyphic.com (Mark Lentczner) Date: Tue Jan 5 18:38:57 2010 Subject: [Haskell-cafe] ANN: uuid-0.1.2 Message-ID: <3B1D041B-766D-466B-81F9-727137770ABF@glyphic.com> Antione and I are please to announce the release of uuid-0.1.2. CHANGES: - added functions toByteString and fromByteString - added 'nil' UUID - added unit tests and benchmarks, built when configured -ftest - major speed up of to/from functions (as well as in general) - added version-3 generation (deterministic based on MD5) - major changes to internal representation - now uses four strict Word32 values - internal ByteSource classes for easy construction (see Builder.hs) - Storable instance now stores in memory as system libraries in C do: 16 bytes derived from the network order of the fields, no matter what the host native endianess is. - fixed bugs in V1 time and clock stepping, and V1 generated values - builds cleanly under GHC's -Wall - added CHANGES file String conversions were sped up 4x to 7x! - Mark Mark Lentczner (MtnViewMark) http://www.ozonehouse.com/mark/ From markl at glyphic.com Tue Jan 5 19:06:09 2010 From: markl at glyphic.com (Mark Lentczner) Date: Tue Jan 5 18:39:08 2010 Subject: [Haskell-cafe] Seven ways to store 16 bytes Message-ID: <42B275B8-983F-4E8C-9696-68953374D23C@glyphic.com> In preparing the speed ups in uuid-0.1.2, I investigated various ways to store 16 bytes of data in a Haskell object. Surprisingly, storing as 4 Word32 values in a standard data type worked best for that application. I've extracted out the testing work for that and put it here: http://bitbucket.org/mtnviewmark/haskell-playground/src/tip/16bytes/ There you can find the code that tests storing 16 bytes in various ways: > import qualified Data.Array as A > import qualified Data.Array.Unboxed as U > import qualified Data.Array.Vector as V > import qualified Data.ByteString as B > > data InBytes = BY !Word8 !Word8 !Word8 !Word8 !Word8 !Word8 !Word8 !Word8 > !Word8 !Word8 !Word8 !Word8 !Word8 !Word8 !Word8 !Word8 > deriving (Eq, Ord) > > data InWords = WO !Word32 !Word32 !Word32 !Word32 > deriving (Eq, Ord) > > data InList = LI [Word8] deriving (Eq, Ord) > data InByteString = BS B.ByteString deriving (Eq, Ord) > data InArray = AR (A.Array Int Word8) deriving (Eq, Ord) > data InUArray = UA (U.UArray Int Word8) deriving (Eq, Ord) > data InVector = VE (V.UArr Word8) deriving (Eq) Depending on operations will be needed most, different storage methods do best. Enjoy! - Mark Mark Lentczner (MtnViewMark) http://www.ozonehouse.com/mark/ From aslatter at gmail.com Tue Jan 5 19:27:30 2010 From: aslatter at gmail.com (Antoine Latter) Date: Tue Jan 5 19:00:28 2010 Subject: [Haskell-cafe] ANN: uuid-0.1.2 In-Reply-To: <3B1D041B-766D-466B-81F9-727137770ABF@glyphic.com> References: <3B1D041B-766D-466B-81F9-727137770ABF@glyphic.com> Message-ID: <694519c51001051627u4dc8045btadcc44df60c10ba@mail.gmail.com> 2010/1/5 Mark Lentczner : > Antione and I are please to announce the release of uuid-0.1.2. > Thanks for doing the heavy lifting on this one, Mark. Antoine From patrick.leboutillier at gmail.com Tue Jan 5 19:31:34 2010 From: patrick.leboutillier at gmail.com (Patrick LeBoutillier) Date: Tue Jan 5 19:04:33 2010 Subject: [Haskell-cafe] Interpreting profiling results In-Reply-To: <201001041605.45336.daniel.is.fischer@web.de> References: <201001041605.45336.daniel.is.fischer@web.de> Message-ID: On Mon, Jan 4, 2010 at 10:05 AM, Daniel Fischer wrote: > Am Montag 04 Januar 2010 02:17:06 schrieb Patrick LeBoutillier: > >> Hi, > >> > >> This question didn't get any replies on the beginners list, I thought > >> I'd try it here... > > Sorry, been occupied with other things. I already took a look, but hadn't > anything conclusive enough to reply yet. No sweat... I didn't mean to be pushy :) Thanks a lot for all the pointers, they have speeded up my code a lot. Patrick > >> > >> I've written (and improved using other solutions I've found on the > >> net) a simple sudoku solver which I'm trying to profile. Here is the > >> code: > >> > >> > >> import Array > > Better > > import Data.Array.Unboxed > > *much* faster > >> import List (transpose, nub, (\\)) > >> import Data.List > >> > >> data Sudoku = Sudoku { unit :: Int, cells :: Array (Int, Int) Int, > > cells :: UArray (Int,Int) Int > >> holes :: [(Int, Int)] } > >> > >> cell :: Sudoku -> (Int, Int) -> Int > >> cell s i = (cells s) ! i > >> > >> instance Read Sudoku where > >> ?readsPrec _ s = [(Sudoku unit cells holes, "")] > >> ? ?where unit = length . words . head . lines $ s > >> ? ? ? ? ?cells = listArray ((1, 1), (unit, unit)) (map read . words $ s) > >> ? ? ? ? ?holes = [ c | c <- indices cells, (cells ! c) == 0] > >> > >> instance Show Sudoku where > >> ?show s = unlines [unwords [show $ cell s (x,y) | x <- [1 .. unit s]] > >> > >> | y <- [1 .. unit s]] > >> > >> genNums :: Sudoku -> (Int, Int) -> [Int] > >> genNums s c@(i,j) = ([1 .. u] \\) . nub $ used > >> ?where > > nub isn't nice. It's quadratic in the length of the list. Use e.g. > > map head . group . sort > > or > > Data.[Int]Set.toList . Data.[Int]Set.fromList > > if the type is in Ord (and you don't need the distinct elements in the order > they come in). That gives an O(n*log n) nub with a sorted result. > > And (\\) isn't particularly fast either (O(m*n), where m and n are the > lengths of the lists). If you use one of the above instead of nub, you can > use the O(min m n) 'minus' for sorted lists: > > xxs@(x:xs) `minus` yys@(y:ys) > > | x < y = x : xs `minus` yys > > | x == y = xs `minus` ys > > | otherwise = xxs `minus` ys > > xs `minus` _ = xs > > Here, you can do better: > > genNums s c@(i,j) = nums > > where > > nums = [n | n <- [1 .. u], arr!n] > > arr :: [U]Array Int Bool > > arr = accumArray (\_ _ -> False) True (0,u) used > >> ? ?used = (row s u i j) ++ (col s u i j) ++ (square s sq u i j) > >> ? ?u = unit s > > Not good to calculate sq here. You'll use it many times, calculate once and > store it in s. > >> ? ?sq = truncate . sqrt . fromIntegral $ u > >> > >> row s u i j = [cell s (i, y) | y <- [1 .. u]] > >> > >> col s u i j = [cell s (x, j) | x <- [1 .. u]] > >> > >> square s sq u i j = [cell s (x, y) | y <- [1 .. u], x <- [1 .. u], f x i, >> f > >> y j] where f a b = div (a-1) sq == div (b-1) sq > > Test for f y j before you generate x to skip early. > > square s sq u i j = [cell s (ni+x,nj+y) | x <- [1 .. sq], y <- [1 .. sq]] > > where > > qi = (i-1) `div` sq > > qj = (j-1) `div` sq > > ni = qi*sq > > nj = qj*sq > >> > >> solve :: Sudoku -> [Sudoku] > >> solve s = > >> ?case holes s of > >> ? ?[] -> [s] > >> ? ?(h:hs) -> do > >> ? ? ?n <- genNums s h > >> ? ? ?let s' = Sudoku (unit s) ((cells s) // [(h, n)]) hs > >> ? ? ?solve s' > >> > >> main = print . head . solve . read =<< getContents > >> > >> > >> When I compile as such: > >> > >> $ ghc -O2 --make Sudoku.hs -prof -auto-all -caf-all -fforce-recomp > >> > >> and run it on the following puzzle: > >> > >> 0 2 3 4 > >> 3 4 1 0 > >> 2 1 4 0 > >> 0 3 2 1 > >> > >> I get the following profiling report: > >> > >> ? ? ? ?Fri Jan ?1 10:34 2010 Time and Allocation Profiling Report ?(Final) > >> > >> ? ? ? ? ? Sudoku +RTS -p -RTS > >> > >> ? ? ? ?total time ?= ? ? ? ?0.00 secs ? (0 ticks @ 20 ms) > > That means the report is basically useless. Not entirely, because the > allocation figures may already contain useful information. Run on a 9x9 > puzzle (a not too hard one, but not trivial either). > > Also, run the profiling with -P instead of -p, you'll get more info about > time and allocation then. > >> ? ? ? ?total alloc = ? ? 165,728 bytes ?(excludes profiling overheads) > >> > >> COST CENTRE ? ? ? ? ? ? ? ? ? ?MODULE ? ? ? ? ? ? ? %time %alloc > >> > >> CAF ? ? ? ? ? ? ? ? ? ? ? ? ? ?GHC.Handle ? ? ? ? ? ? 0.0 ? 10.7 > >> CAF ? ? ? ? ? ? ? ? ? ? ? ? ? ?Text.Read.Lex ? ? ? ? ?0.0 ? ?2.1 > >> CAF ? ? ? ? ? ? ? ? ? ? ? ? ? ?GHC.Read ? ? ? ? ? ? ? 0.0 ? ?1.2 > >> square ? ? ? ? ? ? ? ? ? ? ? ? Main ? ? ? ? ? ? ? ? ? 0.0 ? ?2.8 > >> solve ? ? ? ? ? ? ? ? ? ? ? ? ?Main ? ? ? ? ? ? ? ? ? 0.0 ? ?1.3 > >> show_aVx ? ? ? ? ? ? ? ? ? ? ? Main ? ? ? ? ? ? ? ? ? 0.0 ? ?3.7 > >> readsPrec_aYF ? ? ? ? ? ? ? ? ?Main ? ? ? ? ? ? ? ? ? 0.0 ? 60.6 > >> main ? ? ? ? ? ? ? ? ? ? ? ? ? Main ? ? ? ? ? ? ? ? ? 0.0 ? ?9.6 > >> genNums ? ? ? ? ? ? ? ? ? ? ? ?Main ? ? ? ? ? ? ? ? ? 0.0 ? ?5.0 > >> cell ? ? ? ? ? ? ? ? ? ? ? ? ? Main ? ? ? ? ? ? ? ? ? 0.0 ? ?1.2 > >> > >> > >> > >> ? ? ? ? ? ? ? ? ? ? ? ?individual ? ?inherited > >> COST CENTRE ? ? ? ? ? ? ?MODULE > >> ? ? ? no. ? ?entries ?%time %alloc ? %time %alloc > >> > >> MAIN ? ? ? ? ? ? ? ? ? ? MAIN > >> ? ? ? ? 1 ? ? ? ? ? 0 ? 0.0 ? ?0.3 ? ? 0.0 ?100.0 > >> ?main ? ? ? ? ? ? ? ? ? ?Main > >> ? ? ? 186 ? ? ? ? ? 1 ? 0.0 ? ?9.6 ? ? 0.0 ? 85.6 > >> ?show_aVx ? ? ? ? ? ? ? Main > >> ? ? ? 196 ? ? ? ? ? 2 ? 0.0 ? ?3.7 ? ? 0.0 ? ?3.7 > >> ? cell ? ? ? ? ? ? ? ? ?Main > >> ? ? ? 197 ? ? ? ? ?16 ? 0.0 ? ?0.0 ? ? 0.0 ? ?0.0 > >> ?solve ? ? ? ? ? ? ? ? ?Main > >> ? ? ? 188 ? ? ? ? ? 5 ? 0.0 ? ?1.3 ? ? 0.0 ? 11.8 > >> ? genNums ? ? ? ? ? ? ? Main > >> ? ? ? 189 ? ? ? ? ? 8 ? 0.0 ? ?5.0 ? ? 0.0 ? 10.4 > >> ? ?square ? ? ? ? ? ? ? Main > >> ? ? ? 194 ? ? ? ? ?88 ? 0.0 ? ?2.8 ? ? 0.0 ? ?3.2 > >> ? ? cell ? ? ? ? ? ? ? ?Main > >> ? ? ? 195 ? ? ? ? ?16 ? 0.0 ? ?0.4 ? ? 0.0 ? ?0.4 > >> ? ?col ? ? ? ? ? ? ? ? ?Main > >> ? ? ? 192 ? ? ? ? ? 4 ? 0.0 ? ?0.7 ? ? 0.0 ? ?1.1 > >> ? ? cell ? ? ? ? ? ? ? ?Main > >> ? ? ? 193 ? ? ? ? ?16 ? 0.0 ? ?0.4 ? ? 0.0 ? ?0.4 > >> ? ?row ? ? ? ? ? ? ? ? ?Main > >> ? ? ? 190 ? ? ? ? ? 4 ? 0.0 ? ?0.7 ? ? 0.0 ? ?1.1 > >> ? ? cell ? ? ? ? ? ? ? ?Main > >> ? ? ? 191 ? ? ? ? ?16 ? 0.0 ? ?0.4 ? ? 0.0 ? ?0.4 > >> ?readsPrec_aYF ? ? ? ? ?Main > >> ? ? ? 187 ? ? ? ? ? 3 ? 0.0 ? 60.6 ? ? 0.0 ? 60.6 > >> ?CAF ? ? ? ? ? ? ? ? ? ? GHC.Read > >> ? ? ? 151 ? ? ? ? ? 1 ? 0.0 ? ?1.2 ? ? 0.0 ? ?1.2 > >> ?CAF ? ? ? ? ? ? ? ? ? ? Text.Read.Lex > >> ? ? ? 144 ? ? ? ? ? 8 ? 0.0 ? ?2.1 ? ? 0.0 ? ?2.1 > >> ?CAF ? ? ? ? ? ? ? ? ? ? GHC.Handle > >> ? ? ? 128 ? ? ? ? ? 4 ? 0.0 ? 10.7 ? ? 0.0 ? 10.7 > >> ?CAF ? ? ? ? ? ? ? ? ? ? GHC.Conc > >> ? ? ? 127 ? ? ? ? ? 1 ? 0.0 ? ?0.0 ? ? 0.0 ? ?0.0 > >> > >> Does the column 'entries' represent the number of times the function > >> was called? > > Number of times it was 'entered', not quite the same as the number of times > it was called. > > I think (Warning: speculation ahead, I don't *know* how the profiles are > generated) it's thus: > > Say you call a function returning a list. One call, first entry. It finds > the beginning of the list, the first k elements and hands them to the > caller. Caller processes these, asks "can I have more, or was that it?". > Same call, second entry: f looks for more, finds the next m elements, hands > them to caller. Caller processes. Repeat until whatever happens first, > caller doesn't ask whether there's more or callee finds there's nothing more > (or hits bottom). > >> If so, I don't understand how the 'square' function could > >> be called 88 times when it's caller is only called 8 times. Same thing > >> with 'genNums' (called 8 times, and solve called 5 times) > >> > >> What am I missing here? > >> > >> Patrick -- ===================== Patrick LeBoutillier Rosem?re, Qu?bec, Canada From felipe.lessa at gmail.com Tue Jan 5 19:36:27 2010 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Tue Jan 5 19:09:29 2010 Subject: [Haskell-cafe] Seven ways to store 16 bytes In-Reply-To: <42B275B8-983F-4E8C-9696-68953374D23C@glyphic.com> References: <42B275B8-983F-4E8C-9696-68953374D23C@glyphic.com> Message-ID: <20100106003627.GC19323@kira.casa> On Tue, Jan 05, 2010 at 04:06:09PM -0800, Mark Lentczner wrote: > In preparing the speed ups in uuid-0.1.2, I investigated > various ways to store 16 bytes of data in a Haskell object. > Surprisingly, storing as 4 Word32 values in a standard data > type worked best for that application. However, on an Core 2 Duo in x86-64 mode with GHC 6.10, 2 Word64 values wins over 4 Word32 values. Attached is the modified source code. Here is the summary between them equal-itself/words 76.41 ns equal-itself/words64 64.52 ns equal-same/words 79.64 ns equal-same/words64 67.85 ns equal-differ/words 66.11 ns equal-differ/words64 62.79 ns compare-same/words 80.59 ns compare-same/words64 68.68 ns compare-differ/words 67.14 ns compare-differ/words64 64.22 ns toList-and-sum/words 991.32 ns toList-and-sum/words64 839.45 ns map-and-sum/words 1.04 us map-and-sum/words64 1.12 us fold-and-sum/words 882.88 ns fold-and-sum/words64 755.98 ns fromList-and-eq/words 740.41 ns fromList-and-eq/words64 749.07 ns build-and-eq/words 484.54 ns build-and-eq/words64 447.81 ns unfold-and-eq/words 577.12 ns unfold-and-eq/words64 541.46 ns Cheers, -- Felipe. -------------- next part -------------- A non-text attachment was scrubbed... Name: SixteenBytes.hs Type: text/x-haskell Size: 12452 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100105/e26aee96/SixteenBytes.bin From bos at serpentine.com Tue Jan 5 19:40:55 2010 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue Jan 5 19:13:53 2010 Subject: [Haskell-cafe] Seven ways to store 16 bytes In-Reply-To: <42B275B8-983F-4E8C-9696-68953374D23C@glyphic.com> References: <42B275B8-983F-4E8C-9696-68953374D23C@glyphic.com> Message-ID: 2010/1/5 Mark Lentczner > There you can find the code that tests storing 16 bytes in various ways: > > > data InWords = WO !Word32 !Word32 !Word32 !Word32 > > deriving (Eq, Ord) > > > > data InList = LI [Word8] deriving (Eq, Ord) > > data InByteString = BS B.ByteString deriving (Eq, Ord) > > data InArray = AR (A.Array Int Word8) deriving (Eq, Ord) > > data InUArray = UA (U.UArray Int Word8) deriving (Eq, Ord) > > data InVector = VE (V.UArr Word8) deriving (Eq) You've got an extra level of indirection there due to the use of data instead of newtype, so you're paying an additional boxing penalty for everything except your first case. Are you compiling with -funbox-strict-fields? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100105/56661ed4/attachment.html From felipe.lessa at gmail.com Tue Jan 5 20:25:38 2010 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Tue Jan 5 19:58:43 2010 Subject: [Haskell-cafe] Seven ways to store 16 bytes In-Reply-To: References: <42B275B8-983F-4E8C-9696-68953374D23C@glyphic.com> Message-ID: <20100106012538.GA24578@kira.casa> On Tue, Jan 05, 2010 at 04:40:55PM -0800, Bryan O'Sullivan wrote: > You've got an extra level of indirection there due to the use of data > instead of newtype, so you're paying an additional boxing penalty for > everything except your first case. Are you compiling with > -funbox-strict-fields? I've changed those data's to newtype's but using words still seems better, unless mapping and folding over bytes is more important. In that case maybe storing the bytes separately might be better. Maybe a more complex/realistic benchmark? I've also rerun the benchmark in a x86-32 chroot. In this environment Word32 seems to win over Word64. But, who cares about 32 bits anyway? ;) I'm attaching the source code and the summary results. Everything was compiled with 'ghc -fforce-recomp -O3'. -- Felipe. -------------- next part -------------- A non-text attachment was scrubbed... Name: SixteenBytes.hs Type: text/x-haskell Size: 12560 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100105/e041d985/SixteenBytes.bin -------------- next part -------------- equal-itself/bytes 154.48 ns equal-itself/words 73.11 ns equal-itself/words64 89.19 ns equal-itself/list 455.64 ns equal-itself/byteString 129.09 ns equal-itself/array 214.65 ns equal-itself/uArray 134.84 ns equal-itself/vector 575.81 ns equal-same/bytes 153.40 ns equal-same/words 74.95 ns equal-same/words64 84.43 ns equal-same/list 464.60 ns equal-same/byteString 157.38 ns equal-same/array 190.70 ns equal-same/uArray 136.00 ns equal-same/vector 584.04 ns equal-differ/bytes 78.01 ns equal-differ/words 62.94 ns equal-differ/words64 69.21 ns equal-differ/list 82.36 ns equal-differ/byteString 155.94 ns equal-differ/array 76.39 ns equal-differ/uArray 83.74 ns equal-differ/vector 545.27 ns compare-same/bytes 139.47 ns compare-same/words 76.23 ns compare-same/words64 90.45 ns compare-same/list 470.13 ns compare-same/byteString 83.46 ns compare-same/array 458.69 ns compare-same/uArray 413.76 ns compare-same/vector 538.52 ns compare-differ/bytes 79.67 ns compare-differ/words 70.50 ns compare-differ/words64 84.21 ns compare-differ/list 83.46 ns compare-differ/byteString 83.83 ns compare-differ/array 93.82 ns compare-differ/uArray 94.27 ns compare-differ/vector 499.22 ns toList-and-sum/bytes 556.38 ns toList-and-sum/words 895.83 ns toList-and-sum/words64 1.15 us toList-and-sum/list 539.67 ns toList-and-sum/byteString 706.27 ns toList-and-sum/array 922.25 ns toList-and-sum/uArray 807.74 ns toList-and-sum/vector 871.35 ns map-and-sum/bytes 418.83 ns map-and-sum/words 865.35 ns map-and-sum/words64 1.21 us map-and-sum/list 547.88 ns map-and-sum/byteString 554.30 ns map-and-sum/array 672.47 ns map-and-sum/uArray 590.94 ns map-and-sum/vector 596.50 ns fold-and-sum/bytes 481.02 ns fold-and-sum/words 639.72 ns fold-and-sum/words64 865.86 ns fold-and-sum/list 304.06 ns fold-and-sum/byteString 341.16 ns fold-and-sum/array 632.82 ns fold-and-sum/uArray 522.96 ns fold-and-sum/vector 339.46 ns fromList-and-eq/bytes 790.68 ns fromList-and-eq/words 666.65 ns fromList-and-eq/words64 994.36 ns fromList-and-eq/list 778.35 ns fromList-and-eq/byteString 857.47 ns fromList-and-eq/array 933.95 ns fromList-and-eq/uArray 3.90 us fromList-and-eq/vector 1.40 us build-and-eq/bytes 568.29 ns build-and-eq/words 510.61 ns build-and-eq/words64 890.87 ns build-and-eq/list 1.03 us build-and-eq/byteString 824.19 ns build-and-eq/array 960.80 ns build-and-eq/uArray 3.79 us build-and-eq/vector 1.28 us unfold-and-eq/bytes 624.53 ns unfold-and-eq/words 565.21 ns unfold-and-eq/words64 875.83 ns unfold-and-eq/list 1.21 us unfold-and-eq/byteString 1.35 us unfold-and-eq/array 1.09 us unfold-and-eq/uArray 3.88 us unfold-and-eq/vector 1.19 us -------------- next part -------------- equal-itself/bytes 149.75 ns equal-itself/words 76.60 ns equal-itself/words64 63.62 ns equal-itself/list 516.47 ns equal-itself/byteString 141.86 ns equal-itself/array 192.89 ns equal-itself/uArray 145.88 ns equal-itself/vector 467.59 ns equal-same/bytes 152.78 ns equal-same/words 88.18 ns equal-same/words64 68.02 ns equal-same/list 523.40 ns equal-same/byteString 174.43 ns equal-same/array 192.97 ns equal-same/uArray 123.93 ns equal-same/vector 477.57 ns equal-differ/bytes 85.94 ns equal-differ/words 65.51 ns equal-differ/words64 63.60 ns equal-differ/list 89.86 ns equal-differ/byteString 174.97 ns equal-differ/array 81.49 ns equal-differ/uArray 81.89 ns equal-differ/vector 467.45 ns compare-same/bytes 155.65 ns compare-same/words 83.35 ns compare-same/words64 70.42 ns compare-same/list 475.55 ns compare-same/byteString 95.35 ns compare-same/array 736.59 ns compare-same/uArray 431.40 ns compare-same/vector 513.61 ns compare-differ/bytes 90.90 ns compare-differ/words 79.41 ns compare-differ/words64 93.59 ns compare-differ/list 136.76 ns compare-differ/byteString 94.89 ns compare-differ/array 105.18 ns compare-differ/uArray 103.92 ns compare-differ/vector 610.92 ns toList-and-sum/bytes 649.31 ns toList-and-sum/words 959.82 ns toList-and-sum/words64 1.02 us toList-and-sum/list 605.01 ns toList-and-sum/byteString 759.76 ns toList-and-sum/array 1.11 us toList-and-sum/uArray 942.17 ns toList-and-sum/vector 971.62 ns map-and-sum/bytes 512.01 ns map-and-sum/words 1.23 us map-and-sum/words64 1.25 us map-and-sum/list 693.42 ns map-and-sum/byteString 586.06 ns map-and-sum/array 838.49 ns map-and-sum/uArray 707.18 ns map-and-sum/vector 777.43 ns fold-and-sum/bytes 647.92 ns fold-and-sum/words 890.31 ns fold-and-sum/words64 910.96 ns fold-and-sum/list 301.64 ns fold-and-sum/byteString 399.00 ns fold-and-sum/array 696.64 ns fold-and-sum/uArray 564.33 ns fold-and-sum/vector 375.66 ns fromList-and-eq/bytes 1.01 us fromList-and-eq/words 819.08 ns fromList-and-eq/words64 822.43 ns fromList-and-eq/list 1.00 us fromList-and-eq/byteString 1.01 us fromList-and-eq/array 922.43 ns fromList-and-eq/uArray 4.49 us fromList-and-eq/vector 1.23 us build-and-eq/bytes 609.08 ns build-and-eq/words 532.92 ns build-and-eq/words64 498.30 ns build-and-eq/list 1.16 us build-and-eq/byteString 896.24 ns build-and-eq/array 866.45 ns build-and-eq/uArray 17.39 us build-and-eq/vector 1.19 us unfold-and-eq/bytes 807.60 ns unfold-and-eq/words 603.23 ns unfold-and-eq/words64 645.94 ns unfold-and-eq/list 1.38 us unfold-and-eq/byteString 1.46 us unfold-and-eq/array 1.08 us unfold-and-eq/uArray 4.44 us unfold-and-eq/vector 1.11 us From daniel.is.fischer at web.de Tue Jan 5 21:23:52 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Tue Jan 5 20:58:26 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001050243.43208.daniel.is.fischer@web.de> Message-ID: <201001060323.52877.daniel.is.fischer@web.de> Am Mittwoch 06 Januar 2010 00:09:07 schrieb Will Ness: > Daniel Fischer web.de> writes: > > Am Montag 04 Januar 2010 22:25:28 schrieb Daniel Fischer: > > > memory still grows, but much slower, in my tests, due to the much > > > smaller GC time, it's a bit faster than the version with the original > > > tfold. > > > > Not for larger inputs (but not so large that the tree-fold dies OOM). > > Fix rfold: > > > > rfold f [x] = x > > rfold f xs = rfold f (pairwise f xs) > > > > and it's faster also for those. > > Niiice!!!! This is just great! :) > > I tried a two-step feed BTW (that's three separate sets of lists) , with > the original structure. It ran with same speed as your new version (10..20% > faster) but with the memory of the previous one :) (80M for 8 mil primes vs > the new one's 10M). The memory is almost completely due to the tree-merging of the multiples for the fastest runner. While it produces faster than flat merging, the exponential growth of the trees makes a bad memory citizen. With the nwise and rfold, a two-step (or even three-step) feeding doesn't gain nearly as much (I found about 1% speedup). > But your new structure is just great! I hoped there is > something better, that's why I posted it here in the first place. > I have two more goodies :) 1. now that the trees don't grow so fast, don't use lazy patterns in the definition of tfold: tfold f (a:b:c:xs) = (a `f` (b `f` c)) `f` tfold f xs gains something like 6-7% here (and uses a little less memory). 2. Now we have a big wheel, 5760 differences per period. Then dropping a few thousand elements from the wheel after calculating how many in rollFrom is slow: rollFrom n = go ((n-17) `rem` 30030) wheel13 where go r xxs@(x:xs) | r < x = roll n xxs | otherwise = go (r-x) xs gains another couple of percents for large targets (~1% for the 10M prime, ~2% for 20M, I expect that to stay in th region of 1.5-3% for larger targets). > 'pairwise' puts odd leafs higher on the right. It might be better if it was > so on the left, for the frequency of production is higher. Maybe. But how would you do it? I tried passing the length to rfold, so when there was an odd numberof trees in the list, it would move the first out of the recursion. Any possible gains in production have been more than eaten up by the control code (not a big difference, but it was there). > > > Thanks a lot for your comments! -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100105/27cbb459/attachment.html From daniel.is.fischer at web.de Wed Jan 6 05:50:18 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Jan 6 05:24:51 2010 Subject: [Haskell-cafe] Hackage down Message-ID: <201001061150.18826.daniel.is.fischer@web.de> Just a heads up, hackage is down, doesn't respond to ping even, cabal update says cabal: : resource vanished -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100106/2c1d6ade/attachment.html From vandijk.roel at gmail.com Wed Jan 6 05:57:40 2010 From: vandijk.roel at gmail.com (Roel van Dijk) Date: Wed Jan 6 05:30:37 2010 Subject: [Haskell-cafe] Hackage down In-Reply-To: <201001061150.18826.daniel.is.fischer@web.de> References: <201001061150.18826.daniel.is.fischer@web.de> Message-ID: If you are desperate for some hackage you can at least browse packages on my reverse dependencies thingie: http://bifunctor.homelinux.net/~roel/hackage/packages/hackage.html The last update was the 4th of january. But it doesn't have the actual packages, so it is probably not so useful in this case. On Wed, Jan 6, 2010 at 11:50 AM, Daniel Fischer wrote: > Just a heads up, hackage is down, doesn't respond to ping even, cabal update > says > > cabal: : resource vanished From johan.tibell at gmail.com Wed Jan 6 07:38:31 2010 From: johan.tibell at gmail.com (Johan Tibell) Date: Wed Jan 6 07:11:47 2010 Subject: [Haskell-cafe] Reminder: ZuriHac - Haskell hackathon in Zurich, March 19-21 Message-ID: <90889fe71001060438n2b6bcbf9se71b11e037888e24@mail.gmail.com> Hi all! This is to remind you that we're organizing ZuriHac, a Haskell hackathon/get-together, to be held March 19-21 at the Google Office in Zurich, Switzerland. Lots of people have already registered but we still have space for more! If you plan on coming, please register [1] so we can make sure there's seating for everyone. Registration, travel, lodging and many other details will soon be available on the ZuriHac wiki [2]. If you have any questions don't hesitate to drop Christophe or me an email (or email addresses can be found on the wiki.) WHEN Friday March 19 2:30pm to 6:30pm Saturday March 20 10am to 6pm Sunday March 21 10am to 6pm WHERE We will be in the TechTalk area of the Google Office at Brandschenkestrasse 110. Please see the wiki [3] for directions. ORGANIZERS Johan Tibell Christophe Poucet Hope to see you in Zurich! - The ZuriHac team [1] http://haskell.org/haskellwiki/ZuriHac/Register [2] http://haskell.org/haskellwiki/ZuriHac [3] http://haskell.org/haskellwiki/ZuriHac#Getting_to_the_Google_Office From vandijk.roel at gmail.com Wed Jan 6 07:55:39 2010 From: vandijk.roel at gmail.com (Roel van Dijk) Date: Wed Jan 6 07:28:35 2010 Subject: [Haskell-cafe] Hackage down In-Reply-To: References: <201001061150.18826.daniel.is.fischer@web.de> Message-ID: I have downloaded the torrent with the hackage archive from 19 oktober 2009 and put it on my server. This means you can now download all the packages contained in that archive (only the latest versions at that date). Happy hacking, Roel On Wed, Jan 6, 2010 at 11:57 AM, Roel van Dijk wrote: > If you are desperate for some hackage you can at least browse packages > on my reverse dependencies thingie: > > http://bifunctor.homelinux.net/~roel/hackage/packages/hackage.html > > The last update was the 4th of january. But it doesn't have the actual > packages, so it is probably not so useful in this case. From ivan.miljenovic at gmail.com Wed Jan 6 08:51:10 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Wed Jan 6 08:24:14 2010 Subject: [Haskell-cafe] darcs 2.4 beta 1 release In-Reply-To: <201001051918.38069.tux_rocker@reinier.de> (Reinier Lamers's message of "Tue, 5 Jan 2010 19:18:23 +0100") References: <201001051918.38069.tux_rocker@reinier.de> Message-ID: <87fx6j8hpt.fsf@gmail.com> I really feel that bug 1720 [1] is a show-stopping bug for darcs, especially since it means that building Haddock for darcs with GHC-6.12.* isn't possible. [1] http://bugs.darcs.net/issue1720 I tried to make a fix, but didn't know enough of how darcs is documented to be able to do anything. Reinier Lamers writes: > Hi all, > > The darcs team would like to announce the immediate availability of darcs 2.4 > beta 1. darcs 2.4 will contain many improvements and bugfixes compared to > darcs 2.3.1. Highlights are the fast index-based diffing which is now used by > all darcs commands, and the interactive hunk-splitting in darcs record. This > beta is your chance to test-drive these improvements and make darcs even > better. > > If you have installed the Haskell Platform or cabal-install, you can install > this beta release by doing: > > $ cabal update > $ cabal install --reinstall darcs-beta > > Alternatively, you can download the tarball from > http://darcs.net/releases/darcs-2.3.98.1.tar.gz , and build it by hand as > explained in the README file. > > A list of important changes since 2.3.1 is as follows (please let me know if > there's something you miss!): > > * Use fast index-based diffing everywhere (Petr) > * Interactive patch splitting (Ganesh) > * An 'optimize --upgrade' option to convert to hashed format in-place > (Eric) > * Hunk matching (Kamil Dworakowski, tat.wright) > * Progress reporting is no longer deceptive (Roman Pl??il) > * A 'remove --recursive' option to remove a directory tree from revision > control (Roman Pl??il) > * A '--remote-darcs' flag for pushing to a host where darcs isn't called > darcs > * Many miscellaneous Windows improvements (Salvatore, Petr and others) > * 'darcs send' now mentions the repository name in the email body (Joachim) > * Handle files with boring names in the repository correctly (Petr) > * Fix parsing of .authorspellings file (Tom?? Caitt) > * Various sane new command-line option names (Florent) > * Remove the '--checkpoint' option (Petr) > * Use external libraries for all UTF-8 handling (Eric, Reinier) > * Use the Haskell zlib package exclusively for compression (Petr) > > Kind Regards, > the darcs release manager, > Reinier Lamers > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From miguelimo38 at yandex.ru Wed Jan 6 08:52:10 2010 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Wed Jan 6 08:27:57 2010 Subject: [Haskell-cafe] Explicit garbage collection Message-ID: <4B44958A.2080809@yandex.ru> Is there any kind of "ST" monad that allows to know if some STRef is no longer needed? The problem is, I want to send some data to an external storage over a network and get it back later, but I don't want to send unnecessary data. I've managed to do something like that with weak pointers, System.Mem.performGC and unsafePerformIO, but it seems to me that invoking GC every time is an overkill. Oh, and I'm ready to trade the purity of runST for that, if necessary. Thanks. From dan.doel at gmail.com Wed Jan 6 09:06:51 2010 From: dan.doel at gmail.com (Dan Doel) Date: Wed Jan 6 08:39:50 2010 Subject: [Haskell-cafe] Explicit garbage collection In-Reply-To: <4B44958A.2080809@yandex.ru> References: <4B44958A.2080809@yandex.ru> Message-ID: <201001060906.51127.dan.doel@gmail.com> On Wednesday 06 January 2010 8:52:10 am Miguel Mitrofanov wrote: > Is there any kind of "ST" monad that allows to know if some STRef is no > longer needed? > > The problem is, I want to send some data to an external storage over a > network and get it back later, but I don't want to send unnecessary data. > > I've managed to do something like that with weak pointers, > System.Mem.performGC and unsafePerformIO, but it seems to me that invoking > GC every time is an overkill. > > Oh, and I'm ready to trade the purity of runST for that, if necessary. You may be able to use something like Oleg's Lightweight Monadic Regions to get this effect. I suppose it depends somewhat on what qualifies a reference as "no longer needed". http://www.cs.rutgers.edu/~ccshan/capability/region-io.pdf I'm not aware of anything out-of-the-box that does what you want, though. -- Dan From will_n48 at yahoo.com Wed Jan 6 09:24:51 2010 From: will_n48 at yahoo.com (Will Ness) Date: Wed Jan 6 08:58:13 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001050033.03373.daniel.is.fischer@web.de> <201001051536.09008.daniel.is.fischer@web.de> Message-ID: Will Ness yahoo.com> writes: > > Daniel Fischer web.de> writes: > > > Am Dienstag 05 Januar 2010 14:49:58 schrieb Will Ness: > > > > > > euler ks@(p:rs) = p : euler (rs `minus` map (*p) ks) > > > primes = 2:euler [3,5..] > > > > > > > > Re-write: > > primes = euler $ rollFrom [2] 1 > = 2:euler ( rollFrom [3] 1 `minus` map(2*) (rollFrom [2] 1)) ) > rollFrom [3,4] 2 `minus` rollFrom [4] 2 > -- rollFrom [3] 2 -- > = 2:3:euler (rollFrom [5] 2 `minus` map(3*) (rollFrom [3] 2)) > rollFrom [5,7,9] 6 `minus` rollFrom [9] 6 > -- rollFrom [5,7] 6 -- > = 2:3:5:euler (rollFrom [7,11] 6 `minus` rollFrom [25,35] 30) > [7,11, 13,17, 19,23, 25,29, 31,35] 30 > -- rollFrom [7,11,13,17,19,23,29,31] 30 -- > = ..... > correction: where rollOnce (x:xs) by = (x, xs ++ [x+by]) rollFrom xs by = concat $ iterate (map (+ by)) (xs) multRoll xs@(x:_) by p = takeWhile (< (x+p*by)) $ rollFrom xs by > so, reifying, we get > > data Roll a = Roll [a] a > > rollOnce (Roll (x:xs) by) = (x,Roll (xs ++ [x+by]) by) > rollFrom (Roll xs by) = concat $ iterate (map (+ by)) (xs) > multRoll r@(Roll (x:_) by) p > = Roll (takeWhile (< (x+p*by)) $ rollFrom r) (by*p) > > primes = euler $ Roll [2] 1 > euler r@(Roll xs _) > = x:euler (Roll (mxs `minus` map (x*) xs) mby) > where > (x,r') = rollOnce r > (Roll mxs mby) = multRoll r' x > There's much extra primes pre-calculated inside the Roll, of course. For any (Roll xs@(x:_) _), (takeWhile (< x*x) xs) are all primes too. When these are used, the code's complexity is around O(n^1.5), and it runs about 1.8x slower than Postponed Filters. The "faithful sieve"'s empirical complexity is above 2.10..2.25 and rising. So it might not be exponential, bbut is worse than power it seems anyway. From miguelimo38 at yandex.ru Wed Jan 6 09:39:24 2010 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Wed Jan 6 09:15:10 2010 Subject: [Haskell-cafe] Explicit garbage collection In-Reply-To: <201001060906.51127.dan.doel@gmail.com> References: <4B44958A.2080809@yandex.ru> <201001060906.51127.dan.doel@gmail.com> Message-ID: <4B44A09C.8040103@yandex.ru> I'll take a look at them. I want something like this: refMaybe b dflt ref = if b then readRef ref else return dflt refIgnore ref = return "blablabla" refFst ref = do (v, w) <- readRef ref return v test = do a <- newRef "x" b <- newRef 1 c <- newRef ('z', Just 0) performLocalGC -- if necessary x <- isStillNeeded a y <- isStillNeeded b z <- isStillNeeded c u <- refMaybe y "t" a -- note that it wouldn't actually read "a", -- but it won't be known until runtime. w <- refIgnore b v <- refFst c return (x, y, z) so that "run test" returns (True, False, True). Dan Doel wrote: > On Wednesday 06 January 2010 8:52:10 am Miguel Mitrofanov wrote: >> Is there any kind of "ST" monad that allows to know if some STRef is no >> longer needed? >> >> The problem is, I want to send some data to an external storage over a >> network and get it back later, but I don't want to send unnecessary data. >> >> I've managed to do something like that with weak pointers, >> System.Mem.performGC and unsafePerformIO, but it seems to me that invoking >> GC every time is an overkill. >> >> Oh, and I'm ready to trade the purity of runST for that, if necessary. > > You may be able to use something like Oleg's Lightweight Monadic Regions to > get this effect. I suppose it depends somewhat on what qualifies a reference > as "no longer needed". > > http://www.cs.rutgers.edu/~ccshan/capability/region-io.pdf > > I'm not aware of anything out-of-the-box that does what you want, though. > > -- Dan > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From ganesh.sittampalam at credit-suisse.com Wed Jan 6 10:28:30 2010 From: ganesh.sittampalam at credit-suisse.com (Sittampalam, Ganesh) Date: Wed Jan 6 10:01:54 2010 Subject: [Haskell-cafe] darcs 2.4 beta 1 release In-Reply-To: <87fx6j8hpt.fsf@gmail.com> References: <201001051918.38069.tux_rocker@reinier.de> <87fx6j8hpt.fsf@gmail.com> Message-ID: <16442B752A06A74AB4D9F9A5FF076E4B03B9FE4D@ELON17P32001A.csfb.cs-group.com> Obviously source code documentation would be nice, but why is it "show-stopping"? Ivan Lazar Miljenovic wrote: > I really feel that bug 1720 [1] is a show-stopping bug for darcs, > especially since it means that building Haddock for darcs with > GHC-6.12.* isn't possible. > > [1] http://bugs.darcs.net/issue1720 > > I tried to make a fix, but didn't know enough of how darcs is > documented to be able to do anything. > > > Reinier Lamers writes: > >> Hi all, >> >> The darcs team would like to announce the immediate availability of >> darcs 2.4 beta 1. darcs 2.4 will contain many improvements and >> bugfixes compared to darcs 2.3.1. Highlights are the fast index-based >> diffing which is now used by all darcs commands, and the interactive >> hunk-splitting in darcs record. This beta is your chance to >> test-drive >> these improvements and make darcs even better. >> >> If you have installed the Haskell Platform or cabal-install, you can >> install this beta release by doing: >> >> $ cabal update >> $ cabal install --reinstall darcs-beta >> >> Alternatively, you can download the tarball from >> http://darcs.net/releases/darcs-2.3.98.1.tar.gz , and build it by >> hand >> as explained in the README file. >> >> A list of important changes since 2.3.1 is as follows (please let me >> know if there's something you miss!): >> >> * Use fast index-based diffing everywhere (Petr) >> * Interactive patch splitting (Ganesh) >> * An 'optimize --upgrade' option to convert to hashed format >> in-place (Eric) >> * Hunk matching (Kamil Dworakowski, tat.wright) >> * Progress reporting is no longer deceptive (Roman Pl??il) >> * A 'remove --recursive' option to remove a directory tree from >> revision control (Roman Pl??il) >> * A '--remote-darcs' flag for pushing to a host where darcs isn't >> called darcs >> * Many miscellaneous Windows improvements (Salvatore, Petr and >> others) >> * 'darcs send' now mentions the repository name in the email body >> (Joachim) >> * Handle files with boring names in the repository correctly >> (Petr) >> * Fix parsing of .authorspellings file (Tom?? Caitt) >> * Various sane new command-line option names (Florent) >> * Remove the '--checkpoint' option (Petr) >> * Use external libraries for all UTF-8 handling (Eric, Reinier) >> * Use the Haskell zlib package exclusively for compression (Petr) >> >> Kind Regards, >> the darcs release manager, >> Reinier Lamers >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe =============================================================================== Please access the attached hyperlink for an important electronic communications disclaimer: http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html =============================================================================== From will_n48 at yahoo.com Wed Jan 6 13:13:01 2010 From: will_n48 at yahoo.com (Will Ness) Date: Wed Jan 6 12:46:23 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001050243.43208.daniel.is.fischer@web.de> <201001060323.52877.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > > Am Mittwoch 06 Januar 2010 00:09:07 schrieb Will Ness: > > Daniel Fischer web.de> writes: > > > Am Montag 04 Januar 2010 22:25:28 schrieb Daniel Fischer: > > > Fix rfold: > > > > > > rfold f [x] = x > > > rfold f xs = rfold f (pairwise f xs) > > > > > > and it's faster also for those. > > > > The memory is almost completely due to the tree-merging of the multiples for > the fastest runner. While it produces faster than flat merging, the > exponential growth of the trees makes a bad memory citizen. Isn't the number of nodes the same in any two trees with the same number of leafs? BTW using compos ps = fst $ tfold mergeSP $ nwise 1 mergeSP $ map pmults ps instead of compos ps = fst $ tfold mergeSP $ nwise 1 mergeSP $ pairwise mergeSP $ map pmults ps brings down memory consumption further by 25%..45% on 1..8 mln primes produced, while slowing it down by about 0%..2% (that's after eliminating the lazy pattern in tfold as per your advice). > > 'pairwise' puts odd leafs higher on the right. It might be better if it was > > so on the left, for the frequency of production is higher. > > Maybe. But how would you do it? I tried passing the length to rfold, so when > there was an odd numberof trees in the list, it would move the first out of > the recursion. Any possible gains in production have been more than eaten up > by the control code (not a big difference, but it was there). yes I've seen this too now. BTW, at a price of further slowing down, memory can be lowered yet more with compos ps = fst $ tfold mergeSP $ nwise 1 0.4 mergeSP $ map pmults ps nwise k d f xs = let (ys,zs) = splitAt (round k) xs in rfold f ys : nwise (k+d) d f zs It really looks like the nearer the structure is to linear list, the lower the memory consumption becomes. Of course using 0.0 in place of 0.4 would make it into a plain list. From ndmitchell at gmail.com Wed Jan 6 13:19:08 2010 From: ndmitchell at gmail.com (Neil Mitchell) Date: Wed Jan 6 12:52:04 2010 Subject: [Haskell-cafe] Significant slow-down in parallel code? In-Reply-To: References: <404396ef1001041214t1ef9b497qdf598f6cb8686fd2@mail.gmail.com> Message-ID: <404396ef1001061019q36e5bc63xefbc1cee3267affb@mail.gmail.com> There was a paper at the Haskell Symposium 2009, and the video is online: http://www.vimeo.com/6680185 Thanks, Neil On Tue, Jan 5, 2010 at 2:23 AM, Jamie Morgenstern wrote: > I am using 6.12... are there any good pointers as to how one uses > threadscope? > > On Mon, Jan 4, 2010 at 3:14 PM, Neil Mitchell wrote: >> >> Hi Jamie, >> >> First question, what version of GHC are you using? There are >> significant performance improvements to parallel code in GHC 6.12, so >> it's worth an upgrade. Once you've upgraded you might want to try out >> threadscope which is designed to help track down these sorts of >> problems. >> >> If you are using 6.10, I recommend turning off parallel garbage >> collection with the RTS flags (see the manual) as that can cause >> slowdowns. >> >> Thanks, Neil >> >> 2010/1/4 Jamie Morgenstern : >> > Hello; >> > >> > ?I have a piece of code in which I employ the `par` construct to add >> > some implicit parallelism >> > to a theorem prover. However, when running the *same* code with >> > >> > +RTS -N1 >> > +RTS -N5 >> > +RTS -N10 >> > >> > I see a huge slowdown (a factor of 50 with 5 processes and a factor of >> > 100 for 10 on an 8-core machine). >> > >> > Very little time is being spent using the garbage collector. Any >> > suggestions? >> > >> > Thanks, >> > -Jamie >> > >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > Haskell-Cafe@haskell.org >> > http://www.haskell.org/mailman/listinfo/haskell-cafe >> > >> > > > From ekmett at gmail.com Wed Jan 6 15:21:05 2010 From: ekmett at gmail.com (Edward Kmett) Date: Wed Jan 6 14:54:04 2010 Subject: [Haskell-cafe] Explicit garbage collection In-Reply-To: <4B44A09C.8040103@yandex.ru> References: <4B44958A.2080809@yandex.ru> <201001060906.51127.dan.doel@gmail.com> <4B44A09C.8040103@yandex.ru> Message-ID: <7fb8f82f1001061221v40ffe0cby8c0e4b453e72d65d@mail.gmail.com> You probably just want to hold onto weak references for your 'isStillNeeded' checks. Otherwise the isStillNeeded check itself will keep you from garbage collecting! http://cvs.haskell.org/Hugs/pages/libraries/base/System-Mem-Weak.html -Edward Kmett On Wed, Jan 6, 2010 at 9:39 AM, Miguel Mitrofanov wrote: > I'll take a look at them. > > I want something like this: > > refMaybe b dflt ref = if b then readRef ref else return dflt > refIgnore ref = return "blablabla" > refFst ref = > do > (v, w) <- readRef ref > return v > test = > do > a <- newRef "x" > b <- newRef 1 > c <- newRef ('z', Just 0) > performLocalGC -- if necessary > x <- isStillNeeded a > y <- isStillNeeded b > z <- isStillNeeded c > u <- refMaybe y "t" a -- note that it wouldn't actually read "a", > -- but it won't be known until runtime. > w <- refIgnore b > v <- refFst c > return (x, y, z) > > so that "run test" returns (True, False, True). > > > Dan Doel wrote: > >> On Wednesday 06 January 2010 8:52:10 am Miguel Mitrofanov wrote: >> >>> Is there any kind of "ST" monad that allows to know if some STRef is no >>> longer needed? >>> >>> The problem is, I want to send some data to an external storage over a >>> network and get it back later, but I don't want to send unnecessary >>> data. >>> >>> I've managed to do something like that with weak pointers, >>> System.Mem.performGC and unsafePerformIO, but it seems to me that >>> invoking >>> GC every time is an overkill. >>> >>> Oh, and I'm ready to trade the purity of runST for that, if necessary. >>> >> >> You may be able to use something like Oleg's Lightweight Monadic Regions >> to get this effect. I suppose it depends somewhat on what qualifies a >> reference as "no longer needed". >> >> http://www.cs.rutgers.edu/~ccshan/capability/region-io.pdf >> >> I'm not aware of anything out-of-the-box that does what you want, though. >> >> -- Dan >> _______________________________________________ >> 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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100106/8764dd1f/attachment.html From miguelimo38 at yandex.ru Wed Jan 6 16:05:42 2010 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Wed Jan 6 15:38:38 2010 Subject: [Haskell-cafe] Explicit garbage collection In-Reply-To: <7fb8f82f1001061221v40ffe0cby8c0e4b453e72d65d@mail.gmail.com> References: <4B44958A.2080809@yandex.ru> <201001060906.51127.dan.doel@gmail.com> <4B44A09C.8040103@yandex.ru> <7fb8f82f1001061221v40ffe0cby8c0e4b453e72d65d@mail.gmail.com> Message-ID: On 6 Jan 2010, at 23:21, Edward Kmett wrote: > You probably just want to hold onto weak references for your > 'isStillNeeded' checks. That's what I do now. But I want to minimize the network traffic, so I want referenced values to be garbage collected as soon as possible - and I couldn't find anything except System.Mem.performIO to do the job - which is a bit too global for me. > Otherwise the isStillNeeded check itself will keep you from garbage > collecting! Not necessary. What I'm imagining is that there is essentially only one way to access the value stored in the reference - with readRef. So, if there isn't any chance that readRef would be called, the value can be garbage collected; "isStillNeeded" function only needs the reference, not the value. Well, yeah, that's kinda like weak references. > > http://cvs.haskell.org/Hugs/pages/libraries/base/System-Mem-Weak.html > > -Edward Kmett > > On Wed, Jan 6, 2010 at 9:39 AM, Miguel Mitrofanov > wrote: > I'll take a look at them. > > I want something like this: > > refMaybe b dflt ref = if b then readRef ref else return dflt > refIgnore ref = return "blablabla" > refFst ref = > do > (v, w) <- readRef ref > return v > test = > do > a <- newRef "x" > b <- newRef 1 > c <- newRef ('z', Just 0) > performLocalGC -- if necessary > x <- isStillNeeded a > y <- isStillNeeded b > z <- isStillNeeded c > u <- refMaybe y "t" a -- note that it wouldn't actually read "a", > -- but it won't be known until runtime. > w <- refIgnore b > v <- refFst c > return (x, y, z) > > so that "run test" returns (True, False, True). > > > Dan Doel wrote: > On Wednesday 06 January 2010 8:52:10 am Miguel Mitrofanov wrote: > Is there any kind of "ST" monad that allows to know if some STRef is > no > longer needed? > > The problem is, I want to send some data to an external storage over a > network and get it back later, but I don't want to send unnecessary > data. > > I've managed to do something like that with weak pointers, > System.Mem.performGC and unsafePerformIO, but it seems to me that > invoking > GC every time is an overkill. > > Oh, and I'm ready to trade the purity of runST for that, if necessary. > > You may be able to use something like Oleg's Lightweight Monadic > Regions to get this effect. I suppose it depends somewhat on what > qualifies a reference as "no longer needed". > > http://www.cs.rutgers.edu/~ccshan/capability/region-io.pdf > > I'm not aware of anything out-of-the-box that does what you want, > though. > > -- Dan > _______________________________________________ > 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 mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From ozgurakgun at gmail.com Wed Jan 6 17:38:19 2010 From: ozgurakgun at gmail.com (Ozgur Akgun) Date: Wed Jan 6 17:11:15 2010 Subject: [Haskell-cafe] Problem with cabal install zlib In-Reply-To: <1261520904.9220.77808.camel@localhost> References: <7be1feae0912181501t212357ecge4d486b2798a23f0@mail.gmail.com> <1261212888.9220.56169.camel@localhost> <7be1feae0912190139w5724b1eatf80635445064840b@mail.gmail.com> <1261269079.9220.59827.camel@localhost> <7be1feae0912211508k4476d0cdq1473e1211a8870fd@mail.gmail.com> <1261514309.9220.77361.camel@localhost> <7be1feae0912221348j4609e771p81f4eefd2406ebb3@mail.gmail.com> <1261520904.9220.77808.camel@localhost> Message-ID: <7be1feae1001061438v7d3ace75n56291e91d28d686e@mail.gmail.com> Just to check, anyone running Snow Leopard and *CAN* install "zlib-0.5.2.0" using "cabal install zlib"? I'm trying to make sure whether I am the only one having this problem or I have some companion. Best, 2009/12/22 Duncan Coutts > On Tue, 2009-12-22 at 21:48 +0000, Ozgur Akgun wrote: > > What about this part: > > > > -o dist/build/Codec/Compression/ > > Zlib/Stream.hs Codec/Compression/Zlib/Stream.hsc > > > > Isn't it passing multiple (two in this case) output parameters? Or am > > I missing sth? > > No, that's one -o flag and a single additional non-flag argument which > is the input file. It's like: > > $ command input -o output > > but with the order reversed as: > > $ command -o output input > > > Duncan > > -- Ozgur Akgun -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100106/05133f6f/attachment.html From greg at gregorycollins.net Wed Jan 6 18:58:38 2010 From: greg at gregorycollins.net (Gregory Collins) Date: Wed Jan 6 18:31:31 2010 Subject: [Haskell-cafe] Problem with cabal install zlib In-Reply-To: <7be1feae1001061438v7d3ace75n56291e91d28d686e@mail.gmail.com> (Ozgur Akgun's message of "Wed, 6 Jan 2010 22:38:19 +0000") References: <7be1feae0912181501t212357ecge4d486b2798a23f0@mail.gmail.com> <1261212888.9220.56169.camel@localhost> <7be1feae0912190139w5724b1eatf80635445064840b@mail.gmail.com> <1261269079.9220.59827.camel@localhost> <7be1feae0912211508k4476d0cdq1473e1211a8870fd@mail.gmail.com> <1261514309.9220.77361.camel@localhost> <7be1feae0912221348j4609e771p81f4eefd2406ebb3@mail.gmail.com> <1261520904.9220.77808.camel@localhost> <7be1feae1001061438v7d3ace75n56291e91d28d686e@mail.gmail.com> Message-ID: <87zl4qlr9t.fsf@gregorycollins.net> Ozgur Akgun writes: > Just to check, anyone running Snow Leopard and *CAN* install > "zlib-0.5.2.0" using "cabal install zlib"? > > I'm trying to make sure whether I am the only one having this problem > or I have some companion. $ cabal install --reinstall zlib Resolving dependencies... Configuring zlib-0.5.2.0... Preprocessing library zlib-0.5.2.0... Building zlib-0.5.2.0... [1 of 5] Compiling Codec.Compression.Zlib.Stream ( dist/build/Codec/Compression/Zlib/Stream.hs, dist/build/Codec/Compression/Zlib/Stream.o ) [2 of 5] Compiling Codec.Compression.Zlib.Internal ( Codec/Compression/Zlib/Internal.hs, dist/build/Codec/Compression/Zlib/Internal.o ) [3 of 5] Compiling Codec.Compression.Zlib.Raw ( Codec/Compression/Zlib/Raw.hs, dist/build/Codec/Compression/Zlib/Raw.o ) [4 of 5] Compiling Codec.Compression.Zlib ( Codec/Compression/Zlib.hs, dist/build/Codec/Compression/Zlib.o ) [5 of 5] Compiling Codec.Compression.GZip ( Codec/Compression/GZip.hs, dist/build/Codec/Compression/GZip.o ) ar: creating archive dist/build/libHSzlib-0.5.2.0.a Installing library in /Users/greg/.cabal/lib/zlib-0.5.2.0/ghc-6.10.4 Registering zlib-0.5.2.0... Reading package info from "dist/installed-pkg-config" ... done. Writing new package config file... done. No problem here. Please ensure you've patched /usr/bin/ghc, /usr/bin/ghci, /usr/bin/runhaskell, /usr/bin/runghc, and /usr/bin/hsc2hs according to the instructions on http://haskell.org/haskellwiki/OSX . The next release of the Haskell Platform installer should fix this issue. G -- Gregory Collins From tonymorris at gmail.com Wed Jan 6 19:23:35 2010 From: tonymorris at gmail.com (Tony Morris) Date: Wed Jan 6 18:56:17 2010 Subject: [Haskell-cafe] ghc -e Message-ID: <4B452987.2030305@gmail.com> Can I import a module when using ghc -e? e.g. ghc -e "import Control.Monad; forM [[1,2,3]] reverse" -- Tony Morris http://tmorris.net/ From gwern0 at gmail.com Wed Jan 6 19:27:18 2010 From: gwern0 at gmail.com (Gwern Branwen) Date: Wed Jan 6 19:00:12 2010 Subject: [Haskell-cafe] ghc -e In-Reply-To: <4B452987.2030305@gmail.com> References: <4B452987.2030305@gmail.com> Message-ID: On Wed, Jan 6, 2010 at 7:23 PM, Tony Morris wrote: > ghc -e "import Control.Monad; forM [[1,2,3]] reverse" As of 6.10.2, the bug whereby the GHC API lets you use functions from anywhere just by naming them (Java-style) has not been fixed: $ ghc -e "Control.Monad.forM [[1,2,3]] reverse" package flags have changed, resetting and loading new packages... :1:25: Warning: Defaulting the following constraint(s) to type `Integer' `Num t' arising from the literal `3' at :1:25 In the expression: 3 In the expression: [1, 2, 3] In the first argument of `forM', namely `[[1, 2, 3]]' :1:25: Warning: Defaulting the following constraint(s) to type `Integer' `Num t' arising from the literal `3' at :1:25 In the expression: 3 In the expression: [1, 2, 3] In the first argument of `forM', namely `[[1, 2, 3]]' [[3],[2],[1]] it :: [[Integer]] (0.01 secs, 1710984 bytes) -- gwern From tonymorris at gmail.com Wed Jan 6 19:35:16 2010 From: tonymorris at gmail.com (Tony Morris) Date: Wed Jan 6 19:07:58 2010 Subject: [Haskell-cafe] ghc -e In-Reply-To: References: <4B452987.2030305@gmail.com> Message-ID: <4B452C44.4070406@gmail.com> Gwern Branwen wrote: > On Wed, Jan 6, 2010 at 7:23 PM, Tony Morris wrote: > >> ghc -e "import Control.Monad; forM [[1,2,3]] reverse" >> > > As of 6.10.2, the bug whereby the GHC API lets you use functions from > anywhere just by naming them (Java-style) has not been fixed: > > $ ghc -e "Control.Monad.forM [[1,2,3]] reverse" > package flags have changed, resetting and loading new packages... > > :1:25: > Warning: Defaulting the following constraint(s) to type `Integer' > `Num t' arising from the literal `3' at :1:25 > In the expression: 3 > In the expression: [1, 2, 3] > In the first argument of `forM', namely `[[1, 2, 3]]' > > :1:25: > Warning: Defaulting the following constraint(s) to type `Integer' > `Num t' arising from the literal `3' at :1:25 > In the expression: 3 > In the expression: [1, 2, 3] > In the first argument of `forM', namely `[[1, 2, 3]]' > [[3],[2],[1]] > it :: [[Integer]] > (0.01 secs, 1710984 bytes) > > I see the same on GHC 6.10.4. $ ghc -e "Control.Monad.forM [[1,2,3]] reverse" [[3],[2],[1]] What would it be fixed to? What is wrong with how it is? -- Tony Morris http://tmorris.net/ From schlepptop at henning-thielemann.de Wed Jan 6 19:43:22 2010 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Wed Jan 6 19:16:24 2010 Subject: [Haskell-cafe] Value classes In-Reply-To: <1262203975.6283.4.camel@supermule.opasia.dk> References: <1262203975.6283.4.camel@supermule.opasia.dk> Message-ID: <4B452E2A.1030408@henning-thielemann.de> Mads Lindstr?m schrieb: > Hi > > A function inc5 > > inc5 :: Float -> Float > inc5 x = x + 5 > > can only be a member of a type class A, if we make all functions from > Float -> Float members of type class A. Thus, I assume, that _type_ > class is named type class, as membership is decided by types. > > However, it makes no sense to say that all functions from Float -> Float > are invertible or continuous. We would want to specifically say that > inc5 is continuous, not all Float -> Float functions. Thus, we could > have another abstraction, lets call it _value_ class, where we could say > that an individual value (function) could be member. We could say > something like: > > class Invertible (f :: a -> a) where > invert :: f -> (a -> a) > > instance Invertible inc5 where > invert _ = \x -> x - 5 > > In many cases this would be too specific. We would like to say, that > applying the first argument to `+` returns an invertible function. > Something like: > > instance Invertible (`+` x) where > invert (x +) = \y -> y - x > > We would properly also like to say, that composing two invertible > functions results in another invertible function. I guess there are many > more examples. > Maybe you could define types like newtype InvertibleFunction a b = InvertibleFunction (a -> b) newtype ContinuousFunction a b = ContinuousFunction (a -> b) or newtype AttributedFunction attr a b = AttributedFunction a b where attr can be Invertible, Continuous, or (Invertible, Continuous). Then you may define a type class that provides a functional inverse, if attr shows invertibility. From daniel.is.fischer at web.de Wed Jan 6 19:59:09 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Jan 6 19:33:40 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001060323.52877.daniel.is.fischer@web.de> Message-ID: <201001070159.10175.daniel.is.fischer@web.de> Am Mittwoch 06 Januar 2010 19:13:01 schrieb Will Ness: > Daniel Fischer web.de> writes: > > Am Mittwoch 06 Januar 2010 00:09:07 schrieb Will Ness: > > > Daniel Fischer web.de> writes: > > > > Am Montag 04 Januar 2010 22:25:28 schrieb Daniel Fischer: > > > > Fix rfold: > > > > > > > > rfold f [x] = x > > > > rfold f xs = rfold f (pairwise f xs) > > > > > > > > and it's faster also for those. > > > > The memory is almost completely due to the tree-merging of the multiples > > for the fastest runner. While it produces faster than flat merging, the > > exponential growth of the trees makes a bad memory citizen. > > Isn't the number of nodes the same in any two trees with the same number of > leafs? Sure. And I don't know why it takes *that much* memory, but since a flat merge doesn't consume much memory, it must be the trees. > > BTW using > > compos ps = fst $ tfold mergeSP $ nwise 1 mergeSP $ map pmults ps > > instead of > > compos ps = fst $ tfold mergeSP $ nwise 1 mergeSP > $ pairwise mergeSP $ map pmults ps > > brings down memory consumption further by 25%..45% on 1..8 mln primes > produced, while slowing it down by about 0%..2% (that's after eliminating > the lazy pattern in tfold as per your advice). > So much? Wow. I forgot the numbers, but I had tried that too, I thought the memory gain wasn't worth the speed loss. Another thing that reduces memory usage is compos :: [a] -> [a] compos ps = case pairwise mergeSP (multip ps) of ((a,b):cs) -> a ++ funMerge b (nwise 1 mergeSP $ pairwise mergeSP cs) funMerge b (x:y:zs) = let (c,d) = mergeSP x y in mfun b c d zs mfun u@(x:xs) w@(y:ys) d l = case compare x y of LT -> x:mfun xs w d l EQ -> x:mfun xs ys d l GT -> y:mfun u ys d l mfun u [] d l = funMerge (merge u d) l That's about the same speed as the latter of the above here and uses about 25% less memory. Removing one or two 'pairwise's brings memory down further, but makes it slower. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100106/d93c6608/attachment.html From rwbarton at math.harvard.edu Wed Jan 6 21:15:11 2010 From: rwbarton at math.harvard.edu (Reid Barton) Date: Wed Jan 6 20:48:01 2010 Subject: [Haskell-cafe] ghc -e In-Reply-To: <4B452987.2030305@gmail.com> References: <4B452987.2030305@gmail.com> Message-ID: <20100107021511.GG12245@rwbarton.mit.edu> On Thu, Jan 07, 2010 at 10:23:35AM +1000, Tony Morris wrote: > Can I import a module when using ghc -e? > > e.g. ghc -e "import Control.Monad; forM [[1,2,3]] reverse" One option is to create a file "imports.hs" which contains the text "import Control.Monad", and then run ghc -e "forM [[1,2,3]] reverse" imports.hs I use this method in a short shell script "interact" so that I can apply Haskell functions to files from the command line and don't have to type the full qualified names of things in modules I use frequently. Regards, Reid Barton From gwern0 at gmail.com Wed Jan 6 21:22:04 2010 From: gwern0 at gmail.com (Gwern Branwen) Date: Wed Jan 6 20:55:00 2010 Subject: [Haskell-cafe] ghc -e In-Reply-To: <4B452C44.4070406@gmail.com> References: <4B452987.2030305@gmail.com> <4B452C44.4070406@gmail.com> Message-ID: On Wed, Jan 6, 2010 at 7:35 PM, Tony Morris wrote: > Gwern Branwen wrote: >> On Wed, Jan 6, 2010 at 7:23 PM, Tony Morris wrote: >> >>> ghc -e "import Control.Monad; forM [[1,2,3]] reverse" >>> >> >> As of 6.10.2, the bug whereby the GHC API lets you use functions from >> anywhere just by naming them (Java-style) has not been fixed: >> >> $ ghc -e "Control.Monad.forM [[1,2,3]] reverse" >> package flags have changed, resetting and loading new packages... >> >> :1:25: >> ? ? Warning: Defaulting the following constraint(s) to type `Integer' >> ? ? ? ? ? ? ?`Num t' arising from the literal `3' at :1:25 >> ? ? In the expression: 3 >> ? ? In the expression: [1, 2, 3] >> ? ? In the first argument of `forM', namely `[[1, 2, 3]]' >> >> :1:25: >> ? ? Warning: Defaulting the following constraint(s) to type `Integer' >> ? ? ? ? ? ? ?`Num t' arising from the literal `3' at :1:25 >> ? ? In the expression: 3 >> ? ? In the expression: [1, 2, 3] >> ? ? In the first argument of `forM', namely `[[1, 2, 3]]' >> [[3],[2],[1]] >> it :: [[Integer]] >> (0.01 secs, 1710984 bytes) >> >> > I see the same on GHC 6.10.4. > $ ghc -e "Control.Monad.forM [[1,2,3]] reverse" > [[3],[2],[1]] > > > What would it be fixed to? What is wrong with how it is? Presumably one then have to use some sort of flag to ask for Control.Monad specifically to be visible. What's wrong with it is that this is not merely GHCi behavior, this is universal GHC API behavior and wildly insecure: http://hackage.haskell.org/trac/ghc/ticket/2452 -- gwern From dagit at codersbase.com Wed Jan 6 21:53:49 2010 From: dagit at codersbase.com (Jason Dagit) Date: Wed Jan 6 21:26:43 2010 Subject: [Haskell-cafe] ghc -e In-Reply-To: <20100107021511.GG12245@rwbarton.mit.edu> References: <4B452987.2030305@gmail.com> <20100107021511.GG12245@rwbarton.mit.edu> Message-ID: On Wed, Jan 6, 2010 at 6:15 PM, Reid Barton wrote: > On Thu, Jan 07, 2010 at 10:23:35AM +1000, Tony Morris wrote: > > Can I import a module when using ghc -e? > > > > e.g. ghc -e "import Control.Monad; forM [[1,2,3]] reverse" > > One option is to create a file "imports.hs" which contains the text > "import Control.Monad", and then run > > ghc -e "forM [[1,2,3]] reverse" imports.hs > > I use this method in a short shell script "interact" so that I can > apply Haskell functions to files from the command line and don't have > to type the full qualified names of things in modules I use frequently. > Did you know you can put commands in $HOME/.ghci that will be loaded every time you run ghci? So, if you have modules that you commonly use put something like: :m + Control.Monad In your $HOME/.ghci file and then you can use ghci instead of this ghc -e trick. HTH, Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100106/fbe7ad82/attachment.html From ekmett at gmail.com Wed Jan 6 22:28:34 2010 From: ekmett at gmail.com (Edward Kmett) Date: Wed Jan 6 22:01:28 2010 Subject: [Haskell-cafe] Explicit garbage collection In-Reply-To: References: <4B44958A.2080809@yandex.ru> <201001060906.51127.dan.doel@gmail.com> <4B44A09C.8040103@yandex.ru> <7fb8f82f1001061221v40ffe0cby8c0e4b453e72d65d@mail.gmail.com> Message-ID: <7fb8f82f1001061928o4a58ac46qbaaf00691f26e304@mail.gmail.com> I don't believe you can get quite the semantics you want. However, you can get reasonably close, by building a manual store and backtracking. {-# LANGUAGE Rank2Types #-} -- lets define an Oracle that tracks whether or not you might need the reference, by backtracking. module Oracle ( Oracle, Ref , newRef, readRef, writeRef, modifyRef, needRef ) where import Control.Applicative import Control.Arrow (first) import Control.Monad import Data.IntMap (IntMap) import qualified Data.IntMap as M import Unsafe.Coerce (unsafeCoerce) import GHC.Prim (Any) -- we need to track our own worlds, otherwise we'd have to build over ST, change optimistically, and track how to backtrack the state of the Store. Much uglier. -- values are stored as 'Any's for safety, see GHC.Prim for a discussion on the hazards of risking the storage of function types using unsafeCoerce as anything else. data World s = World { store :: !(IntMap Any), hwm :: !Int } -- references into our store newtype Ref s a = Ref Int deriving (Eq) -- our monad that can 'see the future' ~ StateT (World s) [] newtype Oracle s a = Oracle { unOracle :: World s -> [(a, World s)] } -- we rely on the fact that the list is always non-empty for any oracle you can run. we are only allowed to backtrack if we thought we wouldn't need the reference, and wound up needing it, so head will always succeed. runOracle :: (forall s. Oracle s a) -> a runOracle f = fst $ head $ unOracle f $ World M.empty 1 instance Monad (Oracle s) where return a = Oracle $ \w -> [(a,w)] Oracle m >>= k = Oracle $ \s -> do (a,s') <- m s unOracle (k a) s' -- note: you cannot safely define fail here without risking a crash in runOracle -- Similarly, we're not a MonadPlus instance because we always want to succeed eventually. instance Functor (Oracle s) where fmap f (Oracle g) = Oracle $ \w -> first f <$> g w instance Applicative (Oracle s) where pure = return (<*>) = ap -- new ref allocates a fresh slot and inserts the value into the store. the type level brand 's' keeps us safe, and we don't export the Ref constructor. newRef :: a -> Oracle s (Ref s a) newRef a = Oracle $ \(World w t) -> [(Ref t, World (M.insert t (unsafeCoerce a) w) (t + 1))] -- readRef is the only thing that ever backtracks, if we try to read a reference we claimed we wouldn't need, then we backtrack to when we decided we didn't need the reference, and continue with its value. readRef :: Ref s a -> Oracle s a readRef (Ref slot) = Oracle $ \world -> maybe [] (\a -> [(unsafeCoerce a, world)]) $ M.lookup slot (store world) -- note, writeRef dfoesn't 'need' the ref's current value, so needRef will report False if you writeRef before you read it after this. writeRef :: a -> Ref s a -> Oracle s a writeRef a (Ref slot) = Oracle $ \world -> [(a, world { store = M.insert slot (unsafeCoerce a) $ store world })] {- -- alternate writeRef where writing 'needs' the ref. writeRef :: a -> Ref s a -> Oracle s a writeRef a (Ref slot) = Oracle $ \World store v -> do (Just _, store') <- return $ updateLookupWithKey replace slot store [(a, World store' v)] where replace _ _ = Just (unsafeCoerce a) -} -- modifying a reference of course needs its current value. modifyRef :: (a -> a) -> Ref s a -> Oracle s a modifyRef f r = do a <- readRef r writeRef (f a) r -- needRef tries to continue executing the world without the element in the store in question. if that fails, then we'll backtrack to here, and try again with the original world, and report that the element was in fact needed. needRef :: Ref s a -> Oracle s Bool needRef (Ref slot) = Oracle $ \world -> [ (False, world { store = M.delete slot $ store world }) , (True, world) ] -- test case: refMaybe b dflt ref = if b then readRef ref else return dflt refIgnore ref = return "blablabla" refFst ref = fst <$> readRef ref test = do a <- newRef "x" b <- newRef 1 c <- newRef ('z', Just 0) -- no performLocalGC required x <- needRef a y <- needRef b z <- needRef c u <- refMaybe y "t" a -- note that it wouldn't actually read "a", -- but it won't be known until runtime. w <- refIgnore b v <- refFst c return (x, y, z) -- This will disagree with your desired answer, returning: *Oracle> runOracle test Loading package syb ... linking ... done. Loading package array-0.2.0.0 ... linking ... done. Loading package containers-0.2.0.1 ... linking ... done. (False,False,True) rather than (True, False, True), because the oracle is able to see into the future (via backtracking) to see that refMaybe doesn't use the reference after all. This probably won't suit your needs, but it was a fun little exercise. -Edward Kmett On Wed, Jan 6, 2010 at 4:05 PM, Miguel Mitrofanov wrote: > > On 6 Jan 2010, at 23:21, Edward Kmett wrote: > > You probably just want to hold onto weak references for your >> 'isStillNeeded' checks. >> > > That's what I do now. But I want to minimize the network traffic, so I want > referenced values to be garbage collected as soon as possible - and I > couldn't find anything except System.Mem.performIO to do the job - which is > a bit too global for me. > > Otherwise the isStillNeeded check itself will keep you from garbage >> collecting! >> > > Not necessary. What I'm imagining is that there is essentially only one way > to access the value stored in the reference - with readRef. So, if there > isn't any chance that readRef would be called, the value can be garbage > collected; "isStillNeeded" function only needs the reference, not the value. > > Well, yeah, that's kinda like weak references. > > > http://cvs.haskell.org/Hugs/pages/libraries/base/System-Mem-Weak.html >> >> -Edward Kmett >> >> On Wed, Jan 6, 2010 at 9:39 AM, Miguel Mitrofanov >> wrote: >> I'll take a look at them. >> >> I want something like this: >> >> refMaybe b dflt ref = if b then readRef ref else return dflt >> refIgnore ref = return "blablabla" >> refFst ref = >> do >> (v, w) <- readRef ref >> return v >> test = >> do >> a <- newRef "x" >> b <- newRef 1 >> c <- newRef ('z', Just 0) >> performLocalGC -- if necessary >> x <- isStillNeeded a >> y <- isStillNeeded b >> z <- isStillNeeded c >> u <- refMaybe y "t" a -- note that it wouldn't actually read "a", >> -- but it won't be known until runtime. >> w <- refIgnore b >> v <- refFst c >> return (x, y, z) >> >> so that "run test" returns (True, False, True). >> >> >> Dan Doel wrote: >> On Wednesday 06 January 2010 8:52:10 am Miguel Mitrofanov wrote: >> Is there any kind of "ST" monad that allows to know if some STRef is no >> longer needed? >> >> The problem is, I want to send some data to an external storage over a >> network and get it back later, but I don't want to send unnecessary data. >> >> I've managed to do something like that with weak pointers, >> System.Mem.performGC and unsafePerformIO, but it seems to me that >> invoking >> GC every time is an overkill. >> >> Oh, and I'm ready to trade the purity of runST for that, if necessary. >> >> You may be able to use something like Oleg's Lightweight Monadic Regions >> to get this effect. I suppose it depends somewhat on what qualifies a >> reference as "no longer needed". >> >> http://www.cs.rutgers.edu/~ccshan/capability/region-io.pdf >> >> I'm not aware of anything out-of-the-box that does what you want, though. >> >> -- Dan >> _______________________________________________ >> 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 mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100106/25b00e46/attachment-0001.html From vanenkj at gmail.com Wed Jan 6 23:49:03 2010 From: vanenkj at gmail.com (John Van Enk) Date: Wed Jan 6 23:21:58 2010 Subject: [Haskell-cafe] ANNOUNCE: tuntap-0.0.1 Message-ID: Hi All, As some of you have requested, I've extracted the code from my (under work) VPN which talks to the TUN/TAP device under Linux (/dev/net/tun). Some things to note: 1) I've only tested this under Linux. 2) The help-win.c file under cbits HAS allowed similar code to talk to the TUN/TAP driver used by the OpenVPN project, but I haven't implemented this functionality yet. 3) The help-bsd.c file under cbits HAS allowed Mac/BSD flavors to talk to a TUN/TAP driver, but I've never tested this and haven't implemented this functionality yet. I don't have a whole lot there right now, but keep a lookout for more releases with some examples and better docs (as I get around to it). For a very verbose example, you can look at how I use the Network.TUNTAP module in this project: http://github.com/sw17ch/Scurry, specifically http://github.com/sw17ch/Scurry/blob/master/src/Scurry/TAPTask.hs. Hackage: http://hackage.haskell.org/package/tuntap GitHub: http://github.com/sw17ch/tuntap John Van Enk PS: Thanks to Matthew Isleb and Job Vranish for their help on the C code used. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100106/2befe524/attachment.html From ekmett at gmail.com Thu Jan 7 00:01:20 2010 From: ekmett at gmail.com (Edward Kmett) Date: Wed Jan 6 23:34:14 2010 Subject: [Haskell-cafe] Explicit garbage collection In-Reply-To: <7fb8f82f1001061928o4a58ac46qbaaf00691f26e304@mail.gmail.com> References: <4B44958A.2080809@yandex.ru> <201001060906.51127.dan.doel@gmail.com> <4B44A09C.8040103@yandex.ru> <7fb8f82f1001061221v40ffe0cby8c0e4b453e72d65d@mail.gmail.com> <7fb8f82f1001061928o4a58ac46qbaaf00691f26e304@mail.gmail.com> Message-ID: <7fb8f82f1001062101s44d45b59v83d176d12287243@mail.gmail.com> Here is a slightly nicer version using the Codensity monad of STM. Thanks go to Andrea Vezzosi for figuring out an annoying hanging bug I was having. -Edward Kmett {-# LANGUAGE Rank2Types, GeneralizedNewtypeDeriving, DeriveFunctor #-}module STMOracle ( Oracle, Ref , newRef, readRef, writeRef, modifyRef, needRef ) whereimport Control.Applicativeimport Control.Monadimport Control.Concurrent.STMinstance Applicative STM where pure = return (<*>) = apnewtype Ref s a = Ref (TVar (Maybe a))newtype Oracle s a = Oracle { unOracle :: forall r. (a -> STM r) -> STM r } deriving (Functor)instance Monad (Oracle s) where return x = Oracle (\k -> k x) Oracle m >>= f = Oracle (\k -> m (\a -> unOracle (f a) k))mkOracle m = Oracle (m >>=)runOracle :: (forall s. Oracle s a) -> IO arunOracle t = atomically (unOracle t return)newRef :: a -> Oracle s (Ref s a)newRef a = mkOracle $ Ref <$> newTVar (Just a)readRef :: Ref s a -> Oracle s areadRef (Ref r) = mkOracle $ do m <- readTVar r maybe retry return mwriteRef :: a -> Ref s a -> Oracle s awriteRef a (Ref r) = mkOracle $ do writeTVar r (Just a) return amodifyRef :: (a -> a) -> Ref s a -> Oracle s amodifyRef f r = do a <- readRef r writeRef (f a) rneedRef :: Ref s a -> Oracle s BoolneedRef (Ref slot) = Oracle $ \k -> (writeTVar slot Nothing >> k False) `orElse` k True-- test case: refMaybe b dflt ref = if b then readRef ref else return dfltrefIgnore ref = return "blablabla"refFst ref = fst `fmap` readRef reftest = do a <- newRef "x" b <- newRef 1 c <- newRef ('z', Just 0) -- no performLocalGC required x <- needRef a y <- needRef b z <- needRef c u <- refMaybe y "t" a -- note that it wouldn't actually read "a", -- but it won't be known until runtime. w <- refIgnore b v <- refFst c return (x, y, z) On Wed, Jan 6, 2010 at 10:28 PM, Edward Kmett wrote: > I don't believe you can get quite the semantics you want. However, you can > get reasonably close, by building a manual store and backtracking. > > {-# LANGUAGE Rank2Types #-} > -- lets define an Oracle that tracks whether or not you might need the > reference, by backtracking. > module Oracle > ( Oracle, Ref > , newRef, readRef, writeRef, modifyRef, needRef > ) where > > import Control.Applicative > import Control.Arrow (first) > import Control.Monad > import Data.IntMap (IntMap) > import qualified Data.IntMap as M > import Unsafe.Coerce (unsafeCoerce) > import GHC.Prim (Any) > > -- we need to track our own worlds, otherwise we'd have to build over ST, > change optimistically, and track how to backtrack the state of the Store. > Much uglier. > -- values are stored as 'Any's for safety, see GHC.Prim for a discussion on > the hazards of risking the storage of function types using unsafeCoerce as > anything else. > data World s = World { store :: !(IntMap Any), hwm :: !Int } > > -- references into our store > newtype Ref s a = Ref Int deriving (Eq) > > -- our monad that can 'see the future' ~ StateT (World s) [] > newtype Oracle s a = Oracle { unOracle :: World s -> [(a, World s)] } > > -- we rely on the fact that the list is always non-empty for any oracle you > can run. we are only allowed to backtrack if we thought we wouldn't need the > reference, and wound up needing it, so head will always succeed. > runOracle :: (forall s. Oracle s a) -> a > runOracle f = fst $ head $ unOracle f $ World M.empty 1 > > > instance Monad (Oracle s) where > return a = Oracle $ \w -> [(a,w)] > Oracle m >>= k = Oracle $ \s -> do > (a,s') <- m s > unOracle (k a) s' > > -- note: you cannot safely define fail here without risking a crash in > runOracle > -- Similarly, we're not a MonadPlus instance because we always want to > succeed eventually. > > instance Functor (Oracle s) where > fmap f (Oracle g) = Oracle $ \w -> first f <$> g w > > instance Applicative (Oracle s) where > pure = return > (<*>) = ap > > -- new ref allocates a fresh slot and inserts the value into the store. the > type level brand 's' keeps us safe, and we don't export the Ref constructor. > newRef :: a -> Oracle s (Ref s a) > newRef a = Oracle $ \(World w t) -> > [(Ref t, World (M.insert t (unsafeCoerce a) w) (t + 1))] > > -- readRef is the only thing that ever backtracks, if we try to read a > reference we claimed we wouldn't need, then we backtrack to when we decided > we didn't need the reference, and continue with its value. > readRef :: Ref s a -> Oracle s a > readRef (Ref slot) = Oracle $ \world -> > maybe [] (\a -> [(unsafeCoerce a, world)]) $ M.lookup slot (store > world) > > -- note, writeRef dfoesn't 'need' the ref's current value, so needRef will > report False if you writeRef before you read it after this. > writeRef :: a -> Ref s a -> Oracle s a > writeRef a (Ref slot) = Oracle $ \world -> > [(a, world { store = M.insert slot (unsafeCoerce a) $ store world > })] > > {- > -- alternate writeRef where writing 'needs' the ref. > writeRef :: a -> Ref s a -> Oracle s a > writeRef a (Ref slot) = Oracle $ \World store v -> do > (Just _, store') <- return $ updateLookupWithKey replace slot store > [(a, World store' v)] > where > replace _ _ = Just (unsafeCoerce a) > -} > > -- modifying a reference of course needs its current value. > modifyRef :: (a -> a) -> Ref s a -> Oracle s a > modifyRef f r = do > a <- readRef r > writeRef (f a) r > > -- needRef tries to continue executing the world without the element in the > store in question. if that fails, then we'll backtrack to here, and try > again with the original world, and report that the element was in fact > needed. > needRef :: Ref s a -> Oracle s Bool > needRef (Ref slot) = Oracle $ \world -> > [ (False, world { store = M.delete slot $ store world }) > , (True, world) > ] > > -- test case: > refMaybe b dflt ref = if b then readRef ref else return dflt > refIgnore ref = return "blablabla" > refFst ref = fst <$> readRef ref > test = do > a <- newRef "x" > b <- newRef 1 > c <- newRef ('z', Just 0) > -- no performLocalGC required > x <- needRef a > y <- needRef b > z <- needRef c > u <- refMaybe y "t" a -- note that it wouldn't actually read "a", > -- but it won't be known until runtime. > w <- refIgnore b > v <- refFst c > return (x, y, z) > > -- This will disagree with your desired answer, returning: > > *Oracle> runOracle test > Loading package syb ... linking ... done. > Loading package array-0.2.0.0 ... linking ... done. > Loading package containers-0.2.0.1 ... linking ... done. > (False,False,True) > > rather than (True, False, True), because the oracle is able to see into the > future (via backtracking) to see that refMaybe doesn't use the reference > after all. > > This probably won't suit your needs, but it was a fun little exercise. > > -Edward Kmett > > On Wed, Jan 6, 2010 at 4:05 PM, Miguel Mitrofanov wrote: > >> >> On 6 Jan 2010, at 23:21, Edward Kmett wrote: >> >> You probably just want to hold onto weak references for your >>> 'isStillNeeded' checks. >>> >> >> That's what I do now. But I want to minimize the network traffic, so I >> want referenced values to be garbage collected as soon as possible - and I >> couldn't find anything except System.Mem.performIO to do the job - which is >> a bit too global for me. >> >> Otherwise the isStillNeeded check itself will keep you from garbage >>> collecting! >>> >> >> Not necessary. What I'm imagining is that there is essentially only one >> way to access the value stored in the reference - with readRef. So, if there >> isn't any chance that readRef would be called, the value can be garbage >> collected; "isStillNeeded" function only needs the reference, not the value. >> >> Well, yeah, that's kinda like weak references. >> >> >> http://cvs.haskell.org/Hugs/pages/libraries/base/System-Mem-Weak.html >>> >>> -Edward Kmett >>> >>> On Wed, Jan 6, 2010 at 9:39 AM, Miguel Mitrofanov >>> wrote: >>> I'll take a look at them. >>> >>> I want something like this: >>> >>> refMaybe b dflt ref = if b then readRef ref else return dflt >>> refIgnore ref = return "blablabla" >>> refFst ref = >>> do >>> (v, w) <- readRef ref >>> return v >>> test = >>> do >>> a <- newRef "x" >>> b <- newRef 1 >>> c <- newRef ('z', Just 0) >>> performLocalGC -- if necessary >>> x <- isStillNeeded a >>> y <- isStillNeeded b >>> z <- isStillNeeded c >>> u <- refMaybe y "t" a -- note that it wouldn't actually read "a", >>> -- but it won't be known until runtime. >>> w <- refIgnore b >>> v <- refFst c >>> return (x, y, z) >>> >>> so that "run test" returns (True, False, True). >>> >>> >>> Dan Doel wrote: >>> On Wednesday 06 January 2010 8:52:10 am Miguel Mitrofanov wrote: >>> Is there any kind of "ST" monad that allows to know if some STRef is no >>> longer needed? >>> >>> The problem is, I want to send some data to an external storage over a >>> network and get it back later, but I don't want to send unnecessary >>> data. >>> >>> I've managed to do something like that with weak pointers, >>> System.Mem.performGC and unsafePerformIO, but it seems to me that >>> invoking >>> GC every time is an overkill. >>> >>> Oh, and I'm ready to trade the purity of runST for that, if necessary. >>> >>> You may be able to use something like Oleg's Lightweight Monadic Regions >>> to get this effect. I suppose it depends somewhat on what qualifies a >>> reference as "no longer needed". >>> >>> http://www.cs.rutgers.edu/~ccshan/capability/region-io.pdf >>> >>> I'm not aware of anything out-of-the-box that does what you want, though. >>> >>> -- Dan >>> _______________________________________________ >>> 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 mailing list >>> Haskell-Cafe@haskell.org >>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100106/e69b67b2/attachment.html From miguelimo38 at yandex.ru Thu Jan 7 00:52:45 2010 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Thu Jan 7 00:25:39 2010 Subject: [Haskell-cafe] Explicit garbage collection In-Reply-To: <7fb8f82f1001062101s44d45b59v83d176d12287243@mail.gmail.com> References: <4B44958A.2080809@yandex.ru> <201001060906.51127.dan.doel@gmail.com> <4B44A09C.8040103@yandex.ru> <7fb8f82f1001061221v40ffe0cby8c0e4b453e72d65d@mail.gmail.com> <7fb8f82f1001061928o4a58ac46qbaaf00691f26e304@mail.gmail.com> <7fb8f82f1001062101s44d45b59v83d176d12287243@mail.gmail.com> Message-ID: <7BB0709F-F74E-4181-BA49-D292193DABF9@yandex.ru> Seems very nice. Thanks. On 7 Jan 2010, at 08:01, Edward Kmett wrote: > Here is a slightly nicer version using the Codensity monad of STM. > > Thanks go to Andrea Vezzosi for figuring out an annoying hanging bug > I was having. > > -Edward Kmett > > {-# LANGUAGE Rank2Types, GeneralizedNewtypeDeriving, DeriveFunctor #-} > module STMOracle > ( Oracle, Ref > , newRef, readRef, writeRef, modifyRef, needRef > ) where > > import Control.Applicative > import Control.Monad > import Control.Concurrent.STM > > instance Applicative STM where > pure = return > (<*>) = ap > > newtype Ref s a = Ref (TVar (Maybe a)) > newtype Oracle s a = Oracle { unOracle :: forall r. (a -> STM r) -> > STM r } deriving (Functor) > > instance Monad (Oracle s) where > return x = Oracle (\k -> k x) > Oracle m >>= f = Oracle (\k -> m (\a -> unOracle (f a) k)) > > mkOracle m = Oracle (m >>=) > > runOracle :: (forall s. Oracle s a) -> IO a > runOracle t = atomically (unOracle t return) > > newRef :: a -> Oracle s (Ref s a) > newRef a = mkOracle $ Ref <$> newTVar (Just a) > > readRef :: Ref s a -> Oracle s a > readRef (Ref r) = mkOracle $ do > m <- readTVar r > maybe retry return m > > writeRef :: a -> Ref s a -> Oracle s a > writeRef a (Ref r) = mkOracle $ do > writeTVar r (Just a) > return a > > modifyRef :: (a -> a) -> Ref s a -> Oracle s a > modifyRef f r = do > a <- readRef r > writeRef (f a) r > > needRef :: Ref s a -> Oracle s Bool > needRef (Ref slot) = Oracle $ \k -> > (writeTVar slot Nothing >> k False) > `orElse` k True > > -- test > case > : > refMaybe b dflt ref = if b then readRef ref else return dflt > refIgnore ref = return "blablabla" > refFst ref = fst `fmap` readRef ref > test = do > a <- newRef "x" > b <- newRef 1 > c <- newRef ('z', Just 0) > -- no performLocalGC required > x <- needRef a > y <- needRef b > z <- needRef c > u <- refMaybe y "t" a -- note that it wouldn't actually read "a", > -- but it won't be known until runtime. > w <- refIgnore b > v <- refFst c > return (x, y, z) > > > > On Wed, Jan 6, 2010 at 10:28 PM, Edward Kmett > wrote: > I don't believe you can get quite the semantics you want. However, > you can get reasonably close, by building a manual store and > backtracking. > > {-# LANGUAGE Rank2Types #-} > -- lets define an Oracle that tracks whether or not you might need > the reference, by backtracking. > module Oracle > ( Oracle, Ref > , newRef, readRef, writeRef, modifyRef, needRef > ) where > > import Control.Applicative > import Control.Arrow (first) > import Control.Monad > import Data.IntMap (IntMap) > import qualified Data.IntMap as M > import Unsafe.Coerce (unsafeCoerce) > import GHC.Prim (Any) > > -- we need to track our own worlds, otherwise we'd have to build > over ST, change optimistically, and track how to backtrack the state > of the Store. Much uglier. > -- values are stored as 'Any's for safety, see GHC.Prim for a > discussion on the hazards of risking the storage of function types > using unsafeCoerce as anything else. > data World s = World { store :: !(IntMap Any), hwm :: !Int } > > -- references into our store > newtype Ref s a = Ref Int deriving (Eq) > > -- our monad that can 'see the future' ~ StateT (World s) [] > newtype Oracle s a = Oracle { unOracle :: World s -> [(a, World s)] } > > -- we rely on the fact that the list is always non-empty for any > oracle you can run. we are only allowed to backtrack if we thought > we wouldn't need the reference, and wound up needing it, so head > will always succeed. > runOracle :: (forall s. Oracle s a) -> a > runOracle f = fst $ head $ unOracle f $ World M.empty 1 > > > instance Monad (Oracle s) where > return a = Oracle $ \w -> [(a,w)] > Oracle m >>= k = Oracle $ \s -> do > (a,s') <- m s > unOracle (k a) s' > > -- note: you cannot safely define fail here without risking a crash > in runOracle > -- Similarly, we're not a MonadPlus instance because we always want > to succeed eventually. > > instance Functor (Oracle s) where > fmap f (Oracle g) = Oracle $ \w -> first f <$> g w > > instance Applicative (Oracle s) where > pure = return > (<*>) = ap > > -- new ref allocates a fresh slot and inserts the value into the > store. the type level brand 's' keeps us safe, and we don't export > the Ref constructor. > newRef :: a -> Oracle s (Ref s a) > newRef a = Oracle $ \(World w t) -> > [(Ref t, World (M.insert t (unsafeCoerce a) w) (t + 1))] > > -- readRef is the only thing that ever backtracks, if we try to read > a reference we claimed we wouldn't need, then we backtrack to when > we decided we didn't need the reference, and continue with its value. > readRef :: Ref s a -> Oracle s a > readRef (Ref slot) = Oracle $ \world -> > maybe [] (\a -> [(unsafeCoerce a, world)]) $ M.lookup slot > (store world) > > -- note, writeRef dfoesn't 'need' the ref's current value, so > needRef will report False if you writeRef before you read it after > this. > writeRef :: a -> Ref s a -> Oracle s a > writeRef a (Ref slot) = Oracle $ \world -> > [(a, world { store = M.insert slot (unsafeCoerce a) $ store > world })] > > {- > -- alternate writeRef where writing 'needs' the ref. > writeRef :: a -> Ref s a -> Oracle s a > writeRef a (Ref slot) = Oracle $ \World store v -> do > (Just _, store') <- return $ updateLookupWithKey replace slot > store > [(a, World store' v)] > where > replace _ _ = Just (unsafeCoerce a) > -} > > -- modifying a reference of course needs its current value. > modifyRef :: (a -> a) -> Ref s a -> Oracle s a > modifyRef f r = do > a <- readRef r > writeRef (f a) r > > -- needRef tries to continue executing the world without the element > in the store in question. if that fails, then we'll backtrack to > here, and try again with the original world, and report that the > element was in fact needed. > needRef :: Ref s a -> Oracle s Bool > needRef (Ref slot) = Oracle $ \world -> > [ (False, world { store = M.delete slot $ store world }) > , (True, world) > ] > > -- test case: > refMaybe b dflt ref = if b then readRef ref else return dflt > refIgnore ref = return "blablabla" > refFst ref = fst <$> readRef ref > test = do > a <- newRef "x" > b <- newRef 1 > c <- newRef ('z', Just 0) > -- no performLocalGC required > x <- needRef a > y <- needRef b > z <- needRef c > u <- refMaybe y "t" a -- note that it wouldn't actually read "a", > -- but it won't be known until runtime. > w <- refIgnore b > v <- refFst c > return (x, y, z) > > -- This will disagree with your desired answer, returning: > > *Oracle> runOracle test > Loading package syb ... linking ... done. > Loading package array-0.2.0.0 ... linking ... done. > Loading package containers-0.2.0.1 ... linking ... done. > (False,False,True) > > rather than (True, False, True), because the oracle is able to see > into the future (via backtracking) to see that refMaybe doesn't use > the reference after all. > > This probably won't suit your needs, but it was a fun little exercise. > > -Edward Kmett > > On Wed, Jan 6, 2010 at 4:05 PM, Miguel Mitrofanov > wrote: > > On 6 Jan 2010, at 23:21, Edward Kmett wrote: > > You probably just want to hold onto weak references for your > 'isStillNeeded' checks. > > That's what I do now. But I want to minimize the network traffic, so > I want referenced values to be garbage collected as soon as possible > - and I couldn't find anything except System.Mem.performIO to do the > job - which is a bit too global for me. > > Otherwise the isStillNeeded check itself will keep you from garbage > collecting! > > Not necessary. What I'm imagining is that there is essentially only > one way to access the value stored in the reference - with readRef. > So, if there isn't any chance that readRef would be called, the > value can be garbage collected; "isStillNeeded" function only needs > the reference, not the value. > > Well, yeah, that's kinda like weak references. > > > http://cvs.haskell.org/Hugs/pages/libraries/base/System-Mem-Weak.html > > -Edward Kmett > > On Wed, Jan 6, 2010 at 9:39 AM, Miguel Mitrofanov > wrote: > I'll take a look at them. > > I want something like this: > > refMaybe b dflt ref = if b then readRef ref else return dflt > refIgnore ref = return "blablabla" > refFst ref = > do > (v, w) <- readRef ref > return v > test = > do > a <- newRef "x" > b <- newRef 1 > c <- newRef ('z', Just 0) > performLocalGC -- if necessary > x <- isStillNeeded a > y <- isStillNeeded b > z <- isStillNeeded c > u <- refMaybe y "t" a -- note that it wouldn't actually read "a", > -- but it won't be known until runtime. > w <- refIgnore b > v <- refFst c > return (x, y, z) > > so that "run test" returns (True, False, True). > > > Dan Doel wrote: > On Wednesday 06 January 2010 8:52:10 am Miguel Mitrofanov wrote: > Is there any kind of "ST" monad that allows to know if some STRef is > no > longer needed? > > The problem is, I want to send some data to an external storage over a > network and get it back later, but I don't want to send unnecessary > data. > > I've managed to do something like that with weak pointers, > System.Mem.performGC and unsafePerformIO, but it seems to me that > invoking > GC every time is an overkill. > > Oh, and I'm ready to trade the purity of runST for that, if necessary. > > You may be able to use something like Oleg's Lightweight Monadic > Regions to get this effect. I suppose it depends somewhat on what > qualifies a reference as "no longer needed". > > http://www.cs.rutgers.edu/~ccshan/capability/region-io.pdf > > I'm not aware of anything out-of-the-box that does what you want, > though. > > -- Dan > _______________________________________________ > 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 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 From ivan.miljenovic at gmail.com Thu Jan 7 01:48:51 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Thu Jan 7 01:21:51 2010 Subject: [Haskell-cafe] darcs 2.4 beta 1 release In-Reply-To: <16442B752A06A74AB4D9F9A5FF076E4B03B9FE4D@ELON17P32001A.csfb.cs-group.com> (Ganesh Sittampalam's message of "Wed, 6 Jan 2010 15:28:30 -0000") References: <201001051918.38069.tux_rocker@reinier.de> <87fx6j8hpt.fsf@gmail.com> <16442B752A06A74AB4D9F9A5FF076E4B03B9FE4D@ELON17P32001A.csfb.cs-group.com> Message-ID: <87bph64dgs.fsf@gmail.com> "Sittampalam, Ganesh" writes: > Obviously source code documentation would be nice, but why is it > "show-stopping"? I consider it "show-stopping" in the sense that I keep having people on #gentoo-haskell asking me why they can't compile darcs 2.3.1 because that error comes up, and I have to explain to either disable documentation or downgrade Cabal (if they're still using Ivan Lazar Miljenovic wrote: >> I really feel that bug 1720 [1] is a show-stopping bug for darcs, >> especially since it means that building Haddock for darcs with >> GHC-6.12.* isn't possible. >> >> [1] http://bugs.darcs.net/issue1720 >> >> I tried to make a fix, but didn't know enough of how darcs is >> documented to be able to do anything. >> >> >> Reinier Lamers writes: >> >>> Hi all, >>> >>> The darcs team would like to announce the immediate availability of >>> darcs 2.4 beta 1. darcs 2.4 will contain many improvements and >>> bugfixes compared to darcs 2.3.1. Highlights are the fast index-based >>> diffing which is now used by all darcs commands, and the interactive >>> hunk-splitting in darcs record. This beta is your chance to >>> test-drive >>> these improvements and make darcs even better. >>> >>> If you have installed the Haskell Platform or cabal-install, you can >>> install this beta release by doing: >>> >>> $ cabal update >>> $ cabal install --reinstall darcs-beta >>> >>> Alternatively, you can download the tarball from >>> http://darcs.net/releases/darcs-2.3.98.1.tar.gz , and build it by >>> hand >>> as explained in the README file. >>> >>> A list of important changes since 2.3.1 is as follows (please let me >>> know if there's something you miss!): >>> >>> * Use fast index-based diffing everywhere (Petr) >>> * Interactive patch splitting (Ganesh) >>> * An 'optimize --upgrade' option to convert to hashed format >>> in-place (Eric) >>> * Hunk matching (Kamil Dworakowski, tat.wright) >>> * Progress reporting is no longer deceptive (Roman Pl??il) >>> * A 'remove --recursive' option to remove a directory tree from >>> revision control (Roman Pl??il) >>> * A '--remote-darcs' flag for pushing to a host where darcs isn't >>> called darcs >>> * Many miscellaneous Windows improvements (Salvatore, Petr and >>> others) >>> * 'darcs send' now mentions the repository name in the email body >>> (Joachim) >>> * Handle files with boring names in the repository correctly >>> (Petr) >>> * Fix parsing of .authorspellings file (Tom?? Caitt) >>> * Various sane new command-line option names (Florent) >>> * Remove the '--checkpoint' option (Petr) >>> * Use external libraries for all UTF-8 handling (Eric, Reinier) >>> * Use the Haskell zlib package exclusively for compression (Petr) >>> >>> Kind Regards, >>> the darcs release manager, >>> Reinier Lamers >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> Haskell-Cafe@haskell.org >>> http://www.haskell.org/mailman/listinfo/haskell-cafe > > > =============================================================================== > Please access the attached hyperlink for an important electronic communications disclaimer: > http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html > =============================================================================== > -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From ck_kashyap at yahoo.com Thu Jan 7 03:37:42 2010 From: ck_kashyap at yahoo.com (CK Kashyap) Date: Thu Jan 7 03:10:35 2010 Subject: [Haskell-cafe] Review request for my permutations implementation Message-ID: <121533.40261.qm@web112506.mail.gq1.yahoo.com> Hi All, I've written this piece of code to do permutations - perms :: String -> [String] perms []= [] perms (x:[])= [[x]] perms (x:xs)= concat (f [x] (perms xs)) spread :: String -> String -> [String] -- interpolate first string at various positions of second string spread str1 str2 = _spread str1 str2 (length str2) where _spread str1 str2 0= [str1 ++ str2] _spread str1 str2 n= [(take n str2) ++ str1 ++ (drop n str2)] ++ (_spread str1 str2 (n-1)) f xs = map (spread xs) The number of outcomes seem to indicate that correctness of the algo .. however, I'd be very obliged if I could get some feedback on the Haskellness etc of this ... also any performance pointers ... Regards, Kashyap From jochem at functor.nl Thu Jan 7 04:46:40 2010 From: jochem at functor.nl (Jochem Berndsen) Date: Thu Jan 7 04:19:36 2010 Subject: [Haskell-cafe] Review request for my permutations implementation In-Reply-To: <121533.40261.qm@web112506.mail.gq1.yahoo.com> References: <121533.40261.qm@web112506.mail.gq1.yahoo.com> Message-ID: <4B45AD80.9010502@functor.nl> CK Kashyap wrote: > I've written this piece of code to do permutations - First off, this is a recurring topic. If you search the archives, you'll find some more topics about it. > perms :: String -> [String] Why this type? Since a String is just a list of Char, and you don't use the fact that you're actually using a list of characters. It's better to keep this function generic, and say perms :: [a] -> [[a]] > perms []= [] I don't think this is what you expect or want. I would consider a permutation of X to be a bijection X -> X. The number of bijections X -> X when X is empty, is in fact 1. So I think perms [] = [[]] > perms (x:[])= [[x]] I think you can drop this case if you do perms [] = [[]]. (Didn't prove it, though.) > perms (x:xs)= concat (f [x] (perms xs)) A small stylistic issue: Normally I'd write a space before the '='. > spread :: String -> String -> [String] -- interpolate first string at various positions of second string This function becomes easier if you define it like spread :: a -> [a] -> [[a]] since you only use it in that way. > spread str1 str2 = _spread str1 str2 (length str2) > where > _spread str1 str2 0= [str1 ++ str2] > _spread str1 str2 n= [(take n str2) ++ str1 ++ (drop n str2)] ++ (_spread str1 str2 (n-1)) > > f xs = map (spread xs) There is a better way to write spread, something like spread str1 xs = zipWith (\x y -> x ++ str1 ++ y) (inits xs) (tails xs) with inits and tails from Data.List. HTH, regards, Jochem -- Jochem Berndsen | jochem@functor.nl | jochem@????.com From ozgurakgun at gmail.com Thu Jan 7 05:06:31 2010 From: ozgurakgun at gmail.com (Ozgur Akgun) Date: Thu Jan 7 04:39:25 2010 Subject: [Haskell-cafe] Problem with cabal install zlib In-Reply-To: <87zl4qlr9t.fsf@gregorycollins.net> References: <7be1feae0912181501t212357ecge4d486b2798a23f0@mail.gmail.com> <1261212888.9220.56169.camel@localhost> <7be1feae0912190139w5724b1eatf80635445064840b@mail.gmail.com> <1261269079.9220.59827.camel@localhost> <7be1feae0912211508k4476d0cdq1473e1211a8870fd@mail.gmail.com> <1261514309.9220.77361.camel@localhost> <7be1feae0912221348j4609e771p81f4eefd2406ebb3@mail.gmail.com> <1261520904.9220.77808.camel@localhost> <7be1feae1001061438v7d3ace75n56291e91d28d686e@mail.gmail.com> <87zl4qlr9t.fsf@gregorycollins.net> Message-ID: <7be1feae1001070206s724eb42clcfd4e7416a4e767f@mail.gmail.com> Oh! I was pretty sure that I made these patches correctly. But guess what, the added flags to hsc2hs are different from the others. And I did a bling copy/paste. Thanks for reminding it Gregory. Best, 2010/1/6 Gregory Collins > Ozgur Akgun writes: > > > Just to check, anyone running Snow Leopard and *CAN* install > > "zlib-0.5.2.0" using "cabal install zlib"? > > > > I'm trying to make sure whether I am the only one having this problem > > or I have some companion. > > $ cabal install --reinstall zlib > Resolving dependencies... > Configuring zlib-0.5.2.0... > Preprocessing library zlib-0.5.2.0... > Building zlib-0.5.2.0... > [1 of 5] Compiling Codec.Compression.Zlib.Stream ( > dist/build/Codec/Compression/Zlib/Stream.hs, > dist/build/Codec/Compression/Zlib/Stream.o ) > [2 of 5] Compiling Codec.Compression.Zlib.Internal ( > Codec/Compression/Zlib/Internal.hs, > dist/build/Codec/Compression/Zlib/Internal.o ) > [3 of 5] Compiling Codec.Compression.Zlib.Raw ( > Codec/Compression/Zlib/Raw.hs, dist/build/Codec/Compression/Zlib/Raw.o ) > [4 of 5] Compiling Codec.Compression.Zlib ( Codec/Compression/Zlib.hs, > dist/build/Codec/Compression/Zlib.o ) > [5 of 5] Compiling Codec.Compression.GZip ( Codec/Compression/GZip.hs, > dist/build/Codec/Compression/GZip.o ) > ar: creating archive dist/build/libHSzlib-0.5.2.0.a > Installing library in /Users/greg/.cabal/lib/zlib-0.5.2.0/ghc-6.10.4 > Registering zlib-0.5.2.0... > Reading package info from "dist/installed-pkg-config" ... done. > Writing new package config file... done. > > No problem here. Please ensure you've patched /usr/bin/ghc, > /usr/bin/ghci, /usr/bin/runhaskell, /usr/bin/runghc, and /usr/bin/hsc2hs > according to the instructions on http://haskell.org/haskellwiki/OSX . > > The next release of the Haskell Platform installer should fix this > issue. > > G > -- > Gregory Collins > -- Ozgur Akgun -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100107/7ef523ce/attachment.html From apfelmus at quantentunnel.de Thu Jan 7 05:43:44 2010 From: apfelmus at quantentunnel.de (Heinrich Apfelmus) Date: Thu Jan 7 05:17:01 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001030508.46357.daniel.is.fischer@web.de> <201001040129.22689.daniel.is.fischer@web.de> Message-ID: Will Ness wrote: > Heinrich Apfelmus writes: > >> Concerning lists as producer/consumer, I think that's exactly what lazy >> evaluation is doing. Neither filter , map or span evaluate and >> store more list elements that strictly necessary. > > I laways suspected as much, but was once told that Chris Okasaki has shown that > any filter etc must allocate its own storage. With the peek/pull they don't > have to, if they are nested, and the deepest one from the real storage gets > pulled through some pointer chasing eventually. Span isn't so easily compiled > out too or is it? But that might be a minor point. Hm? In my world view, there is only reduction to normal form and I don't see how "allocate its own storage" fits in there. Okasaki having shown something to that end would be new to me? > I did that once in Scheme, as per SICP, with 'next' hanging in a stream's tail. > Put filters and maps on top of that (inside the new 'next' actually). But that > used the Scheme's lists as sorage. Another one was actual producers/modifiers > with {pull,peek} interface. It even produced some primes, and some Hamming > numbers. Then I saw Haskell, and thought I'd get all that for free with its > equational reasoning. > > But I get the impression that GHC isn't working through equational reasoning?.. > I see all this talk about thunks etc. Sure it does. Concerning the thunks, they're part of the implementation of the reduction model (call-by-need aka lazy evaluation). >> Concerning the sieves, there is a fundamental difference between the >> imperative sieve and the functional sieves, regardless of whether the >> latter start at p or p^2 or use a priority queue. [...] > > We can directy jump to the next multiple too, it is called (+). :) :) > > But seriously, the real issue is that we have to merge the produced streams of > multiples, while the mutable-storage code works on same one, so its "merging > cost" is zero. And even if we are smart to merge them in a tree-like fashion, > we still have no (or little) control over the compiler's representation of > lists and retention of their content and whether it performs stream fusion or > not (if we use lists). Not quite, I think there are two things going on: 1. In contrast to the standard imperative version, we are implementing an on-line algorithm that produces arbitrarily many primes on demand. Any imperative on-line version will need to think about storage for pending prime filters as well. 2. Even the imperative algorithm can be interpreted as "merging" arrays, just that the composites are magically merged at the right place (at distance p from each other) because arrays offer O(1) "jumps". In contrast, the functional version needs O(log something) time to calculate where to put the next composite. > If you could take a look at the tree-merging primes and why it uses too much > memory, it would be great. Fortunately, Daniel already took a detailed look. :) But I also have a few remarks. > The code is in Daniel's post to which I replied, or > on haskellwiki Prime_numbers page (there in its rudimentary form). It's a tangent > to your VIP code, where instead of People structure an ordered list is just > maintained as a split pair, of its known (so far, finite) prefix and the rest > of it. Aww, why remove the cutesy name? The VIPs will be angry for being ignored! Jest aside, note that putting the crowd at the end of the list where it belongs has a reason: you have a guarantee that crowds won't take any memory until they actually appear after all the VIPs. If you put both VIPs and the crowd into a pair, it's easier to get space leaks. In particular, I think that your mergeSP has a laziness bug, it should be mergeSP ~(a,b) ~(c,d) = ... This is a cure for the (potential) problem that spMerge first performs a pattern match / comparison and then returns a pair constructor instead of the other way round. For instance, your second case spMerge u [] = ([], u) should actually behave like spMerge u v = (a,b) where a = if null v then [] else ... b = if null v then u else ... (I don't recommend rewriting spMerge in this fashion, the lazy pattern in mergeSP will do the trick.) Now, I'm not sure whether this is actually a problem or not. But the version shown here, with two lazy patterns instead of just one, is much closer to how the original People structure behaves. > Then under merging these split pairs form a monoid, s can be rearranged > in a tree. If you haven't seen it yet, it uses a different folding structure to > your code, with a lower total cost of multiples production (estimated as Sum > (1/p)*depth): > > tfold f (x:y:z:xs) = (x `f` (y `f` z)) `f` pairwise f xs > comps = tfold $ pairwise mergeSP multips The idea being that each prime produces 1/p composites each "turn" and it takes time depth to trickle it to the top? Sounds reasonable, but remember that a prime p does not start to generate composites until the "turn count" has reached p^2, so it might occupy a place of low depth in the tree that is better spent on the previous primes. But your experiments seem to tell that it works anyway. By the way, I think that both tfold and pairwise need to be lazier. tfold f ~(x: ~(y: ~(z:zs))) = (x `f` (y `f` z)) `f` pairwise f zs pairwise f ~(x: ~(y:ys)) = f x y : pairwise f ys Otherwise, large parts of the tree might be generated too early and hog memory. Also, a small remark on style: I don't like the repetition of mergeSP in compos = fst $ tfold mergeSP (pairwise mergeSP (multip ps)) After all, the right hand side is just another tree fold and I would clearly mark it as such: compos = fst . superSmartTreeFold mergeSP . multip $ ps superSmartTreeFold f = tfold f . pairwise f ;) > I think I'll have to try out your code (amended with a new folding structure) > and see if it has less memory problems maybe. > I assume it is your code on the haskellwiki page. (?) Yes, I put the code snippet on the wiki. And never tested it on large numbers. ;) Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com From daniel.is.fischer at web.de Thu Jan 7 05:46:33 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Thu Jan 7 05:21:07 2010 Subject: [Haskell-cafe] Review request for my permutations implementation In-Reply-To: <121533.40261.qm@web112506.mail.gq1.yahoo.com> References: <121533.40261.qm@web112506.mail.gq1.yahoo.com> Message-ID: <201001071146.33695.daniel.is.fischer@web.de> Am Donnerstag 07 Januar 2010 09:37:42 schrieb CK Kashyap: > Hi All, > > I've written this piece of code to do permutations - > > perms :: String -> [String] Nothing in the algorithm needs the list elements to be Chars, there's no type class involved, so it should be perms :: [a] -> [[a]] > perms []= [] This should actually be perms [] = [[]] > perms (x:[])= [[x]] That is then superfluous. > perms (x:xs)= concat (f [x] (perms xs)) > 'f' is a good name for a function parameter, not for a top level binding. Why not perms (x:xs) = concat (map (spread [x]) (perms xs)) whcih you can reformulate as perms (x:xs) = concatMap (spread [x]) (perms xs) or, if you like Monads, since concatMap is just the bind operator of the []-monad, perms (x:xs) = perms xs >>= spread [x] Which can be written as a simple do-block: perms (x:xs) = do prm <- perms xs spread [x] prm or a list-comprehension perms (x:xs) = [permutation | tailPerm <- perms xs, permutation <- spread [x] tailPerm] > spread :: String -> String -> [String] -- interpolate first string at > various positions of second string spread str1 str2 = _spread str1 str2 > (length str2) > where > _spread str1 str2 0= [str1 ++ str2] > _spread str1 str2 n= [(take n str2) ++ str1 ++ (drop n str2)] ++ (_spread > str1 str2 (n-1)) > import Data.List spread short long = zipWith (\a b -> a ++ short ++ b) (inits long) (tails long) If you only use spread for perms, you never interpolate anything but single element lists, so you might consider spread' :: a -> [a] -> [[a]] spread' x xs = zipWith (\a b -> a ++ x:b) (inits xs) (tails xs) But if you import Data.List, you could also say perms = permutations and be done with it :) (except if you 1. need the permutations in a particular order, which is different from the one Data.List.permutations generates, or 2. you need it to be as fast as possible - Data.List.permutations was written to also cope with infinite lists, so a few things that could speed up generation of permutations for short lists couldn't be used). > f xs = map (spread xs) > > > The number of outcomes seem to indicate that correctness of the algo .. Apart from the case of empty input, it is correct. > however, I'd be very obliged if I could get some feedback on the > Haskellness etc of this ... also any performance pointers ... Re performance: I think the repeated (take k) and (drop k) in your spread are likely to be slower than using inits and tails, but it would need measuring the performance to be sure. I don't see anything that would automatically give bad performance. But there's the question of repeated elements. perms "aaaaabbbbb" spills out 3628800 permutations, but there are only 252 distinct permutations, each of them appearing 120^2 = 14400 times. If your input may contain repeated elements and you're 1. only interested in the distinct permutations (and 2.) or 2. don't care about the order in which the permutations are generated, distinctPerms :: Ord a => [a] -> [[a]] distinctPerms = foldr inserts [[]] . group . sort inserts :: [a] -> [[a]] -> [[a]] inserts xs yss = yss >>= (mingle xs) mingle :: [a] -> [a] -> [[a]] mingle xs [] = [xs] mingle [] ys = [ys] mingle xxs@(x:xs) yys@(y:ys) = [x:zs | zs <- mingle xs yys] ++ [y:zs | zs <- mingle xxs ys] generates the distinct permutations much faster if there are many repeated elements; if you want each distinct permutation repeated the appropriate number of times, the modification is easy. > > > Regards, > Kashyap -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100107/ab400cf4/attachment-0001.html From v.dijk.bas at gmail.com Thu Jan 7 05:50:12 2010 From: v.dijk.bas at gmail.com (Bas van Dijk) Date: Thu Jan 7 05:23:27 2010 Subject: [Haskell-cafe] ANNOUNCE: safer-file-handles-0.1 Message-ID: Hello, I'm happy to announce another member in the 'monadic regions' family: safer-file-handles: http://hackage.haskell.org/package/safer-file-handles-0.1 The package uses my 'regions' and 'explicit-iomodes' packages to add two safety features on top of the regular System.IO file handles and operations: * Regional file handles. Files must be opened in a region. When the region terminates all opened files are automatically closed. The main advantage of regions is that the handles to the opened files can not be returned from the region which ensures no I/O with closed files is possible. * Explicit IOModes. The regional file handles are parameterized by the IOMode in which they were opened. All operations on handles explicitly specify the needed IOMode. This way it is impossible to read from a write-only handle or write to a read-only handle for example. The primary technique used in this package is called "Lightweight monadic regions" which was invented by Oleg Kiselyov and Chung-chieh Shan. See: http://okmij.org/ftp/Haskell/regions.html#light-weight This technique is implemented in the 'regions' package which is re-exported from 'safer-file-handles'. See the 'safer-file-handles-examples' package for examples how to use this package: darcs get http://code.haskell.org/~basvandijk/code/safer-file-handles-examples regards, Bas P.S. While I wrote this message I realized a serious lack of expressive power of my regions package. Namely that I can't write a program that opens two different types of resources in the _same_ region. If for example I want to combine my usb-safe package and this package the following won't type-check: openBoth ? Device ? FilePath ? IO () openBoth usbDevice filePath = runTopRegion $ do h1 ? open usbDevice ? RegionT Device s IO (RegionalHandle Device (RegionT Device s IO)) h2 ? openFile filePath ReadMode ? RegionT File s IO (RegionalHandle File (RegionT File s IO)) return () The reason, as can be seen from the types of the monadic actions, is that the monad types differ between the two actions and bind ((>>=) :: Monad m => m a -> (a -> m b) -> m b) obviously requires them to be the same. The main problem thus, is that I parameterized the region with the type of resources. Note that I'm working on a solution where I remove the resource type from RegionT. So instead of: newtype RegionT resource s (pr ? * ? *) ? = RegionT { unRegionT ? ReaderT (IORef [Opened resource]) pr ? } I will have: newtype RegionT s (pr ? * ? *) ? = RegionT { unRegionT ? ReaderT (IORef [SomeOpenedResource]) pr ? } data SomeOpenedResource = ? resource. Resource resource ? Some (Opened resource) Hopefully I will be able to release this fix before FP-NL tomorrow. From RafaelGCPP.Linux at gmail.com Thu Jan 7 06:39:39 2010 From: RafaelGCPP.Linux at gmail.com (Rafael Gustavo da Cunha Pereira Pinto) Date: Thu Jan 7 06:12:33 2010 Subject: [Haskell-cafe] Review request for my permutations implementation In-Reply-To: <201001071146.33695.daniel.is.fischer@web.de> References: <121533.40261.qm@web112506.mail.gq1.yahoo.com> <201001071146.33695.daniel.is.fischer@web.de> Message-ID: <351ff25e1001070339s301b68d7r7cafe59fa7a18a95@mail.gmail.com> Hi, Is there an entry in the haskell wiki for permutations? Since this is a recurring topic, as primes, shouldn't we create a topic for that in the wiki? Regards, Rafael On Thu, Jan 7, 2010 at 08:46, Daniel Fischer wrote: > Am Donnerstag 07 Januar 2010 09:37:42 schrieb CK Kashyap: > > > Hi All, > > > > > > I've written this piece of code to do permutations - > > > > > > perms :: String -> [String] > > Nothing in the algorithm needs the list elements to be Chars, there's no > type class involved, so it should be > > perms :: [a] -> [[a]] > > > perms []= [] > > This should actually be > > perms [] = [[]] > > > perms (x:[])= [[x]] > > That is then superfluous. > > > perms (x:xs)= concat (f [x] (perms xs)) > > > > > 'f' is a good name for a function parameter, not for a top level binding. > > Why not > > perms (x:xs) = concat (map (spread [x]) (perms xs)) > > whcih you can reformulate as > > perms (x:xs) = concatMap (spread [x]) (perms xs) > > or, if you like Monads, since concatMap is just the bind operator of the > []-monad, > > perms (x:xs) = perms xs >>= spread [x] > > Which can be written as a simple do-block: > > perms (x:xs) = do > > prm <- perms xs > > spread [x] prm > > or a list-comprehension > > perms (x:xs) = [permutation | tailPerm <- perms xs, permutation <- spread > [x] tailPerm] > > > spread :: String -> String -> [String] -- interpolate first string at > > > various positions of second string spread str1 str2 = _spread str1 str2 > > > (length str2) > > > where > > > _spread str1 str2 0= [str1 ++ str2] > > > _spread str1 str2 n= [(take n str2) ++ str1 ++ (drop n str2)] ++ (_spread > > > str1 str2 (n-1)) > > > > > import Data.List > > spread short long = zipWith (\a b -> a ++ short ++ b) (inits long) (tails > long) > > If you only use spread for perms, you never interpolate anything but single > element lists, so you might consider > > spread' :: a -> [a] -> [[a]] > > spread' x xs = zipWith (\a b -> a ++ x:b) (inits xs) (tails xs) > > But if you import Data.List, you could also say > > perms = permutations > > and be done with it :) (except if you 1. need the permutations in a > particular order, which is different from the one Data.List.permutations > generates, or 2. you need it to be as fast as possible - > Data.List.permutations was written to also cope with infinite lists, so a > few things that could speed up generation of permutations for short lists > couldn't be used). > > > f xs = map (spread xs) > > > > > > > > > The number of outcomes seem to indicate that correctness of the algo .. > > Apart from the case of empty input, it is correct. > > > however, I'd be very obliged if I could get some feedback on the > > > Haskellness etc of this ... also any performance pointers ... > > Re performance: > > I think the repeated (take k) and (drop k) in your spread are likely to be > slower than using inits and tails, but it would need measuring the > performance to be sure. > > I don't see anything that would automatically give bad performance. > > But there's the question of repeated elements. > > perms "aaaaabbbbb" > > spills out 3628800 permutations, but there are only 252 distinct > permutations, each of them appearing 120^2 = 14400 times. > > If your input may contain repeated elements and you're > > 1. only interested in the distinct permutations (and 2.) or > > 2. don't care about the order in which the permutations are generated, > > distinctPerms :: Ord a => [a] -> [[a]] > > distinctPerms = foldr inserts [[]] . group . sort > > inserts :: [a] -> [[a]] -> [[a]] > > inserts xs yss = yss >>= (mingle xs) > > mingle :: [a] -> [a] -> [[a]] > > mingle xs [] = [xs] > > mingle [] ys = [ys] > > mingle xxs@(x:xs) yys@(y:ys) > > = [x:zs | zs <- mingle xs yys] ++ [y:zs | zs <- mingle xxs ys] > > generates the distinct permutations much faster if there are many repeated > elements; > > if you want each distinct permutation repeated the appropriate number of > times, the modification is easy. > > > > > > > > > Regards, > > > Kashyap > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- Rafael Gustavo da Cunha Pereira Pinto -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100107/eb0e894a/attachment.html From waldmann at imn.htwk-leipzig.de Thu Jan 7 07:11:21 2010 From: waldmann at imn.htwk-leipzig.de (Johannes Waldmann) Date: Thu Jan 7 06:44:23 2010 Subject: [Haskell-cafe] dph and ghc-6.12 ? Message-ID: <4B45CF69.3080909@imn.htwk-leipzig.de> Dear all, I'd love to use Data Parallel Haskell (for now, just as a demonstration, in a lecture). I want to convince my students (and myself) that this thing "really works". What would be an easy-to-understand, but still impressive enough benchmark? (to be run on 8 core amd64)? What is the current status of dph with ghc-6.12? Is there some up-to-date tutorial? Do we still need separate modules/compilation/linking? (... and where can I download the CUDA backend :-) best regards, J.W. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 260 bytes Desc: OpenPGP digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100107/5bd161bb/signature.bin From waldmann at imn.htwk-leipzig.de Thu Jan 7 07:32:03 2010 From: waldmann at imn.htwk-leipzig.de (Johannes Waldmann) Date: Thu Jan 7 07:05:01 2010 Subject: [Haskell-cafe] looking for origin of quote on preprocessors and language design Message-ID: <4B45D443.8020709@imn.htwk-leipzig.de> Dear all, It's not exactly Haskell-specific, but ... I am trying to track down the origin of the proverb "the existence (or: need for) a preprocessor shows omissions in (the design of) a language." I like to think that in Haskell, we don't need preprocessors since we can manipulate programs programmatically, because they are data. In other words, a preprocessor realizes higher order functions, and you only need this if your base language is first-order. Yes, that's vastly simplified, and it does not cover all cases, what about generic programming (but this can be done via Data.Data) and alex/happy (but we have parsec) etc etc. Best regards, J.W. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 260 bytes Desc: OpenPGP digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100107/a1248532/signature.bin From bulat.ziganshin at gmail.com Thu Jan 7 08:03:07 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Thu Jan 7 07:36:04 2010 Subject: [Haskell-cafe] looking for origin of quote on preprocessors and language design In-Reply-To: <4B45D443.8020709@imn.htwk-leipzig.de> References: <4B45D443.8020709@imn.htwk-leipzig.de> Message-ID: <1032693246.20100107160307@gmail.com> Hello Johannes, Thursday, January 7, 2010, 3:32:03 PM, you wrote: > "the existence (or: need for) a preprocessor > shows omissions in (the design of) a language." yes, that's the common opinion. the same true for comments and identifiers :D shortly speaking, preprocessor is just another language on top of our one that has poor integration with main language. this partly solved by so-called syntactical preprocessors and even typeful ones (like Template Haskell) otoh there is no perfect language that is able to express any constraint. so preprocessor, applied to any given language, provides us additional level of expressiveness. so when you have some concrete problem that may be expressed in A only with preprocessor and in B as is - B is definitely better. if you typically write your programs in C++ w/o using preprocessor, and in C - with it, C++ is better. but when your programming level increases, you may go higher expressiveness of language you are using and start to need use of additional preprocessors. so if some language Pascal typically used without preprocessor and some language C - with it, it may just mean that C users are much more experienced and need more expressive power than Pascal ones -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From uzytkownik2 at gmail.com Thu Jan 7 08:04:20 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Thu Jan 7 07:37:39 2010 Subject: [Haskell-cafe] Re: Review request for my permutations implementation In-Reply-To: <121533.40261.qm@web112506.mail.gq1.yahoo.com> References: <121533.40261.qm@web112506.mail.gq1.yahoo.com> Message-ID: <1262869460.6326.102.camel@picard> On Thu, 2010-01-07 at 00:37 -0800, CK Kashyap wrote: > Hi All, > > I've written this piece of code to do permutations - > I assume that it's training piece not real code as in such I'd recommend: > import Data.List > perms = permutations > perms :: String -> [String] > perms []= [] As pointed out perms [] = [[]]. You can note that: length . perms == factorial > perms (x:[])= [[x]] > perms (x:xs)= concat (f [x] (perms xs)) > Don't call function f. I'd look into parameters - i.e. map f xs is = ... ok as f is some user function but f xs does not say what f is (except it is some function ;) ). Also pointed out concatMap: > perms (x:xs) = concatMap spread > spread :: String -> String -> [String] -- interpolate first string at various positions of second string > spread str1 str2 = _spread str1 str2 (length str2) I'd always be careful with (!!) and length. Both have O(n) complexity and I've seen code in which it shifted from O(n^3) to O(n^6) by uncareful usage (usually something like O(n) to O(n^2) per function). > where > _spread str1 str2 0= [str1 ++ str2] > _spread str1 str2 n= [(take n str2) ++ str1 ++ (drop n str2)] ++ (_spread str1 str2 (n-1)) Please note that the first list (here list of chars) have always length 1. It would be nice to indicate it by rewriting into: > spread :: a -> [a] -> [[a]] > spread a b = _spread a b 0 > where > _spread a b 0 = [a:b] > _spread a b n = ((take n b) ++ a:(drop n b)):(_spread a b (n-1)) > perms (x:xs) = concatMap (spread x) (perms xs) I took the liberty of rewriting [a] ++ b into a:b. In fact (:) is base constructor as the list [1,2,3,4] is syntax sugar for 1:2:3:4:[]. Hence it should be marginally more effective w/out optimalizations Further clarification is > spread a b = map (\n -> (take n b) ++ a:(drop n b)) Or: > spread a b = zipWith (\i e -> i ++ a:e) (inits b) (tails b) (\n -> something) is lambda function and is shorthand of ... f ... where f n = something > f xs = map (spread xs) > Why make separate function (not in where) > > The number of outcomes seem to indicate that correctness of the algo .. however, I'd be very obliged > if I could get some feedback on the Haskellness etc of this ... also any performance pointers ... > Minor difficulty with algorithm - it diverges for: > head $ head $ perms [1..] > > Regards, > Kashyap Regards From bulat.ziganshin at gmail.com Thu Jan 7 08:05:56 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Thu Jan 7 07:38:58 2010 Subject: [Haskell-cafe] looking for origin of quote on preprocessors and language design In-Reply-To: <1032693246.20100107160307@gmail.com> References: <4B45D443.8020709@imn.htwk-leipzig.de> <1032693246.20100107160307@gmail.com> Message-ID: <52199979.20100107160556@gmail.com> Hello Bulat, Thursday, January 7, 2010, 4:03:07 PM, you wrote: >> "the existence (or: need for) a preprocessor >> shows omissions in (the design of) a language." forget to add: for language designers, analysis of typical preprocessor usage and adding analogous features to language instead is a great source of inspiration. in particular C++, D and other C descendants used it a lot -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From daniel.is.fischer at web.de Thu Jan 7 08:12:34 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Thu Jan 7 07:47:04 2010 Subject: [Haskell-cafe] Re: Review request for my permutations implementation In-Reply-To: <1262869460.6326.102.camel@picard> References: <121533.40261.qm@web112506.mail.gq1.yahoo.com> <1262869460.6326.102.camel@picard> Message-ID: <201001071412.34598.daniel.is.fischer@web.de> Am Donnerstag 07 Januar 2010 14:04:20 schrieb Maciej Piechotka: > > As pointed out perms [] = [[]]. You can note that: > length . perms == factorial Surely you meant genericLength . perms == factorial . (genericLength :: [a] -> Integer) -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100107/b0e70927/attachment.html From uzytkownik2 at gmail.com Thu Jan 7 08:18:16 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Thu Jan 7 07:51:36 2010 Subject: [Haskell-cafe] Re: looking for origin of quote on preprocessors and language design In-Reply-To: <4B45D443.8020709@imn.htwk-leipzig.de> References: <4B45D443.8020709@imn.htwk-leipzig.de> Message-ID: <1262870296.6326.116.camel@picard> On Thu, 2010-01-07 at 13:32 +0100, Johannes Waldmann wrote: > Dear all, > > It's not exactly Haskell-specific, but ... > I am trying to track down the origin of the proverb > > "the existence (or: need for) a preprocessor > shows omissions in (the design of) a language." > > > I like to think that in Haskell, we don't need > preprocessors since we can manipulate programs > programmatically, because they are data. > > In other words, a preprocessor realizes higher order > functions, and you only need this if your base language > is first-order. > > Yes, that's vastly simplified, and it does not cover > all cases, what about generic programming > (but this can be done via Data.Data) > and alex/happy (but we have parsec) etc etc. > > Best regards, J.W. > Not quite. While I agree that "the *frequent* need for a preprocessor shows omissions in (the design of) a language." it is not necessary the case. Preprocessor may be useful if: - there is a new beatyful feature in newer version of compiler but you still want to have backward compatibility. - there are compiler or platform dependant elements. For example if you write a driver in Haskell you may want to share code as much as possible but you need to know 1) the size of registers and 2) the platform you're writing as Windows have quite different API then Linux or BSD. - You need to enable/disable features at build-time. It is not frequent at closed-source system but it is frequent on OpenSource systems. For example I might need to have minimal program for embedded system but with full feature set it likly conquer the desktops in such cases it is easier/more efficient to just write #if (defined WINDOWS && BITS >= 64) || defined ALSA ... #elseif GHC_VERSION >= 061004 #endif Regards From uzytkownik2 at gmail.com Thu Jan 7 08:21:18 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Thu Jan 7 08:00:20 2010 Subject: [Haskell-cafe] Re: Re: Review request for my permutations implementation In-Reply-To: <201001071412.34598.daniel.is.fischer@web.de> References: <121533.40261.qm@web112506.mail.gq1.yahoo.com> <1262869460.6326.102.camel@picard> <201001071412.34598.daniel.is.fischer@web.de> Message-ID: <1262870478.6326.119.camel@picard> On Thu, 2010-01-07 at 14:12 +0100, Daniel Fischer wrote: > Am Donnerstag 07 Januar 2010 14:04:20 schrieb Maciej Piechotka: > > > > > > As pointed out perms [] = [[]]. You can note that: > > > length . perms == factorial > > Surely you meant > > genericLength . perms == factorial . (genericLength :: [a] -> Integer) > Ups. Sorry. About genericLength - I can use length as it is postcondition not in haskell (please note that ?Eq ([a] -> Integer) ;)) Regards From mightybyte at gmail.com Thu Jan 7 09:55:55 2010 From: mightybyte at gmail.com (MightyByte) Date: Thu Jan 7 09:28:49 2010 Subject: [Haskell-cafe] looking for origin of quote on preprocessors and language design In-Reply-To: <4B45D443.8020709@imn.htwk-leipzig.de> References: <4B45D443.8020709@imn.htwk-leipzig.de> Message-ID: It strikes me that this question may be related (perhaps distantly) to Godel's incompleteness theorem. Anyone else see similarities here? On Thu, Jan 7, 2010 at 7:32 AM, Johannes Waldmann wrote: > Dear all, > > It's not exactly Haskell-specific, but ... > I am trying to track down the origin of the proverb > > "the existence (or: need for) a preprocessor > shows omissions in (the design of) a language." > > > I like to think that in Haskell, we don't need > preprocessors since we can manipulate programs > programmatically, because they are data. > > In other words, a preprocessor realizes higher order > functions, and you only need this if your base language > is first-order. > > Yes, that's vastly simplified, and it does not cover > all cases, what about generic programming > (but this can be done via Data.Data) > and alex/happy (but we have parsec) etc etc. > > Best regards, J.W. > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From v.dijk.bas at gmail.com Thu Jan 7 10:00:31 2010 From: v.dijk.bas at gmail.com (Bas van Dijk) Date: Thu Jan 7 09:33:44 2010 Subject: [Haskell-cafe] ANNOUNCE: New versions of ALL the monadic regions packages Message-ID: Hello, As I explained in my announcement of 'safer-file-handles', I discovered a serious lack of expressive power in my 'regions' package. I have now solved that problem in the way I envisaged by removing the 'resource' parameter from 'RegionT' and using existential quantification to bring the 'resource' type back at the place I need it but hidden from the outside. Now you're able to open multiple types of resources in a single region which all will be closed automatically on termination of the region. These are the new releases: http://hackage.haskell.org/package/regions-0.2 http://hackage.haskell.org/package/regions-monadsfd-0.2 http://hackage.haskell.org/package/regions-monadstf-0.2.0.1 http://hackage.haskell.org/package/usb-safe-0.5 http://hackage.haskell.org/package/safer-file-handles-0.2 (Note that in the process I shuffled a bit with the API's. That's one of the reasons all these are major releases.) Do you want to see this in action? See 'example.hs' in the following package that demonstrates opening multiple different types of resources in a single region. The example extends the example in the 'usb-safe-examples' package by first opening a USB device (my USB mouse) and a temporary file in the same region. Next the device is configured, an interface is claimed and an alternate is set. Next some bytes are read from an endpoint of the device. Finally these bytes are written to the temporary file. It's fun to see this in action so do try it out: darcs get http://code.haskell.org/~basvandijk/code/usb-safe-and-safer-file-handles-examples/ regards and see some of you at FP-NL tomorrow! Bas From v.dijk.bas at gmail.com Thu Jan 7 10:25:34 2010 From: v.dijk.bas at gmail.com (Bas van Dijk) Date: Thu Jan 7 09:58:46 2010 Subject: [Haskell-cafe] Re: ANNOUNCE: New versions of ALL the monadic regions packages In-Reply-To: References: Message-ID: BTW As can be seen from the documentation of 'safer-file-handles', I'm currently not satisfied at all about my implementation of the standard files (stdin, stdout and stderr). To quote the docs: BIG WARNING: I'm not satisfied with my current implementation of the standard handles (stdin, stdout and stderr)! Currently the standard handles are regional computations that return the regional file handles to the respected standard handles. There are 4 problems with this approach: * When the region terminates in which you call one of the standard handles the respected handle will be closed. I think this is not the expected behaviour. I would expect the standard handles to always remain open. * In System.IO the standard handles are pure values. My standard handles are monadic computations which makes them harder to work with. * There is no way to explicitly close a standard handle. Indeed, the whole purpose of lightweight monadic regions is to automatically close handles. However, when writing a Unix daemon for example, you need to be able to explicitly close the standard handles. * When reading 'man stdin' I'm confused if the standard handles are always open on program startup: quote 'man stdin': "...Under normal circumstances every Unix program has three streams opened for it when it starts up, one for input, one for output, and one for printing diagnostic or error messages..." "...The stdin, stdout, and stderr macros conform to C89 and this standard also stipulates that these three streams shall be open at program startup...." So now I'm confused... are these standard file handles always open on program startup or are there abnormal situations when they are closed? Maybe I just have to believe the documentation in System.IO which specifies that they are always initially open. If the standard handles are closed on startup using a handle returned from one of the standard handles will result in an exception! This would be a violation of my safety guarantees which is unacceptable. Does anyone have a solution or an rough idea how to solve it? Thanks, Bas From daniel.is.fischer at web.de Thu Jan 7 11:13:38 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Thu Jan 7 10:48:11 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: Message-ID: <201001071713.39165.daniel.is.fischer@web.de> Am Donnerstag 07 Januar 2010 11:43:44 schrieb Heinrich Apfelmus: > Will Ness wrote: > > Heinrich Apfelmus writes: > >> Concerning lists as producer/consumer, I think that's exactly what lazy > >> evaluation is doing. Neither filter , map or span evaluate and > >> store more list elements that strictly necessary. > > > > I laways suspected as much, but was once told that Chris Okasaki has > > shown that any filter etc must allocate its own storage. With the > > peek/pull they don't have to, if they are nested, and the deepest one > > from the real storage gets pulled through some pointer chasing > > eventually. Span isn't so easily compiled out too or is it? But that > > might be a minor point. > > Hm? In my world view, there is only reduction to normal form and I don't > see how "allocate its own storage" fits in there. Okasaki having shown > something to that end would be new to me? > Perhaps what was meant was "storage must be allocated for each filter" (which, however, seems trivial). > > > > We can directy jump to the next multiple too, it is called (+). :) :) > > > > But seriously, the real issue is that we have to merge the produced > > streams of multiples, while the mutable-storage code works on same one, > > so its "merging cost" is zero. And even if we are smart to merge them in > > a tree-like fashion, we still have no (or little) control over the > > compiler's representation of lists and retention of their content and > > whether it performs stream fusion or not (if we use lists). > > Not quite, I think there are two things going on: > > 1. In contrast to the standard imperative version, we are implementing > an on-line algorithm that produces arbitrarily many primes on demand. > Any imperative on-line version will need to think about storage for > pending prime filters as well. If you consider a segmented array sieve an on-line algorithm, at the expense of speed, you can omit storage for prime filters. It will not be a real Eratosthenes sieve anymore, but it won't be too horribly slow, I think. If you're using an Atkin sieve, the performance penalty should be even lower. > > 2. Even the imperative algorithm can be interpreted as "merging" arrays, > just that the composites are magically merged at the right place (at And they're merged asynchronously. Yet more magic :) > distance p from each other) because arrays offer O(1) "jumps". In > contrast, the functional version needs O(log something) time to > calculate where to put the next composite. > > > If you could take a look at the tree-merging primes and why it uses too > > much memory, it would be great. > > Fortunately, Daniel already took a detailed look. :) But I also have a > few remarks. > > > The code is in Daniel's post to which I replied, or > > on haskellwiki Prime_numbers page (there in its rudimentary form). It's a > > tangent to your VIP code, where instead of People structure an ordered > > list is just maintained as a split pair, of its known (so far, finite) > > prefix and the rest of it. > > Aww, why remove the cutesy name? The VIPs will be angry for being ignored! You'll be happy to learn that they return, albeit in a different form, then :) > > Jest aside, note that putting the crowd at the end of the list where it > belongs has a reason: you have a guarantee that crowds won't take any > memory until they actually appear after all the VIPs. If you put both > VIPs and the crowd into a pair, it's easier to get space leaks. > Indeed. It's the combination of pairs and the bushy merge trees that lets the memory explode. I still don't completely understand the behaviour, but I managed to squash the space leak :D (see below). Thanks for the idea. > In particular, I think that your mergeSP has a laziness bug, it should be > > mergeSP ~(a,b) ~(c,d) = ... > That doesn't help. The pattern match on the first argument doesn't hurt. > This is a cure for the (potential) problem that spMerge first performs > a pattern match / comparison and then returns a pair constructor instead > of the other way round. For instance, your second case > > spMerge u [] = ([], u) > > should actually behave like > > spMerge u v = (a,b) > where > a = if null v then [] else ... > b = if null v then u else ... > > (I don't recommend rewriting spMerge in this fashion, the lazy pattern > in mergeSP will do the trick.) It didn't. Probably rewriting spMerge thus would do, but I think I'm too lazy to find out. > > Now, I'm not sure whether this is actually a problem or not. But the > version shown here, with two lazy patterns instead of just one, is much > closer to how the original People structure behaves. > > > Then under merging these split pairs form a monoid, s can be rearranged > > in a tree. If you haven't seen it yet, it uses a different folding > > structure to your code, with a lower total cost of multiples production > > (estimated as Sum (1/p)*depth): > > > > tfold f (x:y:z:xs) = (x `f` (y `f` z)) `f` pairwise f xs > > comps = tfold $ pairwise mergeSP multips > > The idea being that each prime produces 1/p composites each "turn" and > it takes time depth to trickle it to the top? Sounds reasonable, but > remember that a prime p does not start to generate composites until > the "turn count" has reached p^2, so it might occupy a place of low > depth in the tree that is better spent on the previous primes. But your > experiments seem to tell that it works anyway. > > > By the way, I think that both tfold and pairwise need to be lazier. > > tfold f ~(x: ~(y: ~(z:zs))) = (x `f` (y `f` z)) `f` pairwise f zs > > pairwise f ~(x: ~(y:ys)) = f x y : pairwise f ys > > Otherwise, large parts of the tree might be generated too early and hog > memory. > As it turns out, I don't know why, it's the other way round. Each lazy pattern increases memory usage. Not very intuitive. > > Also, a small remark on style: I don't like the repetition of mergeSP in > > compos = fst $ tfold mergeSP (pairwise mergeSP (multip ps)) Noted and acted upon. > > After all, the right hand side is just another tree fold and I would > clearly mark it as such: > > compos = fst . superSmartTreeFold mergeSP . multip $ ps > > superSmartTreeFold f = tfold f . pairwise f > > ;) > > > I think I'll have to try out your code (amended with a new folding > > structure) and see if it has less memory problems maybe. > I assume it is > > your code on the haskellwiki page. (?) > > Yes, I put the code snippet on the wiki. And never tested it on large > numbers. ;) > > > Regards, > Heinrich Apfelmus The below code is now a well-behaved memory citizen (3MB for the 100 millionth prime, about the same as the PQ code). It still is considerably slower than the PQ code. In terms of MUT times as reported by +RTS -sstderr - as well as (MUT+GC) times - (measured once for prime No. 5*10^5, 10^6, 2*10^6, 4*10^6, 10^7 to get a rough tendency), it seems to scale a wee bit better than any of the other tfold versions I created, but a little worse than the PQ versions. The relation of MUT times isn't too bad, but the GC times are rather abysmal (30-40%). ---------------------------------------------------------------------- {-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS_GHC -O2 -fno-cse #-} module VippyPrimes (primes) where data People a = P { vips :: [a], dorks :: [a] } {-# SPECIALISE celebrate :: Int -> People Int -> People Int #-} {-# SPECIALISE celebrate :: Integer -> People Integer -> People Integer #-} celebrate :: a -> People a -> People a celebrate x p = P (x:vips p) (dorks p) {-# SPECIALISE primes :: () -> [Int] #-} {-# SPECIALISE primes :: () -> [Integer] #-} primes :: forall a. Integral a => () -> [a] primes () = 2:3:5:7:11:13:primes' ?? where ??? primes' = roll 17 wheel13 `minus` compos primes''' primes'' = 17:19:23:29:31:37:rollFrom 41 `minus` compos primes'' primes''' = 17:19:23:29:31:37:rollFrom 41 `minus` compos primes'' pmults :: a -> People a pmults p = case map (*p) (rollFrom p) of (x:xs) -> P [x] xs multip :: [a] -> [People a] multip ps = map pmults ps compos :: [a] -> [a] compos = vips . itfold mergeSP . multip rollFrom n = go ((n-17) `rem` 30030) wheel13 where go r xxs@(x:xs) | r < x = roll n xxs | otherwise = go (r-x) xs smartfold f = tfold f . pairwise f tfold f (a:b:c:xs) = (a `f` (b `f` c)) `f` smartfold f xs pairwise f (x:y:ys)? = f x y : pairwise f ys {-# SPECIALISE mergeSP :: People Int -> People Int -> People Int #-} {-# SPECIALISE mergeSP :: People Integer -> People Integer -> People Integer #-} mergeSP :: Integral a => People a -> People a -> People a mergeSP p1@(P a _) p2 = P (a ++ vips mrgd) (dorks mrgd) where mrgd = spMerge (dorks p1) (vips p2) (dorks p2) spMerge l1 [] l3 = P [] (merge l1 l3) spMerge ~l1@(x:xs) l2@(y:ys) l3 = case compare x y of LT -> celebrate x (spMerge xs l2 l3) EQ -> celebrate x (spMerge xs ys l3) GT -> celebrate y (spMerge l1 ys l3) -- do the sepcialisations below make a difference at all? {-# SPECIALISE roll :: Int -> [Int] -> [Int] #-} {-# SPECIALISE roll :: Integer -> [Integer] -> [Integer] #-} roll :: Integral a => a -> [a] -> [a] roll?????? = scanl (+) {-# SPECIALISE wheel :: [Int] #-} {-# SPECIALISE wheel :: [Integer] #-} wheel :: Integral a => [a] wheel????? = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: ?????????? 4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel {-# SPECIALISE wheel11 :: [Int] #-} {-# SPECIALISE wheel11 :: [Integer] #-} wheel11 :: Integral a => [a] wheel11 = res where snms = scanl (+) 11 (take 47 wheel) nums = tail $ scanl (+) 11 (take 529 wheel) cops = nums `minus` map (*11) snms diffs = zipWith (-) (tail cops) cops res = foldr (:) res diffs {-# SPECIALISE wheel13 :: [Int] #-} {-# SPECIALISE wheel13 :: [Integer] #-} wheel13 :: Integral a => [a] wheel13 = res where snms = take 480 $ scanl (+) 13 wheel11 nums = take (480*13+1) . tail $ scanl (+) 13 wheel11 cops = nums `minus` map (*13) snms diffs = zipWith (-) (tail cops) cops res = foldr (:) res diffs {-# SPECIALISE minus :: [Int] -> [Int] -> [Int] #-} {-# SPECIALISE minus :: [Integer] -> [Integer] -> [Integer] #-} minus :: Integral a => [a] -> [a] -> [a] minus a@(x:xs) b@(y:ys) = case compare x y of ?????? LT -> x: xs `minus` b ?????? GT ->??? a? `minus` ys ?????? EQ ->??? xs `minus` ys minus a b? = a merge a@(x:xs) b@(y:ys) = case compare x y of ?????? LT -> x: merge xs b ?????? EQ -> x: merge xs ys ?????? GT -> y: merge a? ys merge a b? = if null b then a else b ---------------------------------------------------------------------- -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100107/f92cd9be/attachment-0001.html From felipe.lessa at gmail.com Thu Jan 7 11:15:45 2010 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Thu Jan 7 10:48:45 2010 Subject: [Haskell-cafe] ANNOUNCE: New versions of ALL the monadic regions packages In-Reply-To: References: Message-ID: <20100107161545.GA23610@kira.casa> On Thu, Jan 07, 2010 at 04:00:31PM +0100, Bas van Dijk wrote: > As I explained in my announcement of 'safer-file-handles', I > discovered a serious lack of expressive power in my 'regions' package. > I have now solved that problem in the way I envisaged by removing the > 'resource' parameter from 'RegionT' and using existential > quantification to bring the 'resource' type back at the place I need > it but hidden from the outside. But if I understand correctly, now you can't know from the type signature what kind of resource a given code accesses. Isn't this a drawback? Wouldn't it be better to write something like TopRegion (File `And` Network) to tell something needs both? Cheers! -- Felipe. From bulat.ziganshin at gmail.com Thu Jan 7 11:18:16 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Thu Jan 7 10:56:50 2010 Subject: [Haskell-cafe] Re: ANNOUNCE: New versions of ALL the monadic regions packages In-Reply-To: References: Message-ID: <1188500262.20100107191816@gmail.com> Hello Bas, Thursday, January 7, 2010, 6:25:34 PM, you wrote: > So now I'm confused... are these standard file handles always open on > program startup or are there abnormal situations when they are closed? afaik, parent process may close them before executing your program, it's used in particular for running daemons -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From miguelimo38 at yandex.ru Thu Jan 7 12:39:10 2010 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Thu Jan 7 12:12:03 2010 Subject: [Haskell-cafe] Explicit garbage collection In-Reply-To: <7BB0709F-F74E-4181-BA49-D292193DABF9@yandex.ru> References: <4B44958A.2080809@yandex.ru> <201001060906.51127.dan.doel@gmail.com> <4B44A09C.8040103@yandex.ru> <7fb8f82f1001061221v40ffe0cby8c0e4b453e72d65d@mail.gmail.com> <7fb8f82f1001061928o4a58ac46qbaaf00691f26e304@mail.gmail.com> <7fb8f82f1001062101s44d45b59v83d176d12287243@mail.gmail.com> <7BB0709F-F74E-4181-BA49-D292193DABF9@yandex.ru> Message-ID: <693475F8-3C64-4EA1-839D-C7C1ED87FB01@yandex.ru> Damn. Seems like I really need (True, False, True) as a result of "test". On 7 Jan 2010, at 08:52, Miguel Mitrofanov wrote: > Seems very nice. Thanks. > > On 7 Jan 2010, at 08:01, Edward Kmett wrote: > >> Here is a slightly nicer version using the Codensity monad of STM. >> >> Thanks go to Andrea Vezzosi for figuring out an annoying hanging >> bug I was having. >> >> -Edward Kmett >> >> {-# LANGUAGE Rank2Types, GeneralizedNewtypeDeriving, DeriveFunctor >> #-} >> module STMOracle >> ( Oracle, Ref >> , newRef, readRef, writeRef, modifyRef, needRef >> ) where >> >> import Control.Applicative >> import Control.Monad >> import Control.Concurrent.STM >> >> instance Applicative STM where >> pure = return >> (<*>) = ap >> >> newtype Ref s a = Ref (TVar (Maybe a)) >> newtype Oracle s a = Oracle { unOracle :: forall r. (a -> STM r) -> >> STM r } deriving (Functor) >> >> instance Monad (Oracle s) where >> return x = Oracle (\k -> k x) >> Oracle m >>= f = Oracle (\k -> m (\a -> unOracle (f a) k)) >> >> mkOracle m = Oracle (m >>=) >> >> runOracle :: (forall s. Oracle s a) -> IO a >> runOracle t = atomically (unOracle t return) >> >> newRef :: a -> Oracle s (Ref s a) >> newRef a = mkOracle $ Ref <$> newTVar (Just a) >> >> readRef :: Ref s a -> Oracle s a >> readRef (Ref r) = mkOracle $ do >> m <- readTVar r >> maybe retry return m >> >> writeRef :: a -> Ref s a -> Oracle s a >> writeRef a (Ref r) = mkOracle $ do >> writeTVar r (Just a) >> return a >> >> modifyRef :: (a -> a) -> Ref s a -> Oracle s a >> modifyRef f r = do >> a <- readRef r >> writeRef (f a) r >> >> needRef :: Ref s a -> Oracle s Bool >> needRef (Ref slot) = Oracle $ \k -> >> (writeTVar slot Nothing >> k False) >> `orElse` k True >> >> -- test >> case >> : refMaybe >> b dflt ref = if b then readRef ref else return dflt >> refIgnore ref = return "blablabla" >> refFst ref = fst `fmap` readRef ref >> test = do >> a <- newRef "x" >> b <- newRef 1 >> c <- newRef ('z', Just 0) >> -- no performLocalGC required >> x <- needRef a >> y <- needRef b >> z <- needRef c >> u <- refMaybe y "t" a -- note that it wouldn't actually read "a", >> -- but it won't be known until runtime. >> w <- refIgnore b >> v <- refFst c >> return (x, y, z) >> >> >> >> On Wed, Jan 6, 2010 at 10:28 PM, Edward Kmett >> wrote: >> I don't believe you can get quite the semantics you want. However, >> you can get reasonably close, by building a manual store and >> backtracking. >> >> {-# LANGUAGE Rank2Types #-} >> -- lets define an Oracle that tracks whether or not you might need >> the reference, by backtracking. >> module Oracle >> ( Oracle, Ref >> , newRef, readRef, writeRef, modifyRef, needRef >> ) where >> >> import Control.Applicative >> import Control.Arrow (first) >> import Control.Monad >> import Data.IntMap (IntMap) >> import qualified Data.IntMap as M >> import Unsafe.Coerce (unsafeCoerce) >> import GHC.Prim (Any) >> >> -- we need to track our own worlds, otherwise we'd have to build >> over ST, change optimistically, and track how to backtrack the >> state of the Store. Much uglier. >> -- values are stored as 'Any's for safety, see GHC.Prim for a >> discussion on the hazards of risking the storage of function types >> using unsafeCoerce as anything else. >> data World s = World { store :: !(IntMap Any), hwm :: !Int } >> >> -- references into our store >> newtype Ref s a = Ref Int deriving (Eq) >> >> -- our monad that can 'see the future' ~ StateT (World s) []newtype >> Oracle s a = Oracle { unOracle :: World s -> [(a, World s)] } >> >> -- we rely on the fact that the list is always non-empty for any >> oracle you can run. we are only allowed to backtrack if we thought >> we wouldn't need the reference, and wound up needing it, so head >> will always succeed. >> runOracle :: (forall s. Oracle s a) -> a >> runOracle f = fst $ head $ unOracle f $ World M.empty 1 >> >> >> instance Monad (Oracle s) where >> return a = Oracle $ \w -> [(a,w)] >> Oracle m >>= k = Oracle $ \s -> do >> (a,s') <- m s >> unOracle (k a) s' >> >> -- note: you cannot safely define fail here without risking a crash >> in runOracle >> -- Similarly, we're not a MonadPlus instance because we always want >> to succeed eventually. >> >> instance Functor (Oracle s) where >> fmap f (Oracle g) = Oracle $ \w -> first f <$> g w >> >> instance Applicative (Oracle s) where >> pure = return >> (<*>) = ap >> >> -- new ref allocates a fresh slot and inserts the value into the >> store. the type level brand 's' keeps us safe, and we don't export >> the Ref constructor. >> newRef :: a -> Oracle s (Ref s a) >> newRef a = Oracle $ \(World w t) -> >> [(Ref t, World (M.insert t (unsafeCoerce a) w) (t + 1))] >> >> -- readRef is the only thing that ever backtracks, if we try to >> read a reference we claimed we wouldn't need, then we backtrack to >> when we decided we didn't need the reference, and continue with its >> value. >> readRef :: Ref s a -> Oracle s a >> readRef (Ref slot) = Oracle $ \world -> >> maybe [] (\a -> [(unsafeCoerce a, world)]) $ M.lookup slot >> (store world) >> >> -- note, writeRef dfoesn't 'need' the ref's current value, so >> needRef will report False if you writeRef before you read it after >> this. >> writeRef :: a -> Ref s a -> Oracle s a >> writeRef a (Ref slot) = Oracle $ \world -> >> [(a, world { store = M.insert slot (unsafeCoerce a) $ store >> world })] >> >> {- >> -- alternate writeRef where writing 'needs' the ref. >> writeRef :: a -> Ref s a -> Oracle s a >> writeRef a (Ref slot) = Oracle $ \World store v -> do >> (Just _, store') <- return $ updateLookupWithKey replace slot >> store >> [(a, World store' v)] >> where >> replace _ _ = Just (unsafeCoerce a) >> -} >> >> -- modifying a reference of course needs its current value. >> modifyRef :: (a -> a) -> Ref s a -> Oracle s a >> modifyRef f r = do >> a <- readRef r >> writeRef (f a) r >> >> -- needRef tries to continue executing the world without the >> element in the store in question. if that fails, then we'll >> backtrack to here, and try again with the original world, and >> report that the element was in fact needed. >> needRef :: Ref s a -> Oracle s Bool >> needRef (Ref slot) = Oracle $ \world -> >> [ (False, world { store = M.delete slot $ store world }) >> , (True, world) >> ] >> >> -- test case: >> refMaybe b dflt ref = if b then readRef ref else return dflt >> refIgnore ref = return "blablabla" >> refFst ref = fst <$> readRef ref >> test = do >> a <- newRef "x" >> b <- newRef 1 >> c <- newRef ('z', Just 0) >> -- no performLocalGC required >> x <- needRef a >> y <- needRef b >> z <- needRef c >> u <- refMaybe y "t" a -- note that it wouldn't actually read "a", >> -- but it won't be known until runtime. >> w <- refIgnore b >> v <- refFst c >> return (x, y, z) >> >> -- This will disagree with your desired answer, returning: >> >> *Oracle> runOracle test >> Loading package syb ... linking ... done. >> Loading package array-0.2.0.0 ... linking ... done. >> Loading package containers-0.2.0.1 ... linking ... done. >> (False,False,True) >> >> rather than (True, False, True), because the oracle is able to see >> into the future (via backtracking) to see that refMaybe doesn't use >> the reference after all. >> >> This probably won't suit your needs, but it was a fun little >> exercise. >> >> -Edward Kmett >> >> On Wed, Jan 6, 2010 at 4:05 PM, Miguel Mitrofanov > > wrote: >> >> On 6 Jan 2010, at 23:21, Edward Kmett wrote: >> >> You probably just want to hold onto weak references for your >> 'isStillNeeded' checks. >> >> That's what I do now. But I want to minimize the network traffic, >> so I want referenced values to be garbage collected as soon as >> possible - and I couldn't find anything except System.Mem.performIO >> to do the job - which is a bit too global for me. >> >> Otherwise the isStillNeeded check itself will keep you from garbage >> collecting! >> >> Not necessary. What I'm imagining is that there is essentially only >> one way to access the value stored in the reference - with readRef. >> So, if there isn't any chance that readRef would be called, the >> value can be garbage collected; "isStillNeeded" function only needs >> the reference, not the value. >> >> Well, yeah, that's kinda like weak references. >> >> >> http://cvs.haskell.org/Hugs/pages/libraries/base/System-Mem-Weak.html >> >> -Edward Kmett >> >> On Wed, Jan 6, 2010 at 9:39 AM, Miguel Mitrofanov > > wrote: >> I'll take a look at them. >> >> I want something like this: >> >> refMaybe b dflt ref = if b then readRef ref else return dflt >> refIgnore ref = return "blablabla" >> refFst ref = >> do >> (v, w) <- readRef ref >> return v >> test = >> do >> a <- newRef "x" >> b <- newRef 1 >> c <- newRef ('z', Just 0) >> performLocalGC -- if necessary >> x <- isStillNeeded a >> y <- isStillNeeded b >> z <- isStillNeeded c >> u <- refMaybe y "t" a -- note that it wouldn't actually read "a", >> -- but it won't be known until runtime. >> w <- refIgnore b >> v <- refFst c >> return (x, y, z) >> >> so that "run test" returns (True, False, True). >> >> >> Dan Doel wrote: >> On Wednesday 06 January 2010 8:52:10 am Miguel Mitrofanov wrote: >> Is there any kind of "ST" monad that allows to know if some STRef >> is no >> longer needed? >> >> The problem is, I want to send some data to an external storage >> over a >> network and get it back later, but I don't want to send unnecessary >> data. >> >> I've managed to do something like that with weak pointers, >> System.Mem.performGC and unsafePerformIO, but it seems to me that >> invoking >> GC every time is an overkill. >> >> Oh, and I'm ready to trade the purity of runST for that, if >> necessary. >> >> You may be able to use something like Oleg's Lightweight Monadic >> Regions to get this effect. I suppose it depends somewhat on what >> qualifies a reference as "no longer needed". >> >> http://www.cs.rutgers.edu/~ccshan/capability/region-io.pdf >> >> I'm not aware of anything out-of-the-box that does what you want, >> though. >> >> -- Dan >> _______________________________________________ >> 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 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 mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From rodrigo.bonifacio at uol.com.br Thu Jan 7 13:35:10 2010 From: rodrigo.bonifacio at uol.com.br (rodrigo.bonifacio) Date: Thu Jan 7 13:08:10 2010 Subject: [Haskell-cafe] Distinct types in a list Message-ID: <4b46295e5d934_5fe0edfa670234@weasel13.tmail> Hi all, I have a family of parsers that return either (Success t) or (Fail), using the following data type: > data ParserResult a = Success a | Fail String > deriving (Read, Show, Eq, Ord) > > isSuccess (Success _) = True > isSuccess (Fail _) = False > ... I want to add the results of different parsers to a list. Such as: > m1 = parseFirstModel file1 -- it returns a ParserResult of t1 > m2 = parseSecondModel file2 -- it returns a ParserResult of t2 > ps = [m1, m2] In such a way that I could write something like: > if and (map isSuccess ps) > then process m1 m2 > else ... Actually, in the real program I have to check more than two input models. However, since Lists do only hold elements of a same type, I couldn't proceed in this way. Which improvements to the ParserResult data type should I wrote in order to proceed as I want to. Best regards, Rodrigo. ? From ozgurakgun at gmail.com Thu Jan 7 13:44:41 2010 From: ozgurakgun at gmail.com (Ozgur Akgun) Date: Thu Jan 7 13:17:34 2010 Subject: [Haskell-cafe] Distinct types in a list In-Reply-To: <4b46295e5d934_5fe0edfa670234@weasel13.tmail> References: <4b46295e5d934_5fe0edfa670234@weasel13.tmail> Message-ID: <7be1feae1001071044r266782eeu6b5de64b40877cac@mail.gmail.com> If I understand you correctly, what you want is very similar to catMaybes isSuccess' (Success a) = Just a isSuccess' _ = Nothing result = catMaybes $ map isSuccess ps This should do the trick. 2010/1/7 rodrigo.bonifacio > Hi all, > > I have a family of parsers that return either (Success t) or (Fail), using > the following data type: > > > data ParserResult a = Success a | Fail String > > deriving (Read, Show, Eq, Ord) > > > > isSuccess (Success _) = True > > isSuccess (Fail _) = False > > ... > > I want to add the results of different parsers to a list. Such as: > > > m1 = parseFirstModel file1 -- it returns a ParserResult of t1 > > m2 = parseSecondModel file2 -- it returns a ParserResult of t2 > > > ps = [m1, m2] > > In such a way that I could write something like: > > > if and (map isSuccess ps) > > then process m1 m2 > > else ... > > Actually, in the real program I have to check more than two input models. > However, since Lists do only hold elements of a same type, I couldn't > proceed in this way. Which improvements to the ParserResult data type should > I wrote in order to proceed as I want to. > > Best regards, > > Rodrigo. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- Ozgur Akgun -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100107/f27d6a17/attachment.html From alexey.skladnoy at gmail.com Thu Jan 7 13:56:22 2010 From: alexey.skladnoy at gmail.com (Khudyakov Alexey) Date: Thu Jan 7 13:28:52 2010 Subject: [Haskell-cafe] Distinct types in a list In-Reply-To: <4b46295e5d934_5fe0edfa670234@weasel13.tmail> References: <4b46295e5d934_5fe0edfa670234@weasel13.tmail> Message-ID: <201001072156.22736.alexey.skladnoy@gmail.com> ? ????????? ?? ??????? 07 ?????? 2010 21:35:10 rodrigo.bonifacio ???????: > Hi all, > > I have a family of parsers that return either (Success t) or (Fail), using the following data type: > > data ParserResult a = Success a | Fail String > > deriving (Read, Show, Eq, Ord) > > > > isSuccess (Success _) = True > > isSuccess (Fail _) = False > > ... > > I want to add the results of different parsers to a list. Such as: > > m1 = parseFirstModel file1 -- it returns a ParserResult of t1 > > m2 = parseSecondModel file2 -- it returns a ParserResult of t2 > > > > ps = [m1, m2] > > In such a way that I could write something like: > > if and (map isSuccess ps) > > then process m1 m2 > > else ... > > Actually, in the real program I have to check more than two input models. > However, since Lists do only hold elements of a same type, I couldn't > proceed in this way. Which improvements to the ParserResult data type > should I wrote in order to proceed as I want to. > In short there is no easy way to this lists. But you can make ParserResult instance of Monad and/or Applicative. It's is error monad in fact. You can check Control.Monad.Error to see Monad instance for (Either String) With this you can write you program in applicative notation Here computation will stop after first error. > m1 = parseFirstModel file1 -- it returns a ParserResult of t1 > m2 = parseSecondModel file2 -- it returns a ParserResult of t2 > > case process <$> m1 <*> m2 of > (Success x) -> ... > (Fail x) -> ... Or use do notation with similar results > res = do > m1 <- parseFirstModel file1 > m2 <- parseSecondModel file2 > return $ process m1 m2 > > foo = case res of > (Success x) -> ... > (Fail err) -> ... P.S. I didn't run code but I think it should work if required instances are defined From Christian.Maeder at dfki.de Thu Jan 7 14:02:15 2010 From: Christian.Maeder at dfki.de (Christian Maeder) Date: Thu Jan 7 13:35:08 2010 Subject: [Haskell-cafe] Re: Distinct types in a list In-Reply-To: <4b46295e5d934_5fe0edfa670234@weasel13.tmail> References: <4b46295e5d934_5fe0edfa670234@weasel13.tmail> Message-ID: <4B462FB7.1020303@dfki.de> You could cast your parser result "a" to Dynamic using Data.Dynamic.toDyn (and derive Typeable instances for all involved types). http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Data-Dynamic.html Using an existential types may be another alternative. Cheers Christian rodrigo.bonifacio schrieb: > Hi all, > > I have a family of parsers that return either (Success t) or (Fail), using the following data type: > >> data ParserResult a = Success a | Fail String >> deriving (Read, Show, Eq, Ord) >> >> isSuccess (Success _) = True >> isSuccess (Fail _) = False >> ... > > I want to add the results of different parsers to a list. Such as: > >> m1 = parseFirstModel file1 -- it returns a ParserResult of t1 >> m2 = parseSecondModel file2 -- it returns a ParserResult of t2 > >> ps = [m1, m2] > > In such a way that I could write something like: > >> if and (map isSuccess ps) >> then process m1 m2 >> else ... > > Actually, in the real program I have to check more than two input models. However, since Lists do only hold elements of a same type, I couldn't proceed in this way. Which improvements to the ParserResult data type should I wrote in order to proceed as I want to. > > Best regards, > > Rodrigo. > From daniel.is.fischer at web.de Thu Jan 7 14:25:56 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Thu Jan 7 14:00:26 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: <201001071713.39165.daniel.is.fischer@web.de> References: <201001071713.39165.daniel.is.fischer@web.de> Message-ID: <201001072025.56716.daniel.is.fischer@web.de> Am Donnerstag 07 Januar 2010 17:13:38 schrieb Daniel Fischer: > ? ? compos :: [a] -> [a] > ? ? compos = vips . itfold mergeSP . multip Sigh! That's what I get for editing the code in the mail editor. I decided to change the really stupid 'itfold' to 'smartfold' and forgot this occurrence. From dalej at alum.mit.edu Thu Jan 7 14:35:32 2010 From: dalej at alum.mit.edu (Dale Jordan) Date: Thu Jan 7 14:08:51 2010 Subject: [Haskell-cafe] Re: Why doesn't laziness save the day here? In-Reply-To: <20100105121736.92293173C9@Adric.ern.nps.edu> References: <20100105121736.92293173C9@Adric.ern.nps.edu> Message-ID: <4B463784.9040106@alum.mit.edu> oleg@okmij.org wrote: > > The others have already pointed out the problem with the imperative > solution, which used the mutation of the global state with the new > random seed. Imperative approach is indeed often a problem. > As Daniel Fischer pointed out, my immediate problem was that iterateR never finished, even though it did produce results lazily. I missed the subtlety that access to results didn't mean access to the state. > There is a simple solution however. [Snipped ASCII art of head exploding...] > module RList where > [Nice code snipped] So, if I may paraphrase, oleg's solution works by reifying the implicit continuation in my iterateR's recursive definition into a data structure that is explicitly forced with pullR and its callers. Fascinating... Thanks to all who responded. Dale From v.dijk.bas at gmail.com Thu Jan 7 14:39:59 2010 From: v.dijk.bas at gmail.com (Bas van Dijk) Date: Thu Jan 7 14:13:10 2010 Subject: [Haskell-cafe] ANNOUNCE: New versions of ALL the monadic regions packages In-Reply-To: <20100107161545.GA23610@kira.casa> References: <20100107161545.GA23610@kira.casa> Message-ID: On Thu, Jan 7, 2010 at 5:15 PM, Felipe Lessa wrote: > On Thu, Jan 07, 2010 at 04:00:31PM +0100, Bas van Dijk wrote: >> As I explained in my announcement of 'safer-file-handles', I >> discovered a serious lack of expressive power in my 'regions' package. >> I have now solved that problem in the way I envisaged by removing the >> 'resource' parameter from 'RegionT' and using existential >> quantification to bring the 'resource' type back at the place I need >> it but hidden from the outside. > > But if I understand correctly, now you can't know from the type > signature what kind of resource a given code accesses. ?Isn't > this a drawback? ?Wouldn't it be better to write something like > > ?TopRegion (File `And` Network) > > to tell something needs both? Oh yes, very good point! Lets think, I could parameterize RegionT by some sort of heterogeneous list (HList) that encodes all the resources that the region opens. However won't this introduce my previous problem again? Another solution might be to encode the resources that a region opens as constraints. I think 'control-monad-exception' uses a similar technique to encode all the exceptions that a monadic computation may throw. My previous program could then possibly be written as something like: openBoth ? ( resources `Contains` Device , resources `Contains` File ) ? Device ? FilePath ? RegionT resources pr () openBoth usbDevice filePath = do h1 ? open usbDevice h2 ? openFile filePath ReadMode return () Thanks for bringing up this point! Bas [1] http://hackage.haskell.org/package/control-monad-exception From mail at joachim-breitner.de Thu Jan 7 14:42:34 2010 From: mail at joachim-breitner.de (Joachim Breitner) Date: Thu Jan 7 14:15:30 2010 Subject: [Haskell-cafe] pcre-light install fails with undefined reference to _impure_ptr In-Reply-To: <5fdc56d70912270150h5adb859ev879b887ca548930c@mail.gmail.com> References: <4B36E486.3050102@pessce.net> <5fdc56d70912270123j3983fb3ey7a29bbd4fb78fcf7@mail.gmail.com> <5fdc56d70912270150h5adb859ev879b887ca548930c@mail.gmail.com> Message-ID: <1262893354.3269.4.camel@localhost> Hi, Am Sonntag, den 27.12.2009, 09:50 +0000 schrieb Stephen Tetley: > > I'll try next with MinGW to see if that works... > > Aye, it builds fine under MinGW. > > I built and installed PCRE (c & c++ library) from the source > (./configure, make, make install), though I think there is a package > available on the msys / MinGW repository. I got it to work using the package from the msys repository, but I had to remove "-viaC" from the cabal file. Greetings, Joachim -- Joachim "nomeata" Breitner mail: mail@joachim-breitner.de | ICQ# 74513189 | GPG-Key: 4743206C JID: nomeata@joachim-breitner.de | http://www.joachim-breitner.de/ Debian Developer: nomeata@debian.org -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: Dies ist ein digital signierter Nachrichtenteil Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100107/055877d7/attachment.bin From v.dijk.bas at gmail.com Thu Jan 7 14:44:37 2010 From: v.dijk.bas at gmail.com (Bas van Dijk) Date: Thu Jan 7 14:17:48 2010 Subject: [Haskell-cafe] Re: ANNOUNCE: New versions of ALL the monadic regions packages In-Reply-To: <1188500262.20100107191816@gmail.com> References: <1188500262.20100107191816@gmail.com> Message-ID: On Thu, Jan 7, 2010 at 5:18 PM, Bulat Ziganshin wrote: > Hello Bas, > > Thursday, January 7, 2010, 6:25:34 PM, you wrote: > >> So now I'm confused... are these standard file handles always open on >> program startup or are there abnormal situations when they are closed? > > afaik, parent process may close them before executing your program, > it's used in particular for running daemons Thanks Bulat for explaining. Then I think the standard handles should have a type that at least encodes that they may be closed as in: stdin ? MonadCatchIO pr ? RegionT s pr (Maybe (RegionalFileHandle R (RegionT s pr))) where Nothing means that the standard handle is closed. However this still leaves open problem 1, 2 and 3. Thanks, Bas From ekmett at gmail.com Thu Jan 7 15:07:50 2010 From: ekmett at gmail.com (Edward Kmett) Date: Thu Jan 7 14:40:44 2010 Subject: [Haskell-cafe] Explicit garbage collection In-Reply-To: <693475F8-3C64-4EA1-839D-C7C1ED87FB01@yandex.ru> References: <4B44958A.2080809@yandex.ru> <201001060906.51127.dan.doel@gmail.com> <4B44A09C.8040103@yandex.ru> <7fb8f82f1001061221v40ffe0cby8c0e4b453e72d65d@mail.gmail.com> <7fb8f82f1001061928o4a58ac46qbaaf00691f26e304@mail.gmail.com> <7fb8f82f1001062101s44d45b59v83d176d12287243@mail.gmail.com> <7BB0709F-F74E-4181-BA49-D292193DABF9@yandex.ru> <693475F8-3C64-4EA1-839D-C7C1ED87FB01@yandex.ru> Message-ID: <7fb8f82f1001071207w63da732q168908d024bfaffd@mail.gmail.com> Thats a shame, I was rather fond of this monad. To get that last 'True', you'll really have to rely on garbage collection to approximate reachability for you, leaving the weak reference solution the best you can hope for. -Edward Kmett On Thu, Jan 7, 2010 at 12:39 PM, Miguel Mitrofanov wrote: > Damn. Seems like I really need (True, False, True) as a result of "test". > > > On 7 Jan 2010, at 08:52, Miguel Mitrofanov wrote: > > Seems very nice. Thanks. >> >> On 7 Jan 2010, at 08:01, Edward Kmett wrote: >> >> Here is a slightly nicer version using the Codensity monad of STM. >>> >>> Thanks go to Andrea Vezzosi for figuring out an annoying hanging bug I >>> was having. >>> >>> -Edward Kmett >>> >>> {-# LANGUAGE Rank2Types, GeneralizedNewtypeDeriving, DeriveFunctor #-} >>> module STMOracle >>> ( Oracle, Ref >>> , newRef, readRef, writeRef, modifyRef, needRef >>> ) where >>> >>> import Control.Applicative >>> import Control.Monad >>> import Control.Concurrent.STM >>> >>> instance Applicative STM where >>> pure = return >>> (<*>) = ap >>> >>> newtype Ref s a = Ref (TVar (Maybe a)) >>> newtype Oracle s a = Oracle { unOracle :: forall r. (a -> STM r) -> STM r >>> } deriving (Functor) >>> >>> instance Monad (Oracle s) where >>> return x = Oracle (\k -> k x) >>> Oracle m >>= f = Oracle (\k -> m (\a -> unOracle (f a) k)) >>> >>> mkOracle m = Oracle (m >>=) >>> >>> runOracle :: (forall s. Oracle s a) -> IO a >>> runOracle t = atomically (unOracle t return) >>> >>> newRef :: a -> Oracle s (Ref s a) >>> newRef a = mkOracle $ Ref <$> newTVar (Just a) >>> >>> readRef :: Ref s a -> Oracle s a >>> readRef (Ref r) = mkOracle $ do >>> m <- readTVar r >>> maybe retry return m >>> >>> writeRef :: a -> Ref s a -> Oracle s a >>> writeRef a (Ref r) = mkOracle $ do >>> writeTVar r (Just a) >>> return a >>> >>> modifyRef :: (a -> a) -> Ref s a -> Oracle s a >>> modifyRef f r = do >>> a <- readRef r >>> writeRef (f a) r >>> >>> needRef :: Ref s a -> Oracle s Bool >>> needRef (Ref slot) = Oracle $ \k -> >>> (writeTVar slot Nothing >> k False) >>> `orElse` k True >>> >>> -- test case: >>> refMaybe b >>> dflt ref = if b then readRef ref else return dflt >>> refIgnore ref = return "blablabla" >>> refFst ref = fst `fmap` readRef ref >>> test = do >>> a <- newRef "x" >>> b <- newRef 1 >>> c <- newRef ('z', Just 0) >>> -- no performLocalGC required >>> x <- needRef a >>> y <- needRef b >>> z <- needRef c >>> u <- refMaybe y "t" a -- note that it wouldn't actually read "a", >>> -- but it won't be known until runtime. >>> w <- refIgnore b >>> v <- refFst c >>> return (x, y, z) >>> >>> >>> >>> On Wed, Jan 6, 2010 at 10:28 PM, Edward Kmett wrote: >>> I don't believe you can get quite the semantics you want. However, you >>> can get reasonably close, by building a manual store and backtracking. >>> >>> {-# LANGUAGE Rank2Types #-} >>> -- lets define an Oracle that tracks whether or not you might need the >>> reference, by backtracking. >>> module Oracle >>> ( Oracle, Ref >>> , newRef, readRef, writeRef, modifyRef, needRef >>> ) where >>> >>> import Control.Applicative >>> import Control.Arrow (first) >>> import Control.Monad >>> import Data.IntMap (IntMap) >>> import qualified Data.IntMap as M >>> import Unsafe.Coerce (unsafeCoerce) >>> import GHC.Prim (Any) >>> >>> -- we need to track our own worlds, otherwise we'd have to build over ST, >>> change optimistically, and track how to backtrack the state of the Store. >>> Much uglier. >>> -- values are stored as 'Any's for safety, see GHC.Prim for a discussion >>> on the hazards of risking the storage of function types using unsafeCoerce >>> as anything else. >>> data World s = World { store :: !(IntMap Any), hwm :: !Int } >>> >>> -- references into our store >>> newtype Ref s a = Ref Int deriving (Eq) >>> >>> -- our monad that can 'see the future' ~ StateT (World s) []newtype >>> Oracle s a = Oracle { unOracle :: World s -> [(a, World s)] } >>> >>> -- we rely on the fact that the list is always non-empty for any oracle >>> you can run. we are only allowed to backtrack if we thought we wouldn't need >>> the reference, and wound up needing it, so head will always succeed. >>> runOracle :: (forall s. Oracle s a) -> a >>> runOracle f = fst $ head $ unOracle f $ World M.empty 1 >>> >>> >>> instance Monad (Oracle s) where >>> return a = Oracle $ \w -> [(a,w)] >>> Oracle m >>= k = Oracle $ \s -> do >>> (a,s') <- m s >>> unOracle (k a) s' >>> >>> -- note: you cannot safely define fail here without risking a crash in >>> runOracle >>> -- Similarly, we're not a MonadPlus instance because we always want to >>> succeed eventually. >>> >>> instance Functor (Oracle s) where >>> fmap f (Oracle g) = Oracle $ \w -> first f <$> g w >>> >>> instance Applicative (Oracle s) where >>> pure = return >>> (<*>) = ap >>> >>> -- new ref allocates a fresh slot and inserts the value into the store. >>> the type level brand 's' keeps us safe, and we don't export the Ref >>> constructor. >>> newRef :: a -> Oracle s (Ref s a) >>> newRef a = Oracle $ \(World w t) -> >>> [(Ref t, World (M.insert t (unsafeCoerce a) w) (t + 1))] >>> >>> -- readRef is the only thing that ever backtracks, if we try to read a >>> reference we claimed we wouldn't need, then we backtrack to when we decided >>> we didn't need the reference, and continue with its value. >>> readRef :: Ref s a -> Oracle s a >>> readRef (Ref slot) = Oracle $ \world -> >>> maybe [] (\a -> [(unsafeCoerce a, world)]) $ M.lookup slot (store >>> world) >>> >>> -- note, writeRef dfoesn't 'need' the ref's current value, so needRef >>> will report False if you writeRef before you read it after this. >>> writeRef :: a -> Ref s a -> Oracle s a >>> writeRef a (Ref slot) = Oracle $ \world -> >>> [(a, world { store = M.insert slot (unsafeCoerce a) $ store world >>> })] >>> >>> {- >>> -- alternate writeRef where writing 'needs' the ref. >>> writeRef :: a -> Ref s a -> Oracle s a >>> writeRef a (Ref slot) = Oracle $ \World store v -> do >>> (Just _, store') <- return $ updateLookupWithKey replace slot store >>> [(a, World store' v)] >>> where >>> replace _ _ = Just (unsafeCoerce a) >>> -} >>> >>> -- modifying a reference of course needs its current value. >>> modifyRef :: (a -> a) -> Ref s a -> Oracle s a >>> modifyRef f r = do >>> a <- readRef r >>> writeRef (f a) r >>> >>> -- needRef tries to continue executing the world without the element in >>> the store in question. if that fails, then we'll backtrack to here, and try >>> again with the original world, and report that the element was in fact >>> needed. >>> needRef :: Ref s a -> Oracle s Bool >>> needRef (Ref slot) = Oracle $ \world -> >>> [ (False, world { store = M.delete slot $ store world }) >>> , (True, world) >>> ] >>> >>> -- test case: >>> refMaybe b dflt ref = if b then readRef ref else return dflt >>> refIgnore ref = return "blablabla" >>> refFst ref = fst <$> readRef ref >>> test = do >>> a <- newRef "x" >>> b <- newRef 1 >>> c <- newRef ('z', Just 0) >>> -- no performLocalGC required >>> x <- needRef a >>> y <- needRef b >>> z <- needRef c >>> u <- refMaybe y "t" a -- note that it wouldn't actually read "a", >>> -- but it won't be known until runtime. >>> w <- refIgnore b >>> v <- refFst c >>> return (x, y, z) >>> >>> -- This will disagree with your desired answer, returning: >>> >>> *Oracle> runOracle test >>> Loading package syb ... linking ... done. >>> Loading package array-0.2.0.0 ... linking ... done. >>> Loading package containers-0.2.0.1 ... linking ... done. >>> (False,False,True) >>> >>> rather than (True, False, True), because the oracle is able to see into >>> the future (via backtracking) to see that refMaybe doesn't use the reference >>> after all. >>> >>> This probably won't suit your needs, but it was a fun little exercise. >>> >>> -Edward Kmett >>> >>> On Wed, Jan 6, 2010 at 4:05 PM, Miguel Mitrofanov >>> wrote: >>> >>> On 6 Jan 2010, at 23:21, Edward Kmett wrote: >>> >>> You probably just want to hold onto weak references for your >>> 'isStillNeeded' checks. >>> >>> That's what I do now. But I want to minimize the network traffic, so I >>> want referenced values to be garbage collected as soon as possible - and I >>> couldn't find anything except System.Mem.performIO to do the job - which is >>> a bit too global for me. >>> >>> Otherwise the isStillNeeded check itself will keep you from garbage >>> collecting! >>> >>> Not necessary. What I'm imagining is that there is essentially only one >>> way to access the value stored in the reference - with readRef. So, if there >>> isn't any chance that readRef would be called, the value can be garbage >>> collected; "isStillNeeded" function only needs the reference, not the value. >>> >>> Well, yeah, that's kinda like weak references. >>> >>> >>> http://cvs.haskell.org/Hugs/pages/libraries/base/System-Mem-Weak.html >>> >>> -Edward Kmett >>> >>> On Wed, Jan 6, 2010 at 9:39 AM, Miguel Mitrofanov >>> wrote: >>> I'll take a look at them. >>> >>> I want something like this: >>> >>> refMaybe b dflt ref = if b then readRef ref else return dflt >>> refIgnore ref = return "blablabla" >>> refFst ref = >>> do >>> (v, w) <- readRef ref >>> return v >>> test = >>> do >>> a <- newRef "x" >>> b <- newRef 1 >>> c <- newRef ('z', Just 0) >>> performLocalGC -- if necessary >>> x <- isStillNeeded a >>> y <- isStillNeeded b >>> z <- isStillNeeded c >>> u <- refMaybe y "t" a -- note that it wouldn't actually read "a", >>> -- but it won't be known until runtime. >>> w <- refIgnore b >>> v <- refFst c >>> return (x, y, z) >>> >>> so that "run test" returns (True, False, True). >>> >>> >>> Dan Doel wrote: >>> On Wednesday 06 January 2010 8:52:10 am Miguel Mitrofanov wrote: >>> Is there any kind of "ST" monad that allows to know if some STRef is no >>> longer needed? >>> >>> The problem is, I want to send some data to an external storage over a >>> network and get it back later, but I don't want to send unnecessary data. >>> >>> I've managed to do something like that with weak pointers, >>> System.Mem.performGC and unsafePerformIO, but it seems to me that >>> invoking >>> GC every time is an overkill. >>> >>> Oh, and I'm ready to trade the purity of runST for that, if necessary. >>> >>> You may be able to use something like Oleg's Lightweight Monadic Regions >>> to get this effect. I suppose it depends somewhat on what qualifies a >>> reference as "no longer needed". >>> >>> http://www.cs.rutgers.edu/~ccshan/capability/region-io.pdf >>> >>> I'm not aware of anything out-of-the-box that does what you want, though. >>> >>> -- Dan >>> _______________________________________________ >>> 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 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 mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100107/dbe21dc6/attachment.html From keithshep at gmail.com Thu Jan 7 15:26:51 2010 From: keithshep at gmail.com (Keith Sheppard) Date: Thu Jan 7 14:59:44 2010 Subject: [Haskell-cafe] Re: Distinct types in a list In-Reply-To: <4B462FB7.1020303@dfki.de> References: <4b46295e5d934_5fe0edfa670234@weasel13.tmail> <4B462FB7.1020303@dfki.de> Message-ID: <92e42b741001071226k4abc205fs7886051dc1e1334f@mail.gmail.com> Hello, My impression is that using existential types where possible will result in more complete type checking than Data.Dynamic but I'm not sure since I haven't yet tried Data.Dynamic in my own code. Can someone confirm if this is right? Best Keith On Thu, Jan 7, 2010 at 2:02 PM, Christian Maeder wrote: > You could cast your parser result "a" to Dynamic using > Data.Dynamic.toDyn (and derive Typeable instances for all involved types). > > http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Data-Dynamic.html > > Using an existential types may be another alternative. > > Cheers Christian > > rodrigo.bonifacio schrieb: >> Hi all, >> >> I have a family of parsers that return either (Success t) or (Fail), using the following data type: >> >>> data ParserResult a = Success a | Fail String >>> ?deriving (Read, Show, Eq, Ord) >>> >>> isSuccess (Success _) = True >>> isSuccess (Fail _) = False >>> ... >> >> I want to add the results of different parsers to a list. Such as: >> >>> m1 = parseFirstModel file1 ? -- it returns a ParserResult of t1 >>> m2 = parseSecondModel file2 ?-- it returns a ParserResult of t2 >> >>> ps = [m1, m2] >> >> In such a way that I could write something like: >> >>> if and (map isSuccess ps) >>> ?then process m1 m2 >>> ?else ... >> >> Actually, in the real program I have to check more than two input models. However, since Lists do only hold elements of a same type, I couldn't proceed in this way. Which improvements to the ParserResult data type should I wrote in order to proceed as I want to. >> >> Best regards, >> >> Rodrigo. >> > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- keithsheppard.name From bulat.ziganshin at gmail.com Thu Jan 7 15:45:55 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Thu Jan 7 15:19:10 2010 Subject: [Haskell-cafe] Re: Distinct types in a list In-Reply-To: <92e42b741001071226k4abc205fs7886051dc1e1334f@mail.gmail.com> References: <4b46295e5d934_5fe0edfa670234@weasel13.tmail> <4B462FB7.1020303@dfki.de> <92e42b741001071226k4abc205fs7886051dc1e1334f@mail.gmail.com> Message-ID: <9510120352.20100107234555@gmail.com> Hello Keith, Thursday, January 7, 2010, 11:26:51 PM, you wrote: existential types has more limited usage compared to dynamics, but in the cases they work they allow to have compile-time type-checking instead of run-time one > Hello, My impression is that using existential types where possible > will result in more complete type checking than Data.Dynamic but I'm > not sure since I haven't yet tried Data.Dynamic in my own code. Can > someone confirm if this is right? > Best > Keith > On Thu, Jan 7, 2010 at 2:02 PM, Christian Maeder > wrote: >> You could cast your parser result "a" to Dynamic using >> Data.Dynamic.toDyn (and derive Typeable instances for all involved types). >> >> http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Data-Dynamic.html >> >> Using an existential types may be another alternative. >> >> Cheers Christian >> >> rodrigo.bonifacio schrieb: >>> Hi all, >>> >>> I have a family of parsers that return either (Success t) or (Fail), using the following data type: >>> >>>> data ParserResult a = Success a | Fail String >>>> ?deriving (Read, Show, Eq, Ord) >>>> >>>> isSuccess (Success _) = True >>>> isSuccess (Fail _) = False >>>> ... >>> >>> I want to add the results of different parsers to a list. Such as: >>> >>>> m1 = parseFirstModel file1 ? -- it returns a ParserResult of t1 >>>> m2 = parseSecondModel file2 ?-- it returns a ParserResult of t2 >>> >>>> ps = [m1, m2] >>> >>> In such a way that I could write something like: >>> >>>> if and (map isSuccess ps) >>>> ?then process m1 m2 >>>> ?else ... >>> >>> Actually, in the real program I have to check more than two input models. However, since Lists do only hold elements of a same type, I couldn't proceed in this way. Which improvements to the ParserResult data type should I wrote in order to proceed as I want to. >>> >>> Best regards, >>> >>> Rodrigo. >>> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From deadguysfrom at gmail.com Thu Jan 7 15:49:23 2010 From: deadguysfrom at gmail.com (Matt Brown) Date: Thu Jan 7 15:22:15 2010 Subject: [Haskell-cafe] Example of sending headers/cookies with Network.HTTP.simpleHTTP or Network.Browser? Message-ID: <38a1ef071001071249w37c0ec7br7bdeace72d29bba4@mail.gmail.com> Hi all, Does anyone know of a good/simple example of sending cookies and other headers in an HTTP request via simpleHTTP or Browser? I know what the cookies should be (i.e. I don't want them to be sent by the server). More specifically, I'm looking for an analogue to curl's -b and -H flags. thanks, -matt -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100107/aa8b6ee8/attachment.html From Patrick.Browne at comp.dit.ie Thu Jan 7 16:03:33 2010 From: Patrick.Browne at comp.dit.ie (pbrowne) Date: Thu Jan 7 15:36:39 2010 Subject: [Haskell-cafe] Approaches to dependent types (DT) In-Reply-To: <200910100318.38874.dan.doel@gmail.com> References: <4ACF3682.80000@comp.dit.ie> <200910100318.38874.dan.doel@gmail.com> Message-ID: <4B464C25.4040003@comp.dit.ie> Hi, I am attempting to explain an example of dependent types to computing practitioners who do not have any background in functional programming. My goal is to explain the example rather than implement or improve it. I have been told in previous postings that the approach below is a bit dated. Any comments on the correctness or otherwise would be appreciated. Regards, Pat ======================================================= Dependent Types (DT) The purpose of dependent types (DT) is to allow programmers to specify dependencies between the parameters of a multiple parameter class. DTs can be seen as a move towards more general purpose parametric type classes. DTs are declared in a class header, where the type of one class parameter is declared to depend on another class parameter. Consider the following example: class Named object name | object -> name where namef :: object -> name instance (Eq name, Named object name) => Eq object where object1 == object2 = (namef object1) == (namef object2) The first part of the class definition Named takes two type variables as parameters; namely object and name. We say, that object determines name or alternatively that name is determined by object. This is denoted in the second part of the class header (i.e. | object -> name). With DTs, the dependent type depends on values of the determining type. Hence, a DT involves a relation between Haskell?s value-level and the type-level (or type system). The Named class contains the signature, but not the definition, of one function called namef. Note, the in the definition of namef, the argument and return type (object -> name) are textually identical to that occurring in the class header, however the semantic is that of function definition rather that of type dependency. In the instance declaration, the part before the => is called the context, while the part after the => is called the head of the instance declaration. The context contains one or more class assertions, which is a list of classes each with their respective type variables, asserting that a type variable is a parameter of a particular class. The context for the above example includes two previously defined classes. The Eq class is defined in the Haskell prelude and our user defined Named class. The instance asserts: If (type of name is an instance of the Eq class) and (type pair (object, name) is an instance of Named) then object is an instance of Eq The Eq instance is quite general, it asserts that every type object is an instance of the Eq class. It does not say that every type object that is an instance of Named is also an instance of Eq. Now we consider the definition of equality (==) for the type object in the instance body. Initially, the definition determines the type name in a type->type dependency (e.g. via the function call namef object1). When the two names have been calculated the function uses this information to define equality on values of type object via equality on values of type name. Dan Doel wrote: > I'll see if I can't gloss over some of the stuff Ryan Ingram already covered. > > On Friday 09 October 2009 9:11:30 am pat browne wrote: >> 2) Types depending on types called parametric and type-indexed types > > The above distinction in types (and values) depending on types has to do with > operations beyond just said dependency. For instance: > > data List a = Nil | Cons a (List a) > > Is the definition involving types that depend on other types. And similarly: > > foo :: forall a. List (List a) > foo = Cons Nil Nil > > is a value that depends on a type. In a language more explicit about type > application, one might write: > > foo@a = Cons@(List a) Nil@a Nil@(List a) > > So far, these fall in the parametric category, but your example does not: > >> class Named object name | object -> name where >> name :: object -> name > > Classes in H98 allow you to define non-parametric type->value dependence, and > when extended with functional dependencies, or alternately, if we consider > type families, we get non-parametric type->type dependence. The difference > isn't in what things can depend on what other things, but in what operations > are available on types. Specifically, type classes/families are like being > able to do case analysis on types, so in the value case: > > class Foo a where > bar :: [a] > > instance Foo Int where > bar = [5] > > instance Foo Char where > bar = "c" > > can be seen as similar to: > > bar@c = typecase c of > Int -> [5] > Char -> "c" > > And type families are similar on the type-level (it's less clear how > functional dependencies fit in, but a one way a -> b is kind of like doing a > type-level typecase on a to define b; more accurately you have multiple type > parameters, but in each a-branch, b there is exactly one b-branch). Of course, > this is an over-simplification, so take it with salt. > >> I am aware that dependent types can be used to express constraints on >> the size of lists and other collections. > > Technically, you don't need dependent types for this, you just need type-level > naturals. But dependent types (or some sufficiently fancy faking thereof) are > nice in that you only need to define the naturals once, instead of at both the > value and type levels. > >> The class definition seems to show a >> *type-to-type* dependency (object to name), while the instance >> definition shows how a name value is used to define equality for objects >> which could be interpreted as a *value-to-type* dependency (name to >> object) in the opposite direction to that of the class. > > As Ryan remarked, this is not a value->type dependency. In the instance, you > are defining equality for the type 'object' which determines the type 'name' > in a type->type dependency. You're then defining equality on values of type > 'object' via equality on values of type 'name', via the 'name' function. But > that's just value->value dependency which every language of course has. > > GHC does have ways of faking dependent types, though, with GADTs. GADTs allow > you to define data such that matching on constructors refines things in the > type system. So, along with the mirroring mentioned above, you can manually > set up a value->type dependency that acts like full-on dependent types. For > naturals it looks like: > > -- type level naturals > data Zero > data Suc n > > -- value-level GADT indexed by the type-level naturals > data Nat n where > Zero :: Nat Zero > Suc :: Nat n -> Nat (Suc n) > > -- existential wrapper > data Natural where > Wrap :: Nat n -> Natural > > Ryan's zip function would look like: > > zip :: forall a b n. Nat n -> Vector n a -> Vector n b -> Vector n (a,b) > zip Zero Nil Nil = Nil > zip (Suc n) (Cons x xs) (Cons y ys) = Cons (x,y) (zip n xs ys) > > although the 'Nat n' parameter is technically unnecessary in this case. But, > in some other function: > > foo :: forall n. Nat n -> T > foo Zero = {- we know type-level n = Zero here -} > foo (Suc n) = {- we know type-level n = Suc m for some m here -} > > Of course, mirroring like the above is kind of a pain and only gets more so > the more complex the things you want to mirror are (although this is how, for > instance, ATS handles dependent types). There is a preprocessor, SHE, that > automates this, though, and lets you write definitions that look like a full- > on dependently typed language (among other things). > > Anyhow, I'll cease rambling for now. > > Cheers, > > -- Dan From gcross at phys.washington.edu Thu Jan 7 16:31:46 2010 From: gcross at phys.washington.edu (Gregory Crosswhite) Date: Thu Jan 7 16:04:39 2010 Subject: [Haskell-cafe] Testing for statistical properties Message-ID: Hey everyone! I have some computations that satisfy statistical properties which I would like to test --- that is, the result of the computation is non-deterministic, but I want to check that it is sampling the distribution that it should be sampling. Is anyone aware of a Haskell library out there that does anything like this? Cheers, Greg From miguelimo38 at yandex.ru Thu Jan 7 16:39:03 2010 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Thu Jan 7 16:11:57 2010 Subject: [Haskell-cafe] Explicit garbage collection In-Reply-To: <7fb8f82f1001071207w63da732q168908d024bfaffd@mail.gmail.com> References: <4B44958A.2080809@yandex.ru> <201001060906.51127.dan.doel@gmail.com> <4B44A09C.8040103@yandex.ru> <7fb8f82f1001061221v40ffe0cby8c0e4b453e72d65d@mail.gmail.com> <7fb8f82f1001061928o4a58ac46qbaaf00691f26e304@mail.gmail.com> <7fb8f82f1001062101s44d45b59v83d176d12287243@mail.gmail.com> <7BB0709F-F74E-4181-BA49-D292193DABF9@yandex.ru> <693475F8-3C64-4EA1-839D-C7C1ED87FB01@yandex.ru> <7fb8f82f1001071207w63da732q168908d024bfaffd@mail.gmail.com> Message-ID: <5C491A8C-31E4-4D95-B773-014AD9AAE0FC@yandex.ru> I liked it too. Seems like I have to show some real code, and my apologies for a long e-mail. Well, that's what I'm actually trying to do and what I've managed to achieve so far. > module Ask where > import Control.Monad > import Data.IORef > import Data.Maybe > import System.IO.Unsafe -- Yes, I would need that > import System.Mem > import System.Mem.Weak Suppose we're writing a RESTful server, which keeps all state on the client. We want it to send questions to the client and get back the answers. We can also send some state data to the client and we are sure that the client would return them back unchanged. So, that's the type of our server: > type Server medium = Maybe (medium, String) -> IO (Maybe (medium, String)) The client starts interaction, sending "Nothing"; when server finally returns "Nothing", the session stops. I would emulate the client in GHCi with the following function: > client :: Show medium => Bool -> Server medium -> IO () > client debug server = client' Nothing where > client' query = > do response <- server query > case response of > Nothing -> return () > Just (medium, question) -> > do when debug $ putStr "Debug: " >> print medium > putStrLn question > putStr "--> " > answer <- getLine > client' $ Just (medium, answer) Nothing very interesting. The only thing to note is that the boolean argument allows us to see the state sent by server - for debugging purposes. But I want something more high-level. The goal is to solve the Graham's "arc challenge". So the high-level interface is implemented by this type: > data Ask a = Finish a | Continue String (String -> Ask a) A possible application would be: > test :: Ask () > test = > do s1 <- ask "Enter the first number" > let n1 = read s1 > s2 <- ask "Enter the second number" > let n2 = read s2 > ask $ show $ n1 + n2 > return () Well, to do that, I need a Monad instance for Ask: > instance Monad Ask where > return = Finish > Finish x >>= h = h x > Continue question k >>= h = Continue question $ \answer -> k answer >>= h and an "ask" function: > ask :: String -> Ask String > ask question = Continue question $ \answer -> return answer Now, the problem is with the route from high level to the low level. We can do it relatively simply: > simpleServer :: Ask () -> Server [String] > simpleServer anything = return . simpleServer' anything . maybe [] (\(medium, answer) -> medium ++ [answer]) where > simpleServer' (Finish ()) _ = Nothing > simpleServer' (Continue question _) [] = Just ([], question) > simpleServer' (Continue _ k) (s : ss) = > do (medium, question) <- simpleServer' (k s) ss > return (s : medium, question) And indeed, our test example works: *Ask> client False $ simpleServer test Enter the first number --> 3 Enter the second number --> 4 7 --> But, as you've probably guessed already, this "simpleServer" sends way too much information over network: > nonsense :: Ask () > nonsense = > do a <- ask "?" > b <- ask a > c <- ask b > d <- ask c > e <- ask b -- Note this "b" instead of "d", it's deliberate. > return () *Ask> client True $ simpleServer nonsense Debug: [] ? --> a Debug: ["a"] a --> b Debug: ["a","b"] b --> c Debug: ["a","b","c"] c --> d Debug: ["a","b","c","d"] b --> e All user answers from the very beginning get transmitted. I want to transmit only those answers that are actually used. I'm gonna write another server, a (relatively) smart one. A simple boxing type: > data Box a = Box {unBox :: a} Now, the server. I use "Nothing" for those user answers that are no longer needed. > smartServer :: Ask () -> Server [Maybe String] > smartServer anything = smartServerIO anything . maybe [] (\(medium, answer) -> medium ++ [Just answer]) where > smartServerIO anything query = Sometimes a value is not used anymore just because it WAS used already. So I'll use a mutable list to keep track of those values that are actually dereferenced: > do usedList <- newIORef [] Then, I'll make weak pointers for all user answers: > let boxedQuery = map Box query > weakPtrs <- mapM (\box -> mkWeak box () Nothing) boxedQuery and actually run my "Ask" value. > case findWeakPtrs 0 anything boxedQuery usedList of > Finish () -> return Nothing > Continue question rest -> Now, the interesting part. I'd invoke a garbage collector to get rid of those boxes that aren't necessary anymore. > do performGC Now, weak pointers tell me what boxes are not dereferenced but can be dereferenced in the future, and my mutable list has the numbers of boxes that were dereferenced. > danglingNumbers <- mapM deRefWeak weakPtrs > usedNumbers <- readIORef usedList I also need to keep this "future" alive, so that usable boxes don't get garbage collected. > case rest undefined of _ -> return () And now all I need to do is to filter out those boxes that are not in any of the two lists: > return $ Just (zipWith3 (isUsed usedNumbers) [0..] danglingNumbers query, question) Helper function has an interesting detail: > findWeakPtrs _ (Finish ()) _ _ = Finish () > findWeakPtrs _ response [] _ = response I use unsafePerformIO to track those boxes that get actually dereferenced: > findWeakPtrs n (Continue _ k) (s : ss) usedList = > findWeakPtrs (n+1) (k (unsafePerformIO $ modifyIORef usedList (n :) >> return (fromJust $ unBox s))) ss usedList A filtering function is not very interesting: > isUsed usedNumbers index Nothing _ | not (index `elem` usedNumbers) = Nothing > isUsed _ _ _ answer = answer And it works: *Ask> client True $ smartServer nonsense Debug: [] ? --> a Debug: [Just "a"] a --> b Debug: [Nothing,Just "b"] b --> c Debug: [Nothing,Just "b",Just "c"] c --> d Debug: [Nothing,Just "b",Nothing,Nothing] b --> e So, the problem is, I don't think calling performGC every time is a good idea. I'd like to tell explicitly what values are to be garbage collected. It doesn't seem like it's possible with current version of GHC, though. On 7 Jan 2010, at 23:07, Edward Kmett wrote: > Thats a shame, I was rather fond of this monad. To get that last > 'True', you'll really have to rely on garbage collection to > approximate reachability for you, leaving the weak reference > solution the best you can hope for. > > -Edward Kmett > > On Thu, Jan 7, 2010 at 12:39 PM, Miguel Mitrofanov > wrote: > Damn. Seems like I really need (True, False, True) as a result of > "test". > > > On 7 Jan 2010, at 08:52, Miguel Mitrofanov wrote: > > Seems very nice. Thanks. > > On 7 Jan 2010, at 08:01, Edward Kmett wrote: > > Here is a slightly nicer version using the Codensity monad of STM. > > Thanks go to Andrea Vezzosi for figuring out an annoying hanging bug > I was having. > > -Edward Kmett > > {-# LANGUAGE Rank2Types, GeneralizedNewtypeDeriving, DeriveFunctor #-} > module STMOracle > ( Oracle, Ref > , newRef, readRef, writeRef, modifyRef, needRef > ) where > > import Control.Applicative > import Control.Monad > import Control.Concurrent.STM > > instance Applicative STM where > pure = return > (<*>) = ap > > newtype Ref s a = Ref (TVar (Maybe a)) > newtype Oracle s a = Oracle { unOracle :: forall r. (a -> STM r) -> > STM r } deriving (Functor) > > instance Monad (Oracle s) where > return x = Oracle (\k -> k x) > Oracle m >>= f = Oracle (\k -> m (\a -> unOracle (f a) k)) > > mkOracle m = Oracle (m >>=) > > runOracle :: (forall s. Oracle s a) -> IO a > runOracle t = atomically (unOracle t return) > > newRef :: a -> Oracle s (Ref s a) > newRef a = mkOracle $ Ref <$> newTVar (Just a) > > readRef :: Ref s a -> Oracle s a > readRef (Ref r) = mkOracle $ do > m <- readTVar r > maybe retry return m > > writeRef :: a -> Ref s a -> Oracle s a > writeRef a (Ref r) = mkOracle $ do > writeTVar r (Just a) > return a > > modifyRef :: (a -> a) -> Ref s a -> Oracle s a > modifyRef f r = do > a <- readRef r > writeRef (f a) r > > needRef :: Ref s a -> Oracle s Bool > needRef (Ref slot) = Oracle $ \k -> > (writeTVar slot Nothing >> k False) > `orElse` k True > > -- test > case > : refMaybe > b dflt ref = if b then readRef ref else return dflt > refIgnore ref = return "blablabla" > refFst ref = fst `fmap` readRef ref > test = do > a <- newRef "x" > b <- newRef 1 > c <- newRef ('z', Just 0) > -- no performLocalGC required > x <- needRef a > y <- needRef b > z <- needRef c > u <- refMaybe y "t" a -- note that it wouldn't actually read "a", > -- but it won't be known until runtime. > w <- refIgnore b > v <- refFst c > return (x, y, z) > > > > On Wed, Jan 6, 2010 at 10:28 PM, Edward Kmett > wrote: > I don't believe you can get quite the semantics you want. However, > you can get reasonably close, by building a manual store and > backtracking. > > {-# LANGUAGE Rank2Types #-} > -- lets define an Oracle that tracks whether or not you might need > the reference, by backtracking. > module Oracle > ( Oracle, Ref > , newRef, readRef, writeRef, modifyRef, needRef > ) where > > import Control.Applicative > import Control.Arrow (first) > import Control.Monad > import Data.IntMap (IntMap) > import qualified Data.IntMap as M > import Unsafe.Coerce (unsafeCoerce) > import GHC.Prim (Any) > > -- we need to track our own worlds, otherwise we'd have to build > over ST, change optimistically, and track how to backtrack the state > of the Store. Much uglier. > -- values are stored as 'Any's for safety, see GHC.Prim for a > discussion on the hazards of risking the storage of function types > using unsafeCoerce as anything else. > data World s = World { store :: !(IntMap Any), hwm :: !Int } > > -- references into our store > newtype Ref s a = Ref Int deriving (Eq) > > -- our monad that can 'see the future' ~ StateT (World s) []newtype > Oracle s a = Oracle { unOracle :: World s -> [(a, World s)] } > > -- we rely on the fact that the list is always non-empty for any > oracle you can run. we are only allowed to backtrack if we thought > we wouldn't need the reference, and wound up needing it, so head > will always succeed. > runOracle :: (forall s. Oracle s a) -> a > runOracle f = fst $ head $ unOracle f $ World M.empty 1 > > > instance Monad (Oracle s) where > return a = Oracle $ \w -> [(a,w)] > Oracle m >>= k = Oracle $ \s -> do > (a,s') <- m s > unOracle (k a) s' > > -- note: you cannot safely define fail here without risking a crash > in runOracle > -- Similarly, we're not a MonadPlus instance because we always want > to succeed eventually. > > instance Functor (Oracle s) where > fmap f (Oracle g) = Oracle $ \w -> first f <$> g w > > instance Applicative (Oracle s) where > pure = return > (<*>) = ap > > -- new ref allocates a fresh slot and inserts the value into the > store. the type level brand 's' keeps us safe, and we don't export > the Ref constructor. > newRef :: a -> Oracle s (Ref s a) > newRef a = Oracle $ \(World w t) -> > [(Ref t, World (M.insert t (unsafeCoerce a) w) (t + 1))] > > -- readRef is the only thing that ever backtracks, if we try to read > a reference we claimed we wouldn't need, then we backtrack to when > we decided we didn't need the reference, and continue with its value. > readRef :: Ref s a -> Oracle s a > readRef (Ref slot) = Oracle $ \world -> > maybe [] (\a -> [(unsafeCoerce a, world)]) $ M.lookup slot (store > world) > > -- note, writeRef dfoesn't 'need' the ref's current value, so > needRef will report False if you writeRef before you read it after > this. > writeRef :: a -> Ref s a -> Oracle s a > writeRef a (Ref slot) = Oracle $ \world -> > [(a, world { store = M.insert slot (unsafeCoerce a) $ store > world })] > > {- > -- alternate writeRef where writing 'needs' the ref. > writeRef :: a -> Ref s a -> Oracle s a > writeRef a (Ref slot) = Oracle $ \World store v -> do > (Just _, store') <- return $ updateLookupWithKey replace slot store > [(a, World store' v)] > where > replace _ _ = Just (unsafeCoerce a) > -} > > -- modifying a reference of course needs its current value. > modifyRef :: (a -> a) -> Ref s a -> Oracle s a > modifyRef f r = do > a <- readRef r > writeRef (f a) r > > -- needRef tries to continue executing the world without the element > in the store in question. if that fails, then we'll backtrack to > here, and try again with the original world, and report that the > element was in fact needed. > needRef :: Ref s a -> Oracle s Bool > needRef (Ref slot) = Oracle $ \world -> > [ (False, world { store = M.delete slot $ store world }) > , (True, world) > ] > > -- test case: > refMaybe b dflt ref = if b then readRef ref else return dflt > refIgnore ref = return "blablabla" > refFst ref = fst <$> readRef ref > test = do > a <- newRef "x" > b <- newRef 1 > c <- newRef ('z', Just 0) > -- no performLocalGC required > x <- needRef a > y <- needRef b > z <- needRef c > u <- refMaybe y "t" a -- note that it wouldn't actually read "a", > -- but it won't be known until runtime. > w <- refIgnore b > v <- refFst c > return (x, y, z) > > -- This will disagree with your desired answer, returning: > > *Oracle> runOracle test > Loading package syb ... linking ... done. > Loading package array-0.2.0.0 ... linking ... done. > Loading package containers-0.2.0.1 ... linking ... done. > (False,False,True) > > rather than (True, False, True), because the oracle is able to see > into the future (via backtracking) to see that refMaybe doesn't use > the reference after all. > > This probably won't suit your needs, but it was a fun little exercise. > > -Edward Kmett > > On Wed, Jan 6, 2010 at 4:05 PM, Miguel Mitrofanov > wrote: > > On 6 Jan 2010, at 23:21, Edward Kmett wrote: > > You probably just want to hold onto weak references for your > 'isStillNeeded' checks. > > That's what I do now. But I want to minimize the network traffic, so > I want referenced values to be garbage collected as soon as possible > - and I couldn't find anything except System.Mem.performIO to do the > job - which is a bit too global for me. > > Otherwise the isStillNeeded check itself will keep you from garbage > collecting! > > Not necessary. What I'm imagining is that there is essentially only > one way to access the value stored in the reference - with readRef. > So, if there isn't any chance that readRef would be called, the > value can be garbage collected; "isStillNeeded" function only needs > the reference, not the value. > > Well, yeah, that's kinda like weak references. > > > http://cvs.haskell.org/Hugs/pages/libraries/base/System-Mem-Weak.html > > -Edward Kmett > > On Wed, Jan 6, 2010 at 9:39 AM, Miguel Mitrofanov > wrote: > I'll take a look at them. > > I want something like this: > > refMaybe b dflt ref = if b then readRef ref else return dflt > refIgnore ref = return "blablabla" > refFst ref = > do > (v, w) <- readRef ref > return v > test = > do > a <- newRef "x" > b <- newRef 1 > c <- newRef ('z', Just 0) > performLocalGC -- if necessary > x <- isStillNeeded a > y <- isStillNeeded b > z <- isStillNeeded c > u <- refMaybe y "t" a -- note that it wouldn't actually read "a", > -- but it won't be known until runtime. > w <- refIgnore b > v <- refFst c > return (x, y, z) > > so that "run test" returns (True, False, True). > > > Dan Doel wrote: > On Wednesday 06 January 2010 8:52:10 am Miguel Mitrofanov wrote: > Is there any kind of "ST" monad that allows to know if some STRef is > no > longer needed? > > The problem is, I want to send some data to an external storage over a > network and get it back later, but I don't want to send unnecessary > data. > > I've managed to do something like that with weak pointers, > System.Mem.performGC and unsafePerformIO, but it seems to me that > invoking > GC every time is an overkill. > > Oh, and I'm ready to trade the purity of runST for that, if necessary. > > You may be able to use something like Oleg's Lightweight Monadic > Regions to get this effect. I suppose it depends somewhat on what > qualifies a reference as "no longer needed". > > http://www.cs.rutgers.edu/~ccshan/capability/region-io.pdf > > I'm not aware of anything out-of-the-box that does what you want, > though. > > -- Dan > _______________________________________________ > 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 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 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 From ekmett at gmail.com Thu Jan 7 16:53:09 2010 From: ekmett at gmail.com (Edward Kmett) Date: Thu Jan 7 16:26:02 2010 Subject: [Haskell-cafe] Explicit garbage collection In-Reply-To: <5C491A8C-31E4-4D95-B773-014AD9AAE0FC@yandex.ru> References: <4B44958A.2080809@yandex.ru> <4B44A09C.8040103@yandex.ru> <7fb8f82f1001061221v40ffe0cby8c0e4b453e72d65d@mail.gmail.com> <7fb8f82f1001061928o4a58ac46qbaaf00691f26e304@mail.gmail.com> <7fb8f82f1001062101s44d45b59v83d176d12287243@mail.gmail.com> <7BB0709F-F74E-4181-BA49-D292193DABF9@yandex.ru> <693475F8-3C64-4EA1-839D-C7C1ED87FB01@yandex.ru> <7fb8f82f1001071207w63da732q168908d024bfaffd@mail.gmail.com> <5C491A8C-31E4-4D95-B773-014AD9AAE0FC@yandex.ru> Message-ID: <7fb8f82f1001071353r63358486sefdcd46984e6332e@mail.gmail.com> That is kind of what I thought you were doing. Retooling to see if we can get any better performance out of collecting, it seems that System.Mem.PerformGC does a foreign call out to performMajorGC to ask for a global collection. But I would hazard that you might be able to get most of the benefit by just asking for the nursery to be cleaned up. To that end, perhaps it would be worthwhile to consider switching to something like: foreign import ccall {-safe-} "performGC" performMinorGC :: IO () -- System.Mem imports performMajorGC as 'performGC' but the minor collection appears to be called performGC, hence the rename. This should let you call for a minor collection, which should be considerably less time consuming. Especially as if you call it frequently you'll be dealing with a mostly cleared nursery anyways. -Edward Kmett On Thu, Jan 7, 2010 at 4:39 PM, Miguel Mitrofanov wrote: > I liked it too. Seems like I have to show some real code, and my apologies > for a long e-mail. > > Well, that's what I'm actually trying to do and what I've managed to > achieve so far. > > > module Ask where > > import Control.Monad > > import Data.IORef > > import Data.Maybe > > import System.IO.Unsafe -- Yes, I would need that > > import System.Mem > > import System.Mem.Weak > > Suppose we're writing a RESTful server, which keeps all state on the > client. We want it to send questions to the client and get back the answers. > We can also send some state data to the client and we are sure that the > client would return them back unchanged. So, that's the type of our server: > > > type Server medium = Maybe (medium, String) -> IO (Maybe (medium, > String)) > > The client starts interaction, sending "Nothing"; when server finally > returns "Nothing", the session stops. I would emulate the client in GHCi > with the following function: > > > client :: Show medium => Bool -> Server medium -> IO () > > client debug server = client' Nothing where > > client' query = > > do response <- server query > > case response of > > Nothing -> return () > > Just (medium, question) -> > > do when debug $ putStr "Debug: " >> print medium > > putStrLn question > > putStr "--> " > > answer <- getLine > > client' $ Just (medium, answer) > > Nothing very interesting. The only thing to note is that the boolean > argument allows us to see the state sent by server - for debugging purposes. > > But I want something more high-level. The goal is to solve the Graham's > "arc challenge". So the high-level interface is implemented by this type: > > > data Ask a = Finish a | Continue String (String -> Ask a) > > A possible application would be: > > > test :: Ask () > > test = > > do s1 <- ask "Enter the first number" > > let n1 = read s1 > > s2 <- ask "Enter the second number" > > let n2 = read s2 > > ask $ show $ n1 + n2 > > return () > > Well, to do that, I need a Monad instance for Ask: > > > instance Monad Ask where > > return = Finish > > Finish x >>= h = h x > > Continue question k >>= h = Continue question $ \answer -> k answer > >>= h > > and an "ask" function: > > > ask :: String -> Ask String > > ask question = Continue question $ \answer -> return answer > > Now, the problem is with the route from high level to the low level. We can > do it relatively simply: > > > simpleServer :: Ask () -> Server [String] > > simpleServer anything = return . simpleServer' anything . maybe [] > (\(medium, answer) -> medium ++ [answer]) where > > simpleServer' (Finish ()) _ = Nothing > > simpleServer' (Continue question _) [] = Just ([], question) > > simpleServer' (Continue _ k) (s : ss) = > > do (medium, question) <- simpleServer' (k s) ss > > return (s : medium, question) > > And indeed, our test example works: > > *Ask> client False $ simpleServer test > Enter the first number > --> 3 > Enter the second number > --> 4 > 7 > --> > > But, as you've probably guessed already, this "simpleServer" sends way too > much information over network: > > > nonsense :: Ask () > > nonsense = > > do a <- ask "?" > > b <- ask a > > c <- ask b > > d <- ask c > > e <- ask b -- Note this "b" instead of "d", it's deliberate. > > return () > > *Ask> client True $ simpleServer nonsense > Debug: [] > ? > --> a > Debug: ["a"] > a > --> b > Debug: ["a","b"] > b > --> c > Debug: ["a","b","c"] > c > --> d > Debug: ["a","b","c","d"] > b > --> e > > All user answers from the very beginning get transmitted. > > I want to transmit only those answers that are actually used. I'm gonna > write another server, a (relatively) smart one. > > A simple boxing type: > > > data Box a = Box {unBox :: a} > > Now, the server. I use "Nothing" for those user answers that are no longer > needed. > > > smartServer :: Ask () -> Server [Maybe String] > > smartServer anything = smartServerIO anything . maybe [] (\(medium, > answer) -> medium ++ [Just answer]) where > > smartServerIO anything query = > > Sometimes a value is not used anymore just because it WAS used already. So > I'll use a mutable list to keep track of those values that are actually > dereferenced: > > > do usedList <- newIORef [] > > Then, I'll make weak pointers for all user answers: > > > let boxedQuery = map Box query > > weakPtrs <- mapM (\box -> mkWeak box () Nothing) boxedQuery > > and actually run my "Ask" value. > > > case findWeakPtrs 0 anything boxedQuery usedList of > > Finish () -> return Nothing > > Continue question rest -> > > Now, the interesting part. I'd invoke a garbage collector to get rid of > those boxes that aren't necessary anymore. > > > do performGC > > Now, weak pointers tell me what boxes are not dereferenced but can be > dereferenced in the future, and my mutable list has the numbers of boxes > that were dereferenced. > > > danglingNumbers <- mapM deRefWeak weakPtrs > > usedNumbers <- readIORef usedList > > I also need to keep this "future" alive, so that usable boxes don't get > garbage collected. > > > case rest undefined of _ -> return () > > And now all I need to do is to filter out those boxes that are not in any > of the two lists: > > > return $ Just (zipWith3 (isUsed usedNumbers) [0..] > danglingNumbers query, question) > > Helper function has an interesting detail: > > > findWeakPtrs _ (Finish ()) _ _ = Finish () > > findWeakPtrs _ response [] _ = response > > I use unsafePerformIO to track those boxes that get actually dereferenced: > > > findWeakPtrs n (Continue _ k) (s : ss) usedList = > > findWeakPtrs (n+1) (k (unsafePerformIO $ modifyIORef usedList (n > :) >> return (fromJust $ unBox s))) ss usedList > > A filtering function is not very interesting: > > > isUsed usedNumbers index Nothing _ | not (index `elem` usedNumbers) = > Nothing > > isUsed _ _ _ answer = answer > > And it works: > > *Ask> client True $ smartServer nonsense > Debug: [] > ? > --> a > Debug: [Just "a"] > a > --> b > Debug: [Nothing,Just "b"] > b > --> c > Debug: [Nothing,Just "b",Just "c"] > c > --> d > Debug: [Nothing,Just "b",Nothing,Nothing] > b > --> e > > So, the problem is, I don't think calling performGC every time is a good > idea. I'd like to tell explicitly what values are to be garbage collected. > It doesn't seem like it's possible with current version of GHC, though. > > > On 7 Jan 2010, at 23:07, Edward Kmett wrote: > > Thats a shame, I was rather fond of this monad. To get that last 'True', >> you'll really have to rely on garbage collection to approximate reachability >> for you, leaving the weak reference solution the best you can hope for. >> >> -Edward Kmett >> >> On Thu, Jan 7, 2010 at 12:39 PM, Miguel Mitrofanov >> wrote: >> Damn. Seems like I really need (True, False, True) as a result of "test". >> >> >> On 7 Jan 2010, at 08:52, Miguel Mitrofanov wrote: >> >> Seems very nice. Thanks. >> >> On 7 Jan 2010, at 08:01, Edward Kmett wrote: >> >> Here is a slightly nicer version using the Codensity monad of STM. >> >> Thanks go to Andrea Vezzosi for figuring out an annoying hanging bug I was >> having. >> >> -Edward Kmett >> >> {-# LANGUAGE Rank2Types, GeneralizedNewtypeDeriving, DeriveFunctor #-} >> module STMOracle >> ( Oracle, Ref >> , newRef, readRef, writeRef, modifyRef, needRef >> ) where >> >> import Control.Applicative >> import Control.Monad >> import Control.Concurrent.STM >> >> instance Applicative STM where >> pure = return >> (<*>) = ap >> >> newtype Ref s a = Ref (TVar (Maybe a)) >> newtype Oracle s a = Oracle { unOracle :: forall r. (a -> STM r) -> STM r >> } deriving (Functor) >> >> instance Monad (Oracle s) where >> return x = Oracle (\k -> k x) >> Oracle m >>= f = Oracle (\k -> m (\a -> unOracle (f a) k)) >> >> mkOracle m = Oracle (m >>=) >> >> runOracle :: (forall s. Oracle s a) -> IO a >> runOracle t = atomically (unOracle t return) >> >> newRef :: a -> Oracle s (Ref s a) >> newRef a = mkOracle $ Ref <$> newTVar (Just a) >> >> readRef :: Ref s a -> Oracle s a >> readRef (Ref r) = mkOracle $ do >> m <- readTVar r >> maybe retry return m >> >> writeRef :: a -> Ref s a -> Oracle s a >> writeRef a (Ref r) = mkOracle $ do >> writeTVar r (Just a) >> return a >> >> modifyRef :: (a -> a) -> Ref s a -> Oracle s a >> modifyRef f r = do >> a <- readRef r >> writeRef (f a) r >> >> needRef :: Ref s a -> Oracle s Bool >> needRef (Ref slot) = Oracle $ \k -> >> (writeTVar slot Nothing >> k False) >> `orElse` k True >> >> -- test case: >> refMaybe b >> dflt ref = if b then readRef ref else return dflt >> refIgnore ref = return "blablabla" >> refFst ref = fst `fmap` readRef ref >> test = do >> a <- newRef "x" >> b <- newRef 1 >> c <- newRef ('z', Just 0) >> -- no performLocalGC required >> x <- needRef a >> y <- needRef b >> z <- needRef c >> u <- refMaybe y "t" a -- note that it wouldn't actually read "a", >> -- but it won't be known until runtime. >> w <- refIgnore b >> v <- refFst c >> return (x, y, z) >> >> >> >> On Wed, Jan 6, 2010 at 10:28 PM, Edward Kmett wrote: >> I don't believe you can get quite the semantics you want. However, you can >> get reasonably close, by building a manual store and backtracking. >> >> {-# LANGUAGE Rank2Types #-} >> -- lets define an Oracle that tracks whether or not you might need the >> reference, by backtracking. >> module Oracle >> ( Oracle, Ref >> , newRef, readRef, writeRef, modifyRef, needRef >> ) where >> >> import Control.Applicative >> import Control.Arrow (first) >> import Control.Monad >> import Data.IntMap (IntMap) >> import qualified Data.IntMap as M >> import Unsafe.Coerce (unsafeCoerce) >> import GHC.Prim (Any) >> >> -- we need to track our own worlds, otherwise we'd have to build over ST, >> change optimistically, and track how to backtrack the state of the Store. >> Much uglier. >> -- values are stored as 'Any's for safety, see GHC.Prim for a discussion >> on the hazards of risking the storage of function types using unsafeCoerce >> as anything else. >> data World s = World { store :: !(IntMap Any), hwm :: !Int } >> >> -- references into our store >> newtype Ref s a = Ref Int deriving (Eq) >> >> -- our monad that can 'see the future' ~ StateT (World s) []newtype Oracle >> s a = Oracle { unOracle :: World s -> [(a, World s)] } >> >> -- we rely on the fact that the list is always non-empty for any oracle >> you can run. we are only allowed to backtrack if we thought we wouldn't need >> the reference, and wound up needing it, so head will always succeed. >> runOracle :: (forall s. Oracle s a) -> a >> runOracle f = fst $ head $ unOracle f $ World M.empty 1 >> >> >> instance Monad (Oracle s) where >> return a = Oracle $ \w -> [(a,w)] >> Oracle m >>= k = Oracle $ \s -> do >> (a,s') <- m s >> unOracle (k a) s' >> >> -- note: you cannot safely define fail here without risking a crash in >> runOracle >> -- Similarly, we're not a MonadPlus instance because we always want to >> succeed eventually. >> >> instance Functor (Oracle s) where >> fmap f (Oracle g) = Oracle $ \w -> first f <$> g w >> >> instance Applicative (Oracle s) where >> pure = return >> (<*>) = ap >> >> -- new ref allocates a fresh slot and inserts the value into the store. >> the type level brand 's' keeps us safe, and we don't export the Ref >> constructor. >> newRef :: a -> Oracle s (Ref s a) >> newRef a = Oracle $ \(World w t) -> >> [(Ref t, World (M.insert t (unsafeCoerce a) w) (t + 1))] >> >> -- readRef is the only thing that ever backtracks, if we try to read a >> reference we claimed we wouldn't need, then we backtrack to when we decided >> we didn't need the reference, and continue with its value. >> readRef :: Ref s a -> Oracle s a >> readRef (Ref slot) = Oracle $ \world -> >> maybe [] (\a -> [(unsafeCoerce a, world)]) $ M.lookup slot (store world) >> >> -- note, writeRef dfoesn't 'need' the ref's current value, so needRef will >> report False if you writeRef before you read it after this. >> writeRef :: a -> Ref s a -> Oracle s a >> writeRef a (Ref slot) = Oracle $ \world -> >> [(a, world { store = M.insert slot (unsafeCoerce a) $ store world })] >> >> {- >> -- alternate writeRef where writing 'needs' the ref. >> writeRef :: a -> Ref s a -> Oracle s a >> writeRef a (Ref slot) = Oracle $ \World store v -> do >> (Just _, store') <- return $ updateLookupWithKey replace slot store >> [(a, World store' v)] >> where >> replace _ _ = Just (unsafeCoerce a) >> -} >> >> -- modifying a reference of course needs its current value. >> modifyRef :: (a -> a) -> Ref s a -> Oracle s a >> modifyRef f r = do >> a <- readRef r >> writeRef (f a) r >> >> -- needRef tries to continue executing the world without the element in >> the store in question. if that fails, then we'll backtrack to here, and try >> again with the original world, and report that the element was in fact >> needed. >> needRef :: Ref s a -> Oracle s Bool >> needRef (Ref slot) = Oracle $ \world -> >> [ (False, world { store = M.delete slot $ store world }) >> , (True, world) >> ] >> >> -- test case: >> refMaybe b dflt ref = if b then readRef ref else return dflt >> refIgnore ref = return "blablabla" >> refFst ref = fst <$> readRef ref >> test = do >> a <- newRef "x" >> b <- newRef 1 >> c <- newRef ('z', Just 0) >> -- no performLocalGC required >> x <- needRef a >> y <- needRef b >> z <- needRef c >> u <- refMaybe y "t" a -- note that it wouldn't actually read "a", >> -- but it won't be known until runtime. >> w <- refIgnore b >> v <- refFst c >> return (x, y, z) >> >> -- This will disagree with your desired answer, returning: >> >> *Oracle> runOracle test >> Loading package syb ... linking ... done. >> Loading package array-0.2.0.0 ... linking ... done. >> Loading package containers-0.2.0.1 ... linking ... done. >> (False,False,True) >> >> rather than (True, False, True), because the oracle is able to see into >> the future (via backtracking) to see that refMaybe doesn't use the reference >> after all. >> >> This probably won't suit your needs, but it was a fun little exercise. >> >> -Edward Kmett >> >> On Wed, Jan 6, 2010 at 4:05 PM, Miguel Mitrofanov >> wrote: >> >> On 6 Jan 2010, at 23:21, Edward Kmett wrote: >> >> You probably just want to hold onto weak references for your >> 'isStillNeeded' checks. >> >> That's what I do now. But I want to minimize the network traffic, so I >> want referenced values to be garbage collected as soon as possible - and I >> couldn't find anything except System.Mem.performIO to do the job - which is >> a bit too global for me. >> >> Otherwise the isStillNeeded check itself will keep you from garbage >> collecting! >> >> Not necessary. What I'm imagining is that there is essentially only one >> way to access the value stored in the reference - with readRef. So, if there >> isn't any chance that readRef would be called, the value can be garbage >> collected; "isStillNeeded" function only needs the reference, not the value. >> >> Well, yeah, that's kinda like weak references. >> >> >> http://cvs.haskell.org/Hugs/pages/libraries/base/System-Mem-Weak.html >> >> -Edward Kmett >> >> On Wed, Jan 6, 2010 at 9:39 AM, Miguel Mitrofanov >> wrote: >> I'll take a look at them. >> >> I want something like this: >> >> refMaybe b dflt ref = if b then readRef ref else return dflt >> refIgnore ref = return "blablabla" >> refFst ref = >> do >> (v, w) <- readRef ref >> return v >> test = >> do >> a <- newRef "x" >> b <- newRef 1 >> c <- newRef ('z', Just 0) >> performLocalGC -- if necessary >> x <- isStillNeeded a >> y <- isStillNeeded b >> z <- isStillNeeded c >> u <- refMaybe y "t" a -- note that it wouldn't actually read "a", >> -- but it won't be known until runtime. >> w <- refIgnore b >> v <- refFst c >> return (x, y, z) >> >> so that "run test" returns (True, False, True). >> >> >> Dan Doel wrote: >> On Wednesday 06 January 2010 8:52:10 am Miguel Mitrofanov wrote: >> Is there any kind of "ST" monad that allows to know if some STRef is no >> longer needed? >> >> The problem is, I want to send some data to an external storage over a >> network and get it back later, but I don't want to send unnecessary data. >> >> I've managed to do something like that with weak pointers, >> System.Mem.performGC and unsafePerformIO, but it seems to me that invoking >> GC every time is an overkill. >> >> Oh, and I'm ready to trade the purity of runST for that, if necessary. >> >> You may be able to use something like Oleg's Lightweight Monadic Regions >> to get this effect. I suppose it depends somewhat on what qualifies a >> reference as "no longer needed". >> >> http://www.cs.rutgers.edu/~ccshan/capability/region-io.pdf >> >> I'm not aware of anything out-of-the-box that does what you want, though. >> >> -- Dan >> _______________________________________________ >> 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 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 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 >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100107/2d353ec2/attachment.html From miguelimo38 at yandex.ru Thu Jan 7 17:03:38 2010 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Thu Jan 7 16:36:32 2010 Subject: [Haskell-cafe] Explicit garbage collection In-Reply-To: <7fb8f82f1001071353r63358486sefdcd46984e6332e@mail.gmail.com> References: <4B44958A.2080809@yandex.ru> <4B44A09C.8040103@yandex.ru> <7fb8f82f1001061221v40ffe0cby8c0e4b453e72d65d@mail.gmail.com> <7fb8f82f1001061928o4a58ac46qbaaf00691f26e304@mail.gmail.com> <7fb8f82f1001062101s44d45b59v83d176d12287243@mail.gmail.com> <7BB0709F-F74E-4181-BA49-D292193DABF9@yandex.ru> <693475F8-3C64-4EA1-839D-C7C1ED87FB01@yandex.ru> <7fb8f82f1001071207w63da732q168908d024bfaffd@mail.gmail.com> <5C491A8C-31E4-4D95-B773-014AD9AAE0FC@yandex.ru> <7fb8f82f1001071353r63358486sefdcd46984e6332e@mail.gmail.com> Message-ID: <8AD74D87-A416-42C9-BE91-AC79DFA0915D@yandex.ru> Hmm, interesting. Seems like I have to take a closer look at GHC's garbage collection. Thanks! On 8 Jan 2010, at 00:53, Edward Kmett wrote: > That is kind of what I thought you were doing. > > Retooling to see if we can get any better performance out of > collecting, it seems that System.Mem.PerformGC does a foreign call > out to performMajorGC to ask for a global collection. But I would > hazard that you might be able to get most of the benefit by just > asking for the nursery to be cleaned up. > > To that end, perhaps it would be worthwhile to consider switching to > something like: > > foreign import ccall {-safe-} "performGC" performMinorGC :: IO () > > -- System.Mem imports performMajorGC as 'performGC' but the minor > collection appears to be called performGC, hence the rename. > > This should let you call for a minor collection, which should be > considerably less time consuming. Especially as if you call it > frequently you'll be dealing with a mostly cleared nursery anyways. > > -Edward Kmett > > On Thu, Jan 7, 2010 at 4:39 PM, Miguel Mitrofanov > wrote: > I liked it too. Seems like I have to show some real code, and my > apologies for a long e-mail. > > Well, that's what I'm actually trying to do and what I've managed to > achieve so far. > > > module Ask where > > import Control.Monad > > import Data.IORef > > import Data.Maybe > > import System.IO.Unsafe -- Yes, I would need that > > import System.Mem > > import System.Mem.Weak > > Suppose we're writing a RESTful server, which keeps all state on the > client. We want it to send questions to the client and get back the > answers. We can also send some state data to the client and we are > sure that the client would return them back unchanged. So, that's > the type of our server: > > > type Server medium = Maybe (medium, String) -> IO (Maybe (medium, > String)) > > The client starts interaction, sending "Nothing"; when server > finally returns "Nothing", the session stops. I would emulate the > client in GHCi with the following function: > > > client :: Show medium => Bool -> Server medium -> IO () > > client debug server = client' Nothing where > > client' query = > > do response <- server query > > case response of > > Nothing -> return () > > Just (medium, question) -> > > do when debug $ putStr "Debug: " >> print medium > > putStrLn question > > putStr "--> " > > answer <- getLine > > client' $ Just (medium, answer) > > Nothing very interesting. The only thing to note is that the boolean > argument allows us to see the state sent by server - for debugging > purposes. > > But I want something more high-level. The goal is to solve the > Graham's "arc challenge". So the high-level interface is implemented > by this type: > > > data Ask a = Finish a | Continue String (String -> Ask a) > > A possible application would be: > > > test :: Ask () > > test = > > do s1 <- ask "Enter the first number" > > let n1 = read s1 > > s2 <- ask "Enter the second number" > > let n2 = read s2 > > ask $ show $ n1 + n2 > > return () > > Well, to do that, I need a Monad instance for Ask: > > > instance Monad Ask where > > return = Finish > > Finish x >>= h = h x > > Continue question k >>= h = Continue question $ \answer -> k > answer >>= h > > and an "ask" function: > > > ask :: String -> Ask String > > ask question = Continue question $ \answer -> return answer > > Now, the problem is with the route from high level to the low level. > We can do it relatively simply: > > > simpleServer :: Ask () -> Server [String] > > simpleServer anything = return . simpleServer' anything . maybe [] > (\(medium, answer) -> medium ++ [answer]) where > > simpleServer' (Finish ()) _ = Nothing > > simpleServer' (Continue question _) [] = Just ([], question) > > simpleServer' (Continue _ k) (s : ss) = > > do (medium, question) <- simpleServer' (k s) ss > > return (s : medium, question) > > And indeed, our test example works: > > *Ask> client False $ simpleServer test > Enter the first number > --> 3 > Enter the second number > --> 4 > 7 > --> > > But, as you've probably guessed already, this "simpleServer" sends > way too much information over network: > > > nonsense :: Ask () > > nonsense = > > do a <- ask "?" > > b <- ask a > > c <- ask b > > d <- ask c > > e <- ask b -- Note this "b" instead of "d", it's deliberate. > > return () > > *Ask> client True $ simpleServer nonsense > Debug: [] > ? > --> a > Debug: ["a"] > a > --> b > Debug: ["a","b"] > b > --> c > Debug: ["a","b","c"] > c > --> d > Debug: ["a","b","c","d"] > b > --> e > > All user answers from the very beginning get transmitted. > > I want to transmit only those answers that are actually used. I'm > gonna write another server, a (relatively) smart one. > > A simple boxing type: > > > data Box a = Box {unBox :: a} > > Now, the server. I use "Nothing" for those user answers that are no > longer needed. > > > smartServer :: Ask () -> Server [Maybe String] > > smartServer anything = smartServerIO anything . maybe [] (\ > (medium, answer) -> medium ++ [Just answer]) where > > smartServerIO anything query = > > Sometimes a value is not used anymore just because it WAS used > already. So I'll use a mutable list to keep track of those values > that are actually dereferenced: > > > do usedList <- newIORef [] > > Then, I'll make weak pointers for all user answers: > > > let boxedQuery = map Box query > > weakPtrs <- mapM (\box -> mkWeak box () Nothing) > boxedQuery > > and actually run my "Ask" value. > > > case findWeakPtrs 0 anything boxedQuery usedList of > > Finish () -> return Nothing > > Continue question rest -> > > Now, the interesting part. I'd invoke a garbage collector to get rid > of those boxes that aren't necessary anymore. > > > do performGC > > Now, weak pointers tell me what boxes are not dereferenced but can > be dereferenced in the future, and my mutable list has the numbers > of boxes that were dereferenced. > > > danglingNumbers <- mapM deRefWeak weakPtrs > > usedNumbers <- readIORef usedList > > I also need to keep this "future" alive, so that usable boxes don't > get garbage collected. > > > case rest undefined of _ -> return () > > And now all I need to do is to filter out those boxes that are not > in any of the two lists: > > > return $ Just (zipWith3 (isUsed usedNumbers) > [0..] danglingNumbers query, question) > > Helper function has an interesting detail: > > > findWeakPtrs _ (Finish ()) _ _ = Finish () > > findWeakPtrs _ response [] _ = response > > I use unsafePerformIO to track those boxes that get actually > dereferenced: > > > findWeakPtrs n (Continue _ k) (s : ss) usedList = > > findWeakPtrs (n+1) (k (unsafePerformIO $ modifyIORef > usedList (n :) >> return (fromJust $ unBox s))) ss usedList > > A filtering function is not very interesting: > > > isUsed usedNumbers index Nothing _ | not (index `elem` > usedNumbers) = Nothing > > isUsed _ _ _ answer = answer > > And it works: > > *Ask> client True $ smartServer nonsense > Debug: [] > ? > --> a > Debug: [Just "a"] > a > --> b > Debug: [Nothing,Just "b"] > b > --> c > Debug: [Nothing,Just "b",Just "c"] > c > --> d > Debug: [Nothing,Just "b",Nothing,Nothing] > b > --> e > > So, the problem is, I don't think calling performGC every time is a > good idea. I'd like to tell explicitly what values are to be garbage > collected. It doesn't seem like it's possible with current version > of GHC, though. > > > On 7 Jan 2010, at 23:07, Edward Kmett wrote: > > Thats a shame, I was rather fond of this monad. To get that last > 'True', you'll really have to rely on garbage collection to > approximate reachability for you, leaving the weak reference > solution the best you can hope for. > > -Edward Kmett > > On Thu, Jan 7, 2010 at 12:39 PM, Miguel Mitrofanov > wrote: > Damn. Seems like I really need (True, False, True) as a result of > "test". > > > On 7 Jan 2010, at 08:52, Miguel Mitrofanov wrote: > > Seems very nice. Thanks. > > On 7 Jan 2010, at 08:01, Edward Kmett wrote: > > Here is a slightly nicer version using the Codensity monad of STM. > > Thanks go to Andrea Vezzosi for figuring out an annoying hanging bug > I was having. > > -Edward Kmett > > {-# LANGUAGE Rank2Types, GeneralizedNewtypeDeriving, DeriveFunctor #-} > module STMOracle > ( Oracle, Ref > , newRef, readRef, writeRef, modifyRef, needRef > ) where > > import Control.Applicative > import Control.Monad > import Control.Concurrent.STM > > instance Applicative STM where > pure = return > (<*>) = ap > > newtype Ref s a = Ref (TVar (Maybe a)) > newtype Oracle s a = Oracle { unOracle :: forall r. (a -> STM r) -> > STM r } deriving (Functor) > > instance Monad (Oracle s) where > return x = Oracle (\k -> k x) > Oracle m >>= f = Oracle (\k -> m (\a -> unOracle (f a) k)) > > mkOracle m = Oracle (m >>=) > > runOracle :: (forall s. Oracle s a) -> IO a > runOracle t = atomically (unOracle t return) > > newRef :: a -> Oracle s (Ref s a) > newRef a = mkOracle $ Ref <$> newTVar (Just a) > > readRef :: Ref s a -> Oracle s a > readRef (Ref r) = mkOracle $ do > m <- readTVar r > maybe retry return m > > writeRef :: a -> Ref s a -> Oracle s a > writeRef a (Ref r) = mkOracle $ do > writeTVar r (Just a) > return a > > modifyRef :: (a -> a) -> Ref s a -> Oracle s a > modifyRef f r = do > a <- readRef r > writeRef (f a) r > > needRef :: Ref s a -> Oracle s Bool > needRef (Ref slot) = Oracle $ \k -> > (writeTVar slot Nothing >> k False) > `orElse` k True > > -- test > case > : refMaybe > b dflt ref = if b then readRef ref else return dflt > refIgnore ref = return "blablabla" > refFst ref = fst `fmap` readRef ref > test = do > a <- newRef "x" > b <- newRef 1 > c <- newRef ('z', Just 0) > -- no performLocalGC required > x <- needRef a > y <- needRef b > z <- needRef c > u <- refMaybe y "t" a -- note that it wouldn't actually read "a", > -- but it won't be known until runtime. > w <- refIgnore b > v <- refFst c > return (x, y, z) > > > > On Wed, Jan 6, 2010 at 10:28 PM, Edward Kmett > wrote: > I don't believe you can get quite the semantics you want. However, > you can get reasonably close, by building a manual store and > backtracking. > > {-# LANGUAGE Rank2Types #-} > -- lets define an Oracle that tracks whether or not you might need > the reference, by backtracking. > module Oracle > ( Oracle, Ref > , newRef, readRef, writeRef, modifyRef, needRef > ) where > > import Control.Applicative > import Control.Arrow (first) > import Control.Monad > import Data.IntMap (IntMap) > import qualified Data.IntMap as M > import Unsafe.Coerce (unsafeCoerce) > import GHC.Prim (Any) > > -- we need to track our own worlds, otherwise we'd have to build > over ST, change optimistically, and track how to backtrack the state > of the Store. Much uglier. > -- values are stored as 'Any's for safety, see GHC.Prim for a > discussion on the hazards of risking the storage of function types > using unsafeCoerce as anything else. > data World s = World { store :: !(IntMap Any), hwm :: !Int } > > -- references into our store > newtype Ref s a = Ref Int deriving (Eq) > > -- our monad that can 'see the future' ~ StateT (World s) []newtype > Oracle s a = Oracle { unOracle :: World s -> [(a, World s)] } > > -- we rely on the fact that the list is always non-empty for any > oracle you can run. we are only allowed to backtrack if we thought > we wouldn't need the reference, and wound up needing it, so head > will always succeed. > runOracle :: (forall s. Oracle s a) -> a > runOracle f = fst $ head $ unOracle f $ World M.empty 1 > > > instance Monad (Oracle s) where > return a = Oracle $ \w -> [(a,w)] > Oracle m >>= k = Oracle $ \s -> do > (a,s') <- m s > unOracle (k a) s' > > -- note: you cannot safely define fail here without risking a crash > in runOracle > -- Similarly, we're not a MonadPlus instance because we always want > to succeed eventually. > > instance Functor (Oracle s) where > fmap f (Oracle g) = Oracle $ \w -> first f <$> g w > > instance Applicative (Oracle s) where > pure = return > (<*>) = ap > > -- new ref allocates a fresh slot and inserts the value into the > store. the type level brand 's' keeps us safe, and we don't export > the Ref constructor. > newRef :: a -> Oracle s (Ref s a) > newRef a = Oracle $ \(World w t) -> > [(Ref t, World (M.insert t (unsafeCoerce a) w) (t + 1))] > > -- readRef is the only thing that ever backtracks, if we try to read > a reference we claimed we wouldn't need, then we backtrack to when > we decided we didn't need the reference, and continue with its value. > readRef :: Ref s a -> Oracle s a > readRef (Ref slot) = Oracle $ \world -> > maybe [] (\a -> [(unsafeCoerce a, world)]) $ M.lookup slot (store > world) > > -- note, writeRef dfoesn't 'need' the ref's current value, so > needRef will report False if you writeRef before you read it after > this. > writeRef :: a -> Ref s a -> Oracle s a > writeRef a (Ref slot) = Oracle $ \world -> > [(a, world { store = M.insert slot (unsafeCoerce a) $ store > world })] > > {- > -- alternate writeRef where writing 'needs' the ref. > writeRef :: a -> Ref s a -> Oracle s a > writeRef a (Ref slot) = Oracle $ \World store v -> do > (Just _, store') <- return $ updateLookupWithKey replace slot store > [(a, World store' v)] > where > replace _ _ = Just (unsafeCoerce a) > -} > > -- modifying a reference of course needs its current value. > modifyRef :: (a -> a) -> Ref s a -> Oracle s a > modifyRef f r = do > a <- readRef r > writeRef (f a) r > > -- needRef tries to continue executing the world without the element > in the store in question. if that fails, then we'll backtrack to > here, and try again with the original world, and report that the > element was in fact needed. > needRef :: Ref s a -> Oracle s Bool > needRef (Ref slot) = Oracle $ \world -> > [ (False, world { store = M.delete slot $ store world }) > , (True, world) > ] > > -- test case: > refMaybe b dflt ref = if b then readRef ref else return dflt > refIgnore ref = return "blablabla" > refFst ref = fst <$> readRef ref > test = do > a <- newRef "x" > b <- newRef 1 > c <- newRef ('z', Just 0) > -- no performLocalGC required > x <- needRef a > y <- needRef b > z <- needRef c > u <- refMaybe y "t" a -- note that it wouldn't actually read "a", > -- but it won't be known until runtime. > w <- refIgnore b > v <- refFst c > return (x, y, z) > > -- This will disagree with your desired answer, returning: > > *Oracle> runOracle test > Loading package syb ... linking ... done. > Loading package array-0.2.0.0 ... linking ... done. > Loading package containers-0.2.0.1 ... linking ... done. > (False,False,True) > > rather than (True, False, True), because the oracle is able to see > into the future (via backtracking) to see that refMaybe doesn't use > the reference after all. > > This probably won't suit your needs, but it was a fun little exercise. > > -Edward Kmett > > On Wed, Jan 6, 2010 at 4:05 PM, Miguel Mitrofanov > wrote: > > On 6 Jan 2010, at 23:21, Edward Kmett wrote: > > You probably just want to hold onto weak references for your > 'isStillNeeded' checks. > > That's what I do now. But I want to minimize the network traffic, so > I want referenced values to be garbage collected as soon as possible > - and I couldn't find anything except System.Mem.performIO to do the > job - which is a bit too global for me. > > Otherwise the isStillNeeded check itself will keep you from garbage > collecting! > > Not necessary. What I'm imagining is that there is essentially only > one way to access the value stored in the reference - with readRef. > So, if there isn't any chance that readRef would be called, the > value can be garbage collected; "isStillNeeded" function only needs > the reference, not the value. > > Well, yeah, that's kinda like weak references. > > > http://cvs.haskell.org/Hugs/pages/libraries/base/System-Mem-Weak.html > > -Edward Kmett > > On Wed, Jan 6, 2010 at 9:39 AM, Miguel Mitrofanov > wrote: > I'll take a look at them. > > I want something like this: > > refMaybe b dflt ref = if b then readRef ref else return dflt > refIgnore ref = return "blablabla" > refFst ref = > do > (v, w) <- readRef ref > return v > test = > do > a <- newRef "x" > b <- newRef 1 > c <- newRef ('z', Just 0) > performLocalGC -- if necessary > x <- isStillNeeded a > y <- isStillNeeded b > z <- isStillNeeded c > u <- refMaybe y "t" a -- note that it wouldn't actually read "a", > -- but it won't be known until runtime. > w <- refIgnore b > v <- refFst c > return (x, y, z) > > so that "run test" returns (True, False, True). > > > Dan Doel wrote: > On Wednesday 06 January 2010 8:52:10 am Miguel Mitrofanov wrote: > Is there any kind of "ST" monad that allows to know if some STRef is > no > longer needed? > > The problem is, I want to send some data to an external storage over a > network and get it back later, but I don't want to send unnecessary > data. > > I've managed to do something like that with weak pointers, > System.Mem.performGC and unsafePerformIO, but it seems to me that > invoking > GC every time is an overkill. > > Oh, and I'm ready to trade the purity of runST for that, if necessary. > > You may be able to use something like Oleg's Lightweight Monadic > Regions to get this effect. I suppose it depends somewhat on what > qualifies a reference as "no longer needed". > > http://www.cs.rutgers.edu/~ccshan/capability/region-io.pdf > > I'm not aware of anything out-of-the-box that does what you want, > though. > > -- Dan > _______________________________________________ > 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 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 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 mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From felipe.lessa at gmail.com Thu Jan 7 21:03:45 2010 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Thu Jan 7 20:36:39 2010 Subject: [Haskell-cafe] ANNOUNCE: New versions of ALL the monadic regions packages In-Reply-To: References: <20100107161545.GA23610@kira.casa> Message-ID: <20100108020345.GA6759@kira.casa> On Thu, Jan 07, 2010 at 08:39:59PM +0100, Bas van Dijk wrote: > Another solution might be to encode the resources that a region opens > as constraints. I think 'control-monad-exception' uses a similar > technique to encode all the exceptions that a monadic computation may > throw. Yes, yes, that's what I had in mind, thanks for bringing it up. Although it isn't exatcly beautiful, GHC can infer the types and it works. > My previous program could then possibly be written as something like: > > openBoth ? ( resources `Contains` Device > , resources `Contains` File > ) > ? Device ? FilePath ? RegionT resources pr () > openBoth usbDevice filePath = do > h1 ? open usbDevice > h2 ? openFile filePath ReadMode > return () I just don't see yet (maybe because I'm not well versed in monadic regions) how runRegionT will work. When working with exceptions, I have to provide a datatype that implements all the type classes I've used in my program. Hmmm... Perhaps an internal data type that is exposed and other modules instantiate? Cheers, -- Felipe. From twb at cybersource.com.au Thu Jan 7 21:43:22 2010 From: twb at cybersource.com.au (Trent W. Buck) Date: Thu Jan 7 21:16:46 2010 Subject: [Haskell-cafe] Re: darcs 2.4 beta 1 release References: <201001051918.38069.tux_rocker@reinier.de> <87fx6j8hpt.fsf@gmail.com> <16442B752A06A74AB4D9F9A5FF076E4B03B9FE4D@ELON17P32001A.csfb.cs-group.com> <87bph64dgs.fsf@gmail.com> Message-ID: <30ljg9qpth.fsf@cybersource.com.au> Ivan Lazar Miljenovic writes: > I consider it "show-stopping" in the sense that I keep having people > on #gentoo-haskell asking me why they can't compile darcs 2.3.1 > because that error comes up, and I have to explain to either disable > documentation or downgrade Cabal (if they're still using References: <201001051918.38069.tux_rocker@reinier.de> Message-ID: <27070775.post@talk.nabble.com> Both darcs and xmonad are only great product i know! thanks! Reinier Lamers-2 wrote: > > Hi all, > > The darcs team would like to announce the immediate availability of darcs > 2.4 > beta 1. darcs 2.4 will contain many improvements and bugfixes compared to > darcs 2.3.1. Highlights are the fast index-based diffing which is now used > by > all darcs commands, and the interactive hunk-splitting in darcs record. > This > beta is your chance to test-drive these improvements and make darcs even > better. > > If you have installed the Haskell Platform or cabal-install, you can > install > this beta release by doing: > > $ cabal update > $ cabal install --reinstall darcs-beta > > Alternatively, you can download the tarball from > http://darcs.net/releases/darcs-2.3.98.1.tar.gz , and build it by hand as > explained in the README file. > > A list of important changes since 2.3.1 is as follows (please let me know > if > there's something you miss!): > > * Use fast index-based diffing everywhere (Petr) > * Interactive patch splitting (Ganesh) > * An 'optimize --upgrade' option to convert to hashed format in-place > (Eric) > * Hunk matching (Kamil Dworakowski, tat.wright) > * Progress reporting is no longer deceptive (Roman Pl??il) > * A 'remove --recursive' option to remove a directory tree from > revision > control (Roman Pl??il) > * A '--remote-darcs' flag for pushing to a host where darcs isn't > called > darcs > * Many miscellaneous Windows improvements (Salvatore, Petr and others) > * 'darcs send' now mentions the repository name in the email body > (Joachim) > * Handle files with boring names in the repository correctly (Petr) > * Fix parsing of .authorspellings file (Tom?? Caitt) > * Various sane new command-line option names (Florent) > * Remove the '--checkpoint' option (Petr) > * Use external libraries for all UTF-8 handling (Eric, Reinier) > * Use the Haskell zlib package exclusively for compression (Petr) > > Kind Regards, > the darcs release manager, > Reinier Lamers > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > ----- fac n = foldr (*) 1 [1..n] -- View this message in context: http://old.nabble.com/darcs-2.4-beta-1-release-tp27033177p27070775.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From ivan.miljenovic at gmail.com Thu Jan 7 23:38:30 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Thu Jan 7 23:11:26 2010 Subject: [Haskell-cafe] Re: darcs 2.4 beta 1 release In-Reply-To: <30ljg9qpth.fsf@cybersource.com.au> (Trent W. Buck's message of "Fri, 08 Jan 2010 13:43:22 +1100") References: <201001051918.38069.tux_rocker@reinier.de> <87fx6j8hpt.fsf@gmail.com> <16442B752A06A74AB4D9F9A5FF076E4B03B9FE4D@ELON17P32001A.csfb.cs-group.com> <87bph64dgs.fsf@gmail.com> <30ljg9qpth.fsf@cybersource.com.au> Message-ID: <87k4vt2ou1.fsf@gmail.com> twb@cybersource.com.au (Trent W. Buck) writes: > Does Gentoo's cabal set "documentation: True" by default? On Debian, > "cabal install foo" will not build documentation; it's only when > building a .deb with CDBS that documentation is built. No, but a lot of people have USE=doc which builds the haddock documentation (and USE=hscolour then uses hscolour for prettified source links from haddock docs). > Do / should our buildbots set "documentation: True" in .cabal/config? For testing purposes? Yes, I think they should. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From ck_kashyap at yahoo.com Thu Jan 7 23:48:57 2010 From: ck_kashyap at yahoo.com (CK Kashyap) Date: Thu Jan 7 23:21:48 2010 Subject: [Haskell-cafe] Review request for my permutations implementation In-Reply-To: <201001071146.33695.daniel.is.fischer@web.de> References: <121533.40261.qm@web112506.mail.gq1.yahoo.com> <201001071146.33695.daniel.is.fischer@web.de> Message-ID: <496994.72303.qm@web112507.mail.gq1.yahoo.com> Thanks everyone, Thanks Daniel for this really detailed explanation - thank you very much. Regards, Kashyap > >From: Daniel Fischer >To: haskell-cafe@haskell.org >Cc: CK Kashyap >Sent: Thu, January 7, 2010 4:16:33 PM >Subject: Re: [Haskell-cafe] Review request for my permutations implementation > > >Am Donnerstag 07 Januar 2010 09:37:42 schrieb CK Kashyap: >> Hi All, >> >> I've written this piece of code to do permutations - >> >> perms :: String -> [String] >Nothing in the algorithm needs the list elements to be Chars, there's no type class involved, so it should be >perms :: [a] -> [[a]] >> perms []= [] >This should actually be >perms [] = [[]] >> perms (x:[])= [[x]] >That is then superfluous. >> perms (x:xs)= concat (f [x] (perms xs)) >> >'f' is a good name for a function parameter, not for a top level binding. >Why not >perms (x:xs) = concat (map (spread [x]) (perms xs)) >whcih you can reformulate as >perms (x:xs) = concatMap (spread [x]) (perms xs) >or, if you like Monads, since concatMap is just the bind operator of the []-monad, >perms (x:xs) = perms xs >>= spread [x] >Which can be written as a simple do-block: >perms (x:xs) = do >prm <- perms xs >spread [x] prm >or a list-comprehension >perms (x:xs) = [permutation | tailPerm <- perms xs, permutation <- spread [x] tailPerm] >> spread :: String -> String -> [String] -- interpolate first string at >> various positions of second string spread str1 str2 = _spread str1 str2 >> (length str2) >> where >> _spread str1 str2 0= [str1 ++ str2] >> _spread str1 str2 n= [(take n str2) ++ str1 ++ (drop n str2)] ++ (_spread >> str1 str2 (n-1)) >> >import Data.List >spread short long = zipWith (\a b -> a ++ short ++ b) (inits long) (tails long) >If you only use spread for perms, you never interpolate anything but single element lists, so you might consider >spread' :: a -> [a] -> [[a]] >spread' x xs = zipWith (\a b -> a ++ x:b) (inits xs) (tails xs) >But if you import Data.List, you could also say >perms = permutations >and be done with it :) (except if you 1. need the permutations in a particular order, which is different from the one Data.List.permutations generates, or 2. you need it to be as fast as possible - Data.List.permutations was written to also cope with infinite lists, so a few things that could speed up generation of permutations for short lists couldn't be used). >> f xs = map (spread xs) >> >> >> The number of outcomes seem to indicate that correctness of the algo .. >Apart from the case of empty input, it is correct. >> however, I'd be very obliged if I could get some feedback on the >> Haskellness etc of this ... also any performance pointers ... >Re performance: >I think the repeated (take k) and (drop k) in your spread are likely to be slower than using inits and tails, but it would need measuring the performance to be sure. >I don't see anything that would automatically give bad performance. >But there's the question of repeated elements. >perms "aaaaabbbbb" >spills out 3628800 permutations, but there are only 252 distinct permutations, each of them appearing 120^2 = 14400 times. >If your input may contain repeated elements and you're >1. only interested in the distinct permutations (and 2.) or >2. don't care about the order in which the permutations are generated, >distinctPerms :: Ord a => [a] -> [[a]] >distinctPerms = foldr inserts [[]] . group . sort >inserts :: [a] -> [[a]] -> [[a]] >inserts xs yss = yss >>= (mingle xs) >mingle :: [a] -> [a] -> [[a]] >mingle xs [] = [xs] >mingle [] ys = [ys] >mingle xxs@(x:xs) yys@(y:ys) >= [x:zs | zs <- mingle xs yys] ++ [y:zs | zs <- mingle xxs ys] >generates the distinct permutations much faster if there are many repeated elements; >if you want each distinct permutation repeated the appropriate number of times, the modification is easy. >> >> >> Regards, >> Kashyap -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100107/c7e256e8/attachment.html From allbery at ece.cmu.edu Fri Jan 8 00:03:51 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Thu Jan 7 23:36:47 2010 Subject: [Haskell-cafe] Re: ANNOUNCE: New versions of ALL the monadic regions packages In-Reply-To: References: <1188500262.20100107191816@gmail.com> Message-ID: On Jan 7, 2010, at 14:44 , Bas van Dijk wrote: > On Thu, Jan 7, 2010 at 5:18 PM, Bulat Ziganshin > wrote: >> Thursday, January 7, 2010, 6:25:34 PM, you wrote: >>> So now I'm confused... are these standard file handles always open >>> on >>> program startup or are there abnormal situations when they are >>> closed? >> >> afaik, parent process may close them before executing your program, >> it's used in particular for running daemons > > Thanks Bulat for explaining. POSIX actually discourages that, because it's so common for library routines to assume they can write error messages to stderr; the approved way to handle daemons is to open the standard file handles on /dev/null, *not* to close them. There are systems that violate this, however (the most "fun" one I've encountered is Applications menu commands in Mac OS X 10.4's X11.app; bash partially works around it, but not entirely). So the correct thing to do is to check if they are open on startup, and if not open /dev/null. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100107/bd4e7cf6/PGP.bin From jason.dusek at gmail.com Fri Jan 8 00:09:33 2010 From: jason.dusek at gmail.com (Jason Dusek) Date: Thu Jan 7 23:42:24 2010 Subject: [Haskell-cafe] ANNOUNCE: system-uuid-1.2.0 Message-ID: <42784f261001072109x710e85md1cc511d568fa0fb@mail.gmail.com> Patched by Antoine S. Latter to interoperate with UUID. http://hackage.haskell.org/package/system-uuid-1.2.0 -- Jason Dusek From leepike at gmail.com Fri Jan 8 00:36:43 2010 From: leepike at gmail.com (Lee Pike) Date: Fri Jan 8 00:10:07 2010 Subject: [Haskell-cafe] Testing for statistical properties Message-ID: Greg, > Hey everyone! I have some computations that satisfy statistical > properties which I would like to test --- that is, the result of the > computation is non-deterministic, but I want to check that it is > sampling the distribution that it should be sampling. Is anyone > aware of a Haskell library out there that does anything like this? I don't know of a library, but here are a couple of ideas/pointers: I wanted to do something vaguely similar in the realm of real-time hardware testing. I used QuickCheck (QC) to do some stochastic testing (in my case, generate test cases from the reals satisfying somewhat complex constraints), and I have a small patch to the QC library to make this possible. I have a short '09 Haskell Symposium paper about it (probably Sec. 5 is the most interesting). The paper and patch are here: . One caveat though is that I didn't check that the tests generated by QC satisfied any particular distribution---I was assuming it is roughly uniformly distributed. Also, I didn't investigate how to generate other distributions, but I don't think that'd be too hard. FYI, Bryan O'Sullivan has a statistics library , which I plan to use myself soon! I'm personally interested in how things turn out for you---please keep me posted. Lee From cetin.sert at gmail.com Fri Jan 8 04:36:32 2010 From: cetin.sert at gmail.com (Cetin Sert) Date: Fri Jan 8 04:09:44 2010 Subject: [Haskell-cafe] Upgrading Arch Linux Haskell Packages Message-ID: <1ff5dedc1001080136oa4a2flcbbd5f1306e541dc@mail.gmail.com> Hi, Is there a way to manually upgrade Haskell packages in the aur repository of Arch Linux which were previously contributed automatically by arch-haskell? Or is there a batch upgrade planned for the near future? What is the mailing list for arch Best Regards, Cetin -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100108/150d6534/attachment.html From dons at galois.com Fri Jan 8 04:44:38 2010 From: dons at galois.com (Don Stewart) Date: Fri Jan 8 04:17:30 2010 Subject: [Haskell-cafe] Re: [arch-haskell] Upgrading Arch Linux Haskell Packages In-Reply-To: <1ff5dedc1001080136oa4a2flcbbd5f1306e541dc@mail.gmail.com> References: <1ff5dedc1001080136oa4a2flcbbd5f1306e541dc@mail.gmail.com> Message-ID: <20100108094438.GA25223@whirlpool.galois.com> cetin.sert: > Hi, > > Is there a way to manually upgrade Haskell packages in the aur repository of > Arch Linux which were previously contributed automatically by arch-haskell? > Or is there a batch upgrade planned for the near future? > What is the mailing list for arch There's a batch upgrade, I've just been travelling! From ivan.miljenovic at gmail.com Fri Jan 8 05:08:31 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Fri Jan 8 04:41:26 2010 Subject: [Haskell-cafe] Re: [arch-haskell] Upgrading Arch Linux Haskell Packages In-Reply-To: <20100108094438.GA25223@whirlpool.galois.com> (Don Stewart's message of "Fri, 8 Jan 2010 01:44:38 -0800") References: <1ff5dedc1001080136oa4a2flcbbd5f1306e541dc@mail.gmail.com> <20100108094438.GA25223@whirlpool.galois.com> Message-ID: <877hrs3o4g.fsf@gmail.com> Don Stewart writes: > There's a batch upgrade, I've just been travelling! Yeah, let Don have a break for once! Oh, since you're here Don, how do I do ....... ? ;-) -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From tanielsen at gmail.com Fri Jan 8 05:59:11 2010 From: tanielsen at gmail.com (Tom Nielsen) Date: Fri Jan 8 05:32:20 2010 Subject: [Haskell-cafe] Testing for statistical properties In-Reply-To: References: Message-ID: <78dc001e1001080259k627f9b66p35bf3934edf64772@mail.gmail.com> Hi Greg, Assuming this is a one-dimensional distribtution, you should use a kolmogorov-smirnov test to test this: http://en.wikipedia.org/wiki/Kolmogorov-Smirnov_test I've implemented to the KS distribution from the CERN code linked in the wikipedia article, here: http://github.com/glutamate/samfun/blob/master/Math/Probably/KS.hs (warning, i wasn't able to verify the numbers coming out against anything so just check that it makes sense) So all you have to do is to find the maximal distance between your samples and the cumulative density function, multiply by the sqrt. of of the number of samples, and calculate kprob on that. I don't think you can do this in a Bayesian way because you can't enumerate all the other distributions your samples could come from? Tom On Thu, Jan 7, 2010 at 9:31 PM, Gregory Crosswhite wrote: > Hey everyone! ?I have some computations that satisfy statistical properties which I would like to test --- that is, the result of the computation is non-deterministic, but I want to check that it is sampling the distribution that it should be sampling. ?Is anyone aware of a Haskell library out there that does anything like this? > > Cheers, > Greg > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From kitaev at iqi.caltech.edu Fri Jan 8 06:04:06 2010 From: kitaev at iqi.caltech.edu (Alexei Kitaev) Date: Fri Jan 8 05:37:14 2010 Subject: [Haskell-cafe] space leaks and optimizations Message-ID: <4B471126.4010807@iqi.caltech.edu> Dear Haskellers, Recently I have been looking for a programming language that would be suitable for small scientific and recreational projects and palatable to a picky person like me. (I do theoretical physics and some math; I do not program very often.) Haskell and Clean look attractive from a mathematician's point of view and allow for very elegant solutions in some cases. I tried Clean first because it has a more efficient implementation and better array support. However, I am leaning toward Haskell since it has more libraries, larger community, and some nice features (e.g., the "do" notation). I thought it would be easier to avoid errors when programming in a pure functional language. Indeed, the Haskell type system is great and catches many errors. But in practice, I found it very difficult to write correct programs in Haskell! This is because my definition of correctness includes asymptotic complexity (time and space). I have pondered why Haskell is so prone to space leaks and whether this can be fixed. I posted a related message (describing a space leak caused by inlining) to Glasgow-haskell-users, http://www.haskell.org/pipermail/glasgow-haskell-users/2009-November/018063.html but apparently the GHC developers were busy preparing a new release. Perhaps on Haskell-cafe there are more people with some spare time; I would really appreciate your comments. So, there seem to be several reasons why controlling space usage is difficult: 1) The operational semantics of Haskell is not specified. That said, it seems that unoptimized programs behave in a predictable way if you follow the execution step by step. The Clean report explicitly says that the execution model is graph reduction; I believe that Haskell uses the same model. However, there are some subtleties, e.g., the tail call and selector optimizations. (I read about the selector optimization in Wadler's paper, http://homepages.inf.ed.ac.uk/wadler/topics/garbage-collection.html and saw it mentioned on the GHC development page. It's really nice and indispensable, but it seems to be missing from the user documentation. Is this the following description accurate? After the rhs of a lazy pattern like (a,b) = expression has been evaluated, the pattern does not take up any space, and the space occupied by a and b can be reclaimed independently.) There must be more subtleties. I imagine that a rigorous definition of operational semantics would be too complicated and impractical. But maybe an informal specification is better than nothing? Why people have not attempted to write it? 2) While each step is predictable, the overall behavior of a lazy program can be rather surprising. So one must be very careful. GHC provides two ways to control the evaluation order, seq and bang patterns, but I am not sure which of these (if any) is the right tool. Consider the following example (from the Real World Haskell book): mean :: [Double] -> Double mean xs = sum / fromIntegral num where (num,sum) = foldl' f (0,0) xs :: (Int, Double) f (n,s) x = (n+1, s+x) Although it uses foldl', there is a space leak because Haskell tuples are not strict. There are two possible fixes: f (!n,!s) x = (n+1, s+x) or f (n,s) x = let n1=n+1; s1=s+x in n1 `seq` s1 `seq` (n1,s1) The first one is short, but less natural than the second one, where the offending thunks are suppressed on the spot. Unfortunately, the syntax is awkward; it would be nice to write something like f (n,s) x = (!n+1, !n+1) Well, I am becoming too grumpy, perhaps the bang patterns are fine. More important question: are there established practices to *avoid* space leaks rather than fixing them afterwards? 3) The standard library was not designed with space efficiency in mind; for example, there is sum but no sum'. 4) GHC does a pretty good job optimizing programs for speed, but compiling with the -O option can easily introduce a space leak. I have not encountered such problems with Clean, though my experience is very limited. Apparently, the Clean developers have disallowed some unsafe optimization, see e.g., this message: http://mailman.science.ru.nl/pipermail/clean-list/2009/004140.html I doubt that the Clean solution is 100% reliable because the compiler still uses strictness analysis, which can change the asymptotic space usage (usually for better, but sometimes for worse). So I wonder whether it would be feasible to identify a set of conservative optimizations that do not change the space or time usage more than by a constant factor. For example, the strictness analysis could be limited to fixed-size data. Or instead of strictness analysis, one could inline the top-level patterns of every function. Of course, that would make the optimization less efficient on the average, but predictability is more important. Best regards, Alexei From jaspervdj at gmail.com Fri Jan 8 07:44:54 2010 From: jaspervdj at gmail.com (Jasper Van der Jeugt) Date: Fri Jan 8 07:18:04 2010 Subject: [Haskell-cafe] ANN: hakyll-0.4 Message-ID: Hello, I am announcing the release of hakyll-0.4. Hakyll is a static site generator library written Haskell. It is written in a very configurable way and uses an xmonad-like DSL for configuration. Notable changes since the last big release (0.1) include: - CSS compression - Dependency handling (aka. not generate everything again every time) - A simple http server for previewing your site - Speed improvements and bug fixes - Several specialized functions for dealing with dates, tags... - Abstraction of context manipulations - Some tutorials are added and documentation is mostly complete - Example sites were added More information can be found at http://jaspervdj.be/hakyll All feedback is welcome. Kind regards, Jasper Van der Jeugt -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100108/98409039/attachment.html From sebf at informatik.uni-kiel.de Fri Jan 8 07:53:53 2010 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Fri Jan 8 07:26:43 2010 Subject: [Haskell-cafe] Typed Configuration Files Message-ID: <0102AD94-4A7C-47F0-A412-748FF4850448@informatik.uni-kiel.de> Dear Caf?, Neil Mitchell's cmdargs package [1] is pretty neat. It can be used to parse command-line arguments into a user-defined data structure. Is there something similar for parsing config files? There are a number of config file parsers on Hackage. But even the most sophisticated one I found, ConfigFile by John Goerzen [2], only yields primitive data like strings, booleans, and numbers. Did I overlook something? I'd like to write something like do fc <- configFile ... ac <- cmdArgs ... let conf = fc `mappend` ac where the type of `conf` is a user defined monoid. I found that the fez-conf package [3] provides a function `parseToArgs` which creates a list similar to the one returned by `System.getArgs` from a config file. Neil, if you would add a function to your cmdargs package that allows to specify the argument list, then one could reuse your machinery to create typed config data from config files too, right? Maybe along the lines of do args <- parseToArgs <$> readFile "/my/conf" conf <- cmdArgsWithDefault args "My Program" [myMode] The new function `cmdArgsWithDefault` could require the return type to be a monoid in order to allow users to specify themselves how to deal with multiple options of the same kind. Would that be reasonable or is there a better alternative? Cheers, Sebastian [1] http://hackage.haskell.org/package/cmdargs [2] http://hackage.haskell.org/package/ConfigFile [3] http://hackage.haskell.org/package/fez-conf -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From ivan.miljenovic at gmail.com Fri Jan 8 09:08:01 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Fri Jan 8 08:40:57 2010 Subject: [Haskell-cafe] ANNOUNCE: SourceGraph-0.6.0.0 and Graphalyze-0.9.0.0 Message-ID: <87y6k81ygu.fsf@gmail.com> I'm pleased to announce the latest releases of SourceGraph [1] and Graphalyze [2]. [1]: http://hackage.haskell.org/package/SourceGraph [2]: http://hackage.haskell.org/package/Graphalyze SourceGraph is a program that performs static code analysis on Haskell projects on the by applying graph theoretic techniques to the project's call graph. Graphalyze is a library for analysing discrete data using graph theory, and as such performs the heavy lifting for SourceGraph. Sample analysis reports generated by SourceGraph are available at http://code.haskell.org/~ivanm/Sample_SourceGraph/SampleReports.html . I will also be demoing SourceGraph at PEPM [3] in Madrid on 19 January. [3]: http://www.program-transformation.org/PEPM10/ Changes since the previous version include: * Now supports "implicitly exported" entities (as requested by Curt Sampson). This includes instantiated class methods from other modules and functions, etc. that start with an underscore (see http://www.haskell.org/ghc/docs/latest/html/users_guide/options-sanity.html for more information). * All inaccessible entities are now reported, not just those that were root nodes in the call graph. * Edges are now colour-coded based upon whether they are part of a clique, cycle or a chain. * Level-based analyses: visualise how deep an entity is from those exported entities. * A re-done TODO that lists in detail what is planned for SourceGraph. * Lots of under-the-hood changes that don't sound as interesting as the above :-( -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From mblazevic at stilo.com Fri Jan 8 09:26:06 2010 From: mblazevic at stilo.com (Mario Blazevic) Date: Fri Jan 8 08:58:57 2010 Subject: [Haskell-cafe] Splitting a Hackage project (was ANN: Streaming Component Combinators 0.4) In-Reply-To: <.1262910550@magma.ca> References: <.1262910550@magma.ca> Message-ID: <4B47407E.40702@stilo.com> I couldn't find any Hackage policy guideline on the appropriate balance between the package list size and package size, so I'll just ask the question. I have released the version 0.4 of my SCC package yesterday. In this particular release, there is at least one module that's nicely self-contained, providing useful functionality of its own, and not expected to evolve much: http://hackage.haskell.org/packages/archive/scc/0.4/doc/html/Control-Concurrent-Coroutine.html My question then is if I should split this module into a separate package or leave it where it is? If I split it out, what should I do about the ParallelizableMonad class in the module? > class Monad m => ParallelizableMonad m where > bindM2 :: (a -> b -> m c) -> m a -> m b -> m c This class and its instances would again be something *usable* both outside the SCC package and outside the Control.Concurrent.Coroutine module. But would they be *useful* and would they be *used*? Should I split the class out into a Control.ParallelizableMonad package? I'm sure I'm not the only one with the same dilemma. It would be nice to have some written rules to follow on what belongs on Hackage as a separate package. > Version 0.4 of Streaming Component Combinators, or SCC for short, has > been released on Hackage. Get it at > > http://hackage.haskell.org/package/scc > > There isn't much new high-level functionality compared to the > previous version, but the implementation has been heavily refactored and > the foundations completely replaced. > > I'm particularly happy to have found a way to drop the ugly reliance > on Data.Dynamic and to encode the required constraints in the type > system instead. The foundation of streaming components in this version > is the new Control.Concurrent.Coroutine module, whose main export is the monad > transformer Coroutine. It can transform any monad into a suspendable, resumable, > trampoline-style-runnable monad. Coroutines can be nested, which was the > requirement for streaming and the main stumbling block for the implementation. > The solution, worth at least 10 milliOlegs according to my estimate, was to > parameterize the Coroutine with a functor that wraps the coroutine suspension, > and to use nested functors for suspension from nested coroutines. The type system > automatically figures out how many wrappings to apply to each suspension > depending on how many intermediate coroutines it suspends. > > In other news is the project's Wiki page at > http://trac.haskell.org/SCC/wiki/. It's still rudimentary, but growing. > > All feedback will be appreciated. > > > _______________________________________________ > Haskell mailing list > Haskell@haskell.org > http://www.haskell.org/mailman/listinfo/haskell > From ivan.miljenovic at gmail.com Fri Jan 8 09:29:41 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Fri Jan 8 09:02:34 2010 Subject: [Haskell-cafe] ANNOUNCE: SourceGraph-0.6.0.1 In-Reply-To: <87y6k81ygu.fsf@gmail.com> (Ivan Lazar Miljenovic's message of "Sat, 09 Jan 2010 00:08:01 +1000") References: <87y6k81ygu.fsf@gmail.com> Message-ID: <87tyuw1xgq.fsf@gmail.com> I realised soon after I sent the announcement email that there was a bug in one of the new "subtle" features that I didn't list, namely the background shading of directories in import visualisation. As such, SourceGraph 0.6.0.1 contains this fix. There were also two other features in 0.6.0.0 that I forgot to mention: * SourceGraph will (well, should; I haven't managed to come across a situation where it occurs anyway) no longer throw a fit if Graphviz throws an error when visualising a graph; instead it will just put an error message into the generated report. * The generated Dot code is also saved in the SourceGraph/graphs/ subdirectory, so you can tweak the call graphs of your programs. Ivan Lazar Miljenovic writes: > I'm pleased to announce the latest releases of SourceGraph [1] and > Graphalyze [2]. > > [1]: http://hackage.haskell.org/package/SourceGraph > [2]: http://hackage.haskell.org/package/Graphalyze > > SourceGraph is a program that performs static code analysis on Haskell > projects on the by applying graph theoretic techniques to the project's > call graph. Graphalyze is a library for analysing discrete data using > graph theory, and as such performs the heavy lifting for SourceGraph. > > Sample analysis reports generated by SourceGraph are available at > http://code.haskell.org/~ivanm/Sample_SourceGraph/SampleReports.html . > I will also be demoing SourceGraph at PEPM [3] in Madrid on 19 January. > > [3]: http://www.program-transformation.org/PEPM10/ > > Changes since the previous version include: > > * Now supports "implicitly exported" entities (as requested by Curt > Sampson). This includes instantiated class methods from other > modules and functions, etc. that start with an underscore (see > http://www.haskell.org/ghc/docs/latest/html/users_guide/options-sanity.html > for more information). > > * All inaccessible entities are now reported, not just those that were > root nodes in the call graph. > > * Edges are now colour-coded based upon whether they are part of a > clique, cycle or a chain. > > * Level-based analyses: visualise how deep an entity is from those > exported entities. > > * A re-done TODO that lists in detail what is planned for SourceGraph. > > * Lots of under-the-hood changes that don't sound as interesting as the > above :-( -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From leimy2k at gmail.com Fri Jan 8 10:17:58 2010 From: leimy2k at gmail.com (David Leimbach) Date: Fri Jan 8 09:50:51 2010 Subject: [Haskell-cafe] space leaks and optimizations In-Reply-To: <4B471126.4010807@iqi.caltech.edu> References: <4B471126.4010807@iqi.caltech.edu> Message-ID: <3e1162e61001080717i25e54a1bl16c983d0e8ebc68d@mail.gmail.com> > > > 2) While each step is predictable, the overall behavior of a lazy > program can be rather surprising. So one must be very careful. GHC > provides two ways to control the evaluation order, seq and bang > patterns, but I am not sure which of these (if any) is the right tool. > Consider the following example (from the Real World Haskell book): > mean :: [Double] -> Double > mean xs = sum / fromIntegral num where > (num,sum) = foldl' f (0,0) xs :: (Int, Double) > f (n,s) x = (n+1, s+x) > Although it uses foldl', there is a space leak because Haskell tuples > are not strict. There are two possible fixes: > f (!n,!s) x = (n+1, s+x) > or > f (n,s) x = let n1=n+1; s1=s+x in n1 `seq` s1 `seq` (n1,s1) > The first one is short, but less natural than the second one, where the > offending thunks are suppressed on the spot. Unfortunately, the syntax > is awkward; it would be nice to write something like > f (n,s) x = (!n+1, !n+1) > Well, I am becoming too grumpy, perhaps the bang patterns are fine. More > important question: are there established practices to *avoid* space > leaks rather than fixing them afterwards? > > I believe the expectation is to learn to not be surprised in the areas where lazy or non-strict evaluation can be overused, and to learn all the advantages of non-strict evaluation vs strict, and the power it gives, such that an imperative programmer doesn't feel surprised or angry when things go wrong. I blogged about writing a long running service in Haskell that ran into problems with the lazy State monad, and lazy Data.Map, and I discussed how I had to force evaluations of everything to get the program under control. This wasn't for a hobby, this was for a production system. I believe I've a much better handle on strict vs non-strict than when I started the project, but I felt pretty lost for a while in the process of doing it. I was even using the Maybe monad with it's MonadPlus implementation to avoid using case statements around deconstruction, which I'm sure exacerbated some of my problem. However, since Haskell will evaluate the outer-most stuff first, the trick seems to be to find the point at which you *really* need the values computed, then tell Haskell to get on with it. You kind of have to have an explicit sequence point where all things need to be resolved, and you have to be able to see those in your code. Sometimes you can get away with only doing small pieces at a time. I had about the worst situation I've ever seen for data growth in my code. I had a pile of non-strict expressions, that were all dependencies for the next, running forever, and never getting evaluated except at asynchronous and user-controlled moments. If these expressions had been evaluated strictly, they would have taken up constant space, but since they were all thunks, I got linear data growth over time, until I blew up. Some advice I've gotten since then was to think about using case for strictness rather than explicitly using seq. Turns out case's pattern matching is pretty strict, and that you can often get by with that. I haven't spent a lot of time with core output, but my understanding is that it's all let and case. > 3) The standard library was not designed with space efficiency in mind; > for example, there is sum but no sum'. > Actually I think that the standard library was designed to be consistent with the way the language is documented to behave. That is to say that it's non-strict by default everywhere it's possible to be so. Control.Monad.State selects Control.Monad.State.Lazy by default instead of Control.Monad.State.Strict, but both exist. Yes, in some cases there's no strict equivalent provided, but is writing a strict sum really a big problem? I think there's stricter folds included because they're not quite as trivial, but once you have a strict fold isn't strict sum pretty easy? I suppose the type of the contained element in the list could make a big difference in whether the strict fold is strict enough, but where do you stop providing strict versions of functions for people? It seems a line must be drawn somewhere, and the right solution is to properly educate Haskell programmer about both the power and drawbacks of non-strict evaluation, and when it's really necessary to turn things off. Giving examples is fine, but one must learn to see the patterns where there is a problem that could brew. Real World Haskell teaches us about the profiling tools that helped me uncover my problems. > > > Best regards, > Alexei > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100108/b5218dfd/attachment.html From magnus at therning.org Fri Jan 8 10:25:31 2010 From: magnus at therning.org (Magnus Therning) Date: Fri Jan 8 09:58:21 2010 Subject: [Haskell-cafe] Typed Configuration Files In-Reply-To: <0102AD94-4A7C-47F0-A412-748FF4850448@informatik.uni-kiel.de> References: <0102AD94-4A7C-47F0-A412-748FF4850448@informatik.uni-kiel.de> Message-ID: On Fri, Jan 8, 2010 at 12:53 PM, Sebastian Fischer wrote: > Dear Caf?, > > Neil Mitchell's cmdargs package [1] is pretty neat. It can be used to parse > command-line arguments into a user-defined data structure. > > Is there something similar for parsing config files? If you write one I most certainly will use it! ;) Seriously, cmdargs is *brilliant*. It's also magic (to me). Implementing a config parser in a similar way would likely dispell the magic... if I only could find the time. /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe From nicolas.pouillard at gmail.com Fri Jan 8 10:41:56 2010 From: nicolas.pouillard at gmail.com (Nicolas Pouillard) Date: Fri Jan 8 10:14:44 2010 Subject: [Haskell-cafe] Typed Configuration Files In-Reply-To: References: <0102AD94-4A7C-47F0-A412-748FF4850448@informatik.uni-kiel.de> Message-ID: <1262965263-sup-4865@peray> Excerpts from Magnus Therning's message of Fri Jan 08 16:25:31 +0100 2010: > On Fri, Jan 8, 2010 at 12:53 PM, Sebastian Fischer > wrote: > > Dear Caf?, > > > > Neil Mitchell's cmdargs package [1] is pretty neat. It can be used to parse > > command-line arguments into a user-defined data structure. > > > > Is there something similar for parsing config files? > > If you write one I most certainly will use it! ;) > > Seriously, cmdargs is *brilliant*. It's also magic (to me). Not only to you in fact it is black magic since it uses unsafePerformIO :( -- Nicolas Pouillard http://nicolaspouillard.fr From ndmitchell at gmail.com Fri Jan 8 11:18:29 2010 From: ndmitchell at gmail.com (Neil Mitchell) Date: Fri Jan 8 10:51:20 2010 Subject: [Haskell-cafe] Typed Configuration Files In-Reply-To: <1262965263-sup-4865@peray> References: <0102AD94-4A7C-47F0-A412-748FF4850448@informatik.uni-kiel.de> <1262965263-sup-4865@peray> Message-ID: <404396ef1001080818s60640725y483624ad6bec9c84@mail.gmail.com> Hi, >> Seriously, cmdargs is *brilliant*. ?It's also magic (to me). > > Not only to you in fact it is black magic since it uses unsafePerformIO :( The problem isn't that it's black magic or that it uses unsafePerformIO - the problem is that it's horribly impure, so doesn't obey referential transparency. Unfortunately this in unavoidable with the way I wanted to write command line arguments... Thanks, Neil From bulat.ziganshin at gmail.com Fri Jan 8 12:08:11 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Fri Jan 8 11:48:34 2010 Subject: [Haskell-cafe] Typed Configuration Files In-Reply-To: <0102AD94-4A7C-47F0-A412-748FF4850448@informatik.uni-kiel.de> References: <0102AD94-4A7C-47F0-A412-748FF4850448@informatik.uni-kiel.de> Message-ID: <1666313526.20100108200811@gmail.com> Hello Sebastian, Friday, January 8, 2010, 3:53:53 PM, you wrote: > Neil Mitchell's cmdargs package [1] is pretty neat. It can be used to > parse command-line arguments into a user-defined data structure. > Is there something similar for parsing config files? Lua language may be used to describe arbitrarily complex data structure and there is HsLua: http://www.haskell.org/haskellwiki/HsLua -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From paul.brauner at loria.fr Fri Jan 8 12:33:24 2010 From: paul.brauner at loria.fr (Paul Brauner) Date: Fri Jan 8 12:06:14 2010 Subject: [Haskell-cafe] telling ghc to run several jobs in parallel Message-ID: <20100108173324.GC2207@inria.fr> Hi, I have to processors but ghc --make only uses one of them, even if some files could be compiled in parallel. Is there some option similar to the -j one of the make tool ? (I read the manual but didn't find it) Regards, Paul From will_n48 at yahoo.com Fri Jan 8 12:37:21 2010 From: will_n48 at yahoo.com (Will Ness) Date: Fri Jan 8 12:10:35 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001071713.39165.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > > Am Donnerstag 07 Januar 2010 11:43:44 schrieb Heinrich Apfelmus: > > Will Ness wrote: > > > > Hm? In my world view, there is only reduction to normal form and I don't > > see how "allocate its own storage" fits in there. Okasaki having shown > > something to that end would be new to me? > > > Perhaps what was meant was "storage must be allocated for each filter" > (which, however, seems trivial). I still contend that in case of nested filters, where each filter has only one consumer, even that isn't ultimately necessary (a chain of pointers could be formed). That's because there's no "peek"s, only "pull"s there. If the filters are used in merge situation, then there will be some "peek"s so current value must be somehow stored, though it's better to be made explicit and thus static (the place for it, I mean, instead of the "rolling" cons cell). Such implementation technique would prevent some extra gc. > > > Then under merging these split pairs form a monoid, so can be rearranged > > > in a tree. If you haven't seen it yet, it uses a different folding > > > structure to your code, with a lower total cost of multiples production > > > (estimated as Sum (1/p)*depth): correction: > > > tfold f (x:y:z:xs) = (x `f` (y `f` z)) `f` tfold f (pairwise f xs) > > > comps = tfold mergeSP $ pairwise mergeSP multips > > > > The idea being that each prime produces 1/p composites each "turn" and > > it takes time depth to trickle it to the top? Sounds reasonable, but > > remember that a prime p does not start to generate composites until > > the "turn count" has reached p^2, so it might occupy a place of low > > depth in the tree that is better spent on the previous primes. That might be why Daniel's structure is better: it plunges down faster than mine. "treefold" structure was: (2+4) + ( (4+8) + ( (8+16) + ( (16+32) + ( (32+64) + ....... )))) dpths: 3 4 4 5 5 6 6 7 7 8 daniel's: (2+(4+6)) + ( (8+(10+12)) + ( (14+(16+18)) + ( (20+(22+24)) + .... )) 3 5 5.4 6 7.8 7.9 8 9 9.5 9.6 10.7 10.8 > primes () = 2:3:5:7:11:13:primes' > ?? where > ??? primes' = roll 17 wheel13 `minus` compos primes''' > primes'' = 17:19:23:29:31:37:rollFrom 41 `minus` compos primes'' > primes''' = 17:19:23:29:31:37:rollFrom 41 `minus` compos primes'' Haven't read through the whole thing yet. :) :) I thought there was a typo there. There isn't. BTW using the no-share switch isn't necessary if we just write it down twice with some variations, like primes''' = let (h,t)=span (< 17^2) roll 17 wheel13 in h++t `minus` compos primes'' As we've found out, compilers aren't _that_ smart yet. From pumpkingod at gmail.com Fri Jan 8 12:40:35 2010 From: pumpkingod at gmail.com (Daniel Peebles) Date: Fri Jan 8 12:13:23 2010 Subject: [Haskell-cafe] telling ghc to run several jobs in parallel In-Reply-To: <20100108173324.GC2207@inria.fr> References: <20100108173324.GC2207@inria.fr> Message-ID: There is no such option yet, but there was some work recently on making GHC more amenable to doing jobs in parallel (from what I understand there's a global variable or two that makes it hard). Dan On Fri, Jan 8, 2010 at 6:33 PM, Paul Brauner wrote: > Hi, > > I have to processors but ghc --make only uses one of them, even if some > files could be compiled in parallel. Is there some option similar to the > -j one of the make tool ? (I read the manual but didn't find it) > > Regards, > Paul > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100108/c699df06/attachment.html From will_n48 at yahoo.com Fri Jan 8 13:45:47 2010 From: will_n48 at yahoo.com (Will Ness) Date: Fri Jan 8 13:19:01 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001071713.39165.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > > The below code is now a well-behaved memory citizen (3MB for the 100 millionth prime, about the same as the PQ code). It still is considerably slower than the PQ code. > In terms of MUT times as reported by +RTS -sstderr - as well as (MUT+GC) times - (measured once for prime No. 5*10^5, 10^6, 2*10^6, 4*10^6, 10^7 to get a rough tendency), it seems to scale a wee bit better than any of the other tfold versions I created, but a little worse than the PQ versions. > The relation of MUT times isn't too bad, but the GC times are rather abysmal (30-40%). > > ---------------------------------------------------------------------- > data People a = P { vips :: [a], dorks :: [a] } > > celebrate :: a -> People a -> People a > celebrate x p = P (x:vips p) (dorks p) > > primes :: forall a. Integral a => () -> [a] > primes () = 2:3:5:7:11:13:primes' > ?? where > ??? primes' = roll 17 wheel13 `minus` compos primes''' primes'' = 17:19:23:29:31:rollFrom 37 `minus` compos primes'' > primes''' = 17:19:23:29:31:37:rollFrom 41 `minus` compos primes'' > > pmults :: a -> People a > pmults p = case map (*p) (rollFrom p) of > (x:xs) -> P [x] xs > > multip :: [a] -> [People a] > multip ps = map pmults ps > > compos :: [a] -> [a] compos = vips . smartfold mergeSP . multip > > > smartfold f = tfold f . pairwise f > > tfold f (a:b:c:xs) = (a `f` (b `f` c)) `f` smartfold f xs > > pairwise f (x:y:ys)? = f x y : pairwise f ys > > mergeSP :: Integral a => People a -> People a -> People a > mergeSP p1@(P a _) p2 = P (a ++ vips mrgd) (dorks mrgd) > where > mrgd = spMerge (dorks p1) (vips p2) (dorks p2) > spMerge l1 [] l3 = P [] (merge l1 l3) > spMerge ~l1@(x:xs) l2@(y:ys) l3 = case compare x y of > LT -> celebrate x (spMerge xs l2 l3) > EQ -> celebrate x (spMerge xs ys l3) > GT -> celebrate y (spMerge l1 ys l3) > > ---------------------------------------------------------------------- > Hi Daniel, Is it so that you went back to my fold structure? Was it better for really big numbers of primes? I had the following for ages (well, at least two weeks) but I thought it was slower and took more memory (that was _before_ the 'no-share' and 'feeder' stuff). I can see the only difference in that you've re-written spMerge in a tail-recursive style with explicitly deconstructed parts; mine was relying on the compiler (8-L) to de-couple the two pipes and recognize that the second just passes along the final result, unchanged. The two versions seem to me to be _exactly_ operationally equivalent. All this searching for the code better understood by the compiler is _*very*_ frustrating, as it doesn't reflect on the semantics of the code, or even the operational semantics of the code. :-[ Weren't the P's supposed to disappear completely in the compiled code? Aren't types just a _behavioral_ definitions??? Aren't we supposed to be able to substitute equals for equals dammit?? Is this the state of our _best_ Haskell compiler???? module Primes8 where import Data.Monoid data (Ord a) => SplitList a = P [a] [a] instance (Ord a) => Monoid (SplitList a) where mempty = P [] [] -- {x | x::SplitList a} form a monoid under mappend mappend (P a b) ~(P c d) = let P bc b' = spMerge b c in P (a ++ bc) (merge b' d) where spMerge :: (Ord a) => [a] -> [a] -> SplitList a spMerge u@(x:xs) w@(y:ys) = case compare x y of LT -> P (x:c) d where (P c d) = spMerge xs w EQ -> P (x:c) d where (P c d) = spMerge xs ys GT -> P (y:c) d where (P c d) = spMerge u ys spMerge u [] = P [] u spMerge [] w = P [] w mconcat ms = fold mappend (pairwise mappend ms) where fold f (a: ~(b: ~(c:xs))) = (a `f` (b `f` c)) `f` fold f (pairwise f xs) pairwise f (x:y:ys) = f x y:pairwise f ys primes :: Integral a => () -> [a] primes () = 2:3:5:7:primes' where primes' = [11,13] ++ drop 2 (rollFrom 11) `minus` comps mults = map (\p-> P [p*p] [p*n | n<- tail $ rollFrom p]) $ primes' P comps _ = mconcat mults From gcross at phys.washington.edu Fri Jan 8 14:47:15 2010 From: gcross at phys.washington.edu (Gregory Crosswhite) Date: Fri Jan 8 14:21:02 2010 Subject: [Haskell-cafe] Testing for statistical properties In-Reply-To: <78dc001e1001080259k627f9b66p35bf3934edf64772@mail.gmail.com> References: <78dc001e1001080259k627f9b66p35bf3934edf64772@mail.gmail.com> Message-ID: <479D7566-151E-4023-A021-627736A30FD5@phys.washington.edu> Thanks! I had reached the same conclusion, so I am glad to see that you already wrote code to do this for me. :-) There is a bug in the version that you posted, though: you missed one of the terms in the u < 0.755 case, so the c2 constant goes completely unused. Here is my modified version of your function + bug fix, with some stylistic tweaks: computeKolmogorovProbability :: Double -> Double computeKolmogorovProbability z | u < 0.2 = 1 | u < 0.755 = 1 - w * (exp(c1/v)+exp(c2/v)+exp(c3/v))/u | u < 6.8116 = 2 * sum [ sign * exp(coef*v) | (sign,coef) <- take (1 `max` round (3/u)) coefs ] | otherwise = 0 where u = abs z v = u*u w = 2.50662827 c1 = -pi**2/8 c2 = 9*c1 c3 = 25*c1 coefs = [(1,-2),(-1,-8),(1,-18),(-1,-32)] Cheers, Greg On Jan 8, 2010, at 2:59 AM, Tom Nielsen wrote: > Hi Greg, > > Assuming this is a one-dimensional distribtution, you should use a > kolmogorov-smirnov test to test this: > > http://en.wikipedia.org/wiki/Kolmogorov-Smirnov_test > > I've implemented to the KS distribution from the CERN code linked in > the wikipedia article, here: > > http://github.com/glutamate/samfun/blob/master/Math/Probably/KS.hs > > (warning, i wasn't able to verify the numbers coming out against > anything so just check that it makes sense) > > So all you have to do is to find the maximal distance between your > samples and the cumulative density function, multiply by the sqrt. of > of the number of samples, and calculate kprob on that. > > I don't think you can do this in a Bayesian way because you can't > enumerate all the other distributions your samples could come from? > > Tom > > On Thu, Jan 7, 2010 at 9:31 PM, Gregory Crosswhite > wrote: >> Hey everyone! I have some computations that satisfy statistical properties which I would like to test --- that is, the result of the computation is non-deterministic, but I want to check that it is sampling the distribution that it should be sampling. Is anyone aware of a Haskell library out there that does anything like this? >> >> Cheers, >> Greg >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> From will_n48 at yahoo.com Fri Jan 8 15:05:18 2010 From: will_n48 at yahoo.com (Will Ness) Date: Fri Jan 8 14:38:33 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001071713.39165.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > roll?????? = scanl (+) > wheel????? = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: > ?????????? 4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel > wheel11 = res > where > snms = scanl (+) 11 (take 47 wheel) > nums = tail $ scanl (+) 11 (take 529 wheel) > cops = nums `minus` map (*11) snms > diffs = zipWith (-) (tail cops) cops > res = foldr (:) res diffs > wheel13 = res > where > snms = take 480 $ scanl (+) 13 wheel11 > nums = take (480*13+1) . tail $ scanl (+) 13 wheel11 > cops = nums `minus` map (*13) snms > diffs = zipWith (-) (tail cops) cops > res = foldr (:) res diffs > BTW have you seen my take on the "faithful Euler's sieve"? It shows another way to look at the wheels, which for me was really the first time I really understood what's going on there. It also makes for easier wheel extention (IMO): > euler ks@(p:rs) = p : euler (rs `minus` map (*p) ks) > primes = euler [2..] The essence of Euler's sieve is the wheel: after each step we're left with lists of non-multiples of the preceding primes: primes = euler $ listFrom [2] 1 = 2:euler ( listFrom [3] 1 `minus` map(2*) (listFrom [2] 1)) ) listFrom [3,4] 2 `minus` listFrom [4] 2 -- listFrom [3] 2 -- = 2:3:euler (listFrom [5] 2 `minus` map(3*) (listFrom [3] 2)) listFrom [5,7,9] 6 `minus` listFrom [9] 6 -- listFrom [5,7] 6 -- = 2:3:5:euler (listFrom [7,11] 6 `minus` listFrom [25,35] 30) [7,11, 13,17, 19,23, 25,29, 31,35] 30 -- listFrom [7,11,13,17,19,23,29,31] 30 -- = ..... where listFrom xs by = concat $ iterate (map (+ by)) xs so -- startRoll = ([2],1) nextRoll r@(xs@(x:xt),b) = ( (x,r') , r') where ys@(y:_) = xt ++ [x + b] r' = (xs',b') b' = x*b xs' = takeWhile (< y + b') (listFrom ys b) `minus` map (x*) xs rolls = unfoldr (Just . nextRoll) ([2],1) nthWheel n = let (ps,rs) = unzip $ take n rolls (x:xs,b) = last rs in ((ps, x), zipWith (-) (xs++[x+b]) (x:xs)) {- *Main> mapM print $ take 4 rolls (2,([3],2)) (3,([5,7],6)) (5,([7,11,13,17,19,23,29,31],30)) (7,([11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97, 101,103,107,109,113,121,127,131,137,139,143,149,151,157,163,167,169, 173,179,181,187,191,193,197,199,209,211],210)) *Main> nthWheel 3 (([2,3,5],7),[4,2,4,2,4,6,2,6]) *Main> nthWheel 4 (([2,3,5,7],11),[2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2, 4,8,6,4,6,2,4,6,2,6,6,4,2,4,6,2,6,4,2,4,2,10,2,10]) -} Coincidentally, the function specified by eulerPrimes n = let (ps,rs) = unzip $ take n rolls (qs@(q:_),b) = last rs in ps ++ takeWhile (< q^2) qs can be used to write the specialized nthEulerPrime etc., whose complexity seems to be about O(n^1.5). Maybe this reinvents some spiraling wheels or somethn'. :) From will_n48 at yahoo.com Fri Jan 8 15:11:51 2010 From: will_n48 at yahoo.com (Will Ness) Date: Fri Jan 8 14:45:09 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001071713.39165.daniel.is.fischer@web.de> Message-ID: Will Ness yahoo.com> writes: > > > That might be why Daniel's structure is better: it plunges down faster than > mine. > > "treefold" structure was: > (2+4) + ( (4+8) + ( (8+16) + ( (16+32) + ( (32+64) + ....... )))) > dpths: 3 4 4 5 5 6 6 7 7 8 this should of course have been dpths: 3 4 5 6 7 8 9 10 11 12 > > daniel's: > (2+(4+6)) + ( (8+(10+12)) + ( (14+(16+18)) + ( (20+(22+24)) + .... )) > 3 5 5.4 6 7.8 7.9 8 9 9.5 9.6 10.7 10.8 > hmm. :| From felipe.lessa at gmail.com Fri Jan 8 16:03:45 2010 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Fri Jan 8 15:36:38 2010 Subject: [Haskell-cafe] Re: ANNOUNCE: Clutterhs 0.1 In-Reply-To: <20091129080918.662a91fd@gaura-nitai.no-ip.org> References: <1259468280.21437.151.camel@wanda> <20091129080918.662a91fd@gaura-nitai.no-ip.org> Message-ID: <20100108210345.GA22083@kira.casa> (Sorry for replying to this old thread.) On Sun, Nov 29, 2009 at 08:09:18AM +0100, Gour wrote: > What do you think about binding Moblin's nbtk (now it's called mx) ? Just out of curiosity, did anyone do something about Moblin's toolkit and Haskell? Thanks! :) -- Felipe. From v.dijk.bas at gmail.com Fri Jan 8 17:59:35 2010 From: v.dijk.bas at gmail.com (Bas van Dijk) Date: Fri Jan 8 17:32:45 2010 Subject: [Haskell-cafe] Infix instance headers In-Reply-To: References: <59543203684B2244980D7E4057D5FBC10AF787C3@DB3EX14MBXC310.europe.corp.microsoft.com> <59543203684B2244980D7E4057D5FBC10AF78FF5@DB3EX14MBXC310.europe.corp.microsoft.com> Message-ID: Simon, I discovered that the following example also won't parse in ghc-6.12.1 because of the infix 'MayOpen' constraint: with ? (Resource resource, MonadCatchIO pr) ? resource ? (? s. s `MayOpen` resource ? RegionalHandle resource (RegionT s pr) ? RegionT s pr ?) ? pr ? Is this also fixed by your previous patch? regards, Bas From jmillikin at gmail.com Fri Jan 8 18:38:15 2010 From: jmillikin at gmail.com (John Millikin) Date: Fri Jan 8 18:11:22 2010 Subject: [Haskell-cafe] Capped lists and |append| Message-ID: <3283f7fe1001081538w5d390c14mf5ac33dfc4436be2@mail.gmail.com> Earlier today I uploaded the capped-list package; I didn't think there would be any interest, since it's a relatively trivial data structure, but already there's been three emails and an IRC convo about it. In short, this is Heinrich Apfelmus's "Train" type from , which showed up in a thread I posted regarding lazy error handling . The structure of a Train / CappedList (I like my name better) is: data Train a b = Wagon a (Train a b) | Loco b data CappedList cap a = Next a (CappedList cap a) | Cap cap Since uploading, there's been a big problem pointed out to me regarding this structure, namely the possible definitions of |append|. Because the list terminus is itself a value, but isn't / shouldn't be the same type as the elements, either obvious implementation will drop it. append :: CappedList cap a -> CappedList cap a -> CappedList cap a append (Cap 0) (Cap 1) = -- either (Cap 0) or (Cap 1), but information has been lost This problem can be solved using an unusual type signature for |append|, such as: append :: CappedList cap1 a -> CappedList cap2 a -> (cap1, CappedList cap2 a) or by declaring that a capped list is truly "capped": append :: CappedList cap a -> CappedList cap2 b -> CappedList cap a but these makes defining a reasonable |concat| difficult. Any ideas? This seems like a useful structure, since several people have described it, but some of the semantics seem troublesome. From felipe.lessa at gmail.com Fri Jan 8 20:57:00 2010 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Fri Jan 8 20:29:52 2010 Subject: [Haskell-cafe] Capped lists and |append| In-Reply-To: <3283f7fe1001081538w5d390c14mf5ac33dfc4436be2@mail.gmail.com> References: <3283f7fe1001081538w5d390c14mf5ac33dfc4436be2@mail.gmail.com> Message-ID: <20100109015700.GA7344@kira.casa> [Disclaimer: I didn't really read all the thread from which this data structure originated on Caf? =).] On Fri, Jan 08, 2010 at 03:38:15PM -0800, John Millikin wrote: > Since uploading, there's been a big problem pointed out to me > regarding this structure, namely the possible definitions of |append|. > Because the list terminus is itself a value, but isn't / shouldn't be > the same type as the elements, either obvious implementation will drop > it. > > append :: CappedList cap a -> CappedList cap a -> CappedList cap a > append (Cap 0) (Cap 1) = -- either (Cap 0) or (Cap 1), but > information has been lost I don't think there is an easy solution here. In a first approach, what I would do would be to provide -- Returning one of the caps out of list. appendL :: CappedList cap a -> CappedList cap' a -> (cap', CappedList cap a) appendR :: CappedList cap' a -> CappedList cap a -> (cap', CappedList cap a) -- Discarding one of the caps. appendL_ :: CappedList cap a -> CappedList discarded a -> CappedList cap a appendR_ :: CappedList discarded a -> CappedList cap a -> CappedList cap a -- 'mappend'ing the caps appendM :: Monoid cap => CappedList cap a -> CappedList cap a -> CappedList cap a and then define mappend = appendM If we used appendL_ then we would violate Monoid's law that says that mappend mempty x = x And if we used appendR_ we would violate mappend x mempty = x Of course, you would have to change your 'empty' package to include the following law: "For every data type implementing Empty and Monoid, empty should be mempty." This way you will guarantee that when using appendM Cap empty `mappend` Cap c = Cap c Also, you may want to have CappedList an instance of Control.Functor.Bifunctor from category-extras: -- Hask is a synonym for (->). instance Bifunctor CappedList Hask Hask Hask where bimap f g = foldr (Next . f) (Cap . g) And, of course, import Data.Monoid (First(..), Last(..)) appendL_ = bimap id getFirst . appendM . bimap id First appendR_ = bimap id getLast . appendM . bimap id Last Cheers, -- Felipe. From twanvl at gmail.com Fri Jan 8 21:01:28 2010 From: twanvl at gmail.com (Twan van Laarhoven) Date: Fri Jan 8 20:34:10 2010 Subject: [Haskell-cafe] Capped lists and |append| In-Reply-To: <3283f7fe1001081538w5d390c14mf5ac33dfc4436be2@mail.gmail.com> References: <3283f7fe1001081538w5d390c14mf5ac33dfc4436be2@mail.gmail.com> Message-ID: <4B47E378.9010503@gmail.com> John Millikin wrote: > Earlier today I uploaded the capped-list package; I didn't think there > would be any interest, since it's a relatively trivial data structure, > but already there's been three emails and an IRC convo about it. > > Since uploading, there's been a big problem pointed out to me > regarding this structure, namely the possible definitions of |append|. > > Any ideas? This seems like a useful structure, since several people > have described it, but some of the semantics seem troublesome. Some ideas: append :: Monoid c => CappedList c a -> CappedList c a -> CappedList c a append (Cap a) (Cap b) = Cap (a `mappend` b) This also leads to an instance Monoid (CappedList c): instance Monoid c => Monoid (CappedList c) where mempty = Cap mempty mappend = append You could also make the combining function flexible: appendWith :: (c -> d -> e) -> CappedList c a -> CappedList d a -> CappedList e a The problem with this definition is that it doesn't really respect the structure of the second list: the entire list has to be traversed just to update the cap. More random ideas: -- this is bind in the CappedList _ a monad bindCap :: CappedList c a -> (c -> CappedList d a) -> CappedList d a bindCapF :: Functor f => CappedList c a -> (c -> f (CappedList d a)) -> f (CappedList d a) Twan From cetin.sert at gmail.com Fri Jan 8 21:12:16 2010 From: cetin.sert at gmail.com (Cetin Sert) Date: Fri Jan 8 20:45:25 2010 Subject: [Haskell-cafe] Re: [arch-haskell] Upgrading Arch Linux Haskell Packages In-Reply-To: <877hrs3o4g.fsf@gmail.com> References: <1ff5dedc1001080136oa4a2flcbbd5f1306e541dc@mail.gmail.com> <20100108094438.GA25223@whirlpool.galois.com> <877hrs3o4g.fsf@gmail.com> Message-ID: <1ff5dedc1001081812p4410a340i310406f7c9a17cb9@mail.gmail.com> Even while having a break he's blazing fast with his replies! 2010/1/8 Ivan Lazar Miljenovic > Don Stewart writes: > > There's a batch upgrade, I've just been travelling! > > Yeah, let Don have a break for once! > > Oh, since you're here Don, how do I do ....... ? ;-) > > -- > Ivan Lazar Miljenovic > Ivan.Miljenovic@gmail.com > IvanMiljenovic.wordpress.com > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100108/a1d8f50f/attachment.html From daniel.is.fischer at web.de Fri Jan 8 22:52:48 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Fri Jan 8 22:27:16 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001071713.39165.daniel.is.fischer@web.de> Message-ID: <201001090452.48889.daniel.is.fischer@web.de> Am Freitag 08 Januar 2010 19:45:47 schrieb Will Ness: > Daniel Fischer web.de> writes: > > > > mergeSP :: Integral a => People a -> People a -> People a > > mergeSP p1@(P a _) p2 = P (a ++ vips mrgd) (dorks mrgd) > > where > > mrgd = spMerge (dorks p1) (vips p2) (dorks p2) > > spMerge l1 [] l3 = P [] (merge l1 l3) > > spMerge ~l1@(x:xs) l2@(y:ys) l3 = case compare x y of > > LT -> celebrate x (spMerge xs l2 l3) > > EQ -> celebrate x (spMerge xs ys l3) > > GT -> celebrate y (spMerge l1 ys l3) > > > > ---------------------------------------------------------------------- > > Hi Daniel, > > Is it so that you went back to my fold structure? Yes. > Was it better for really big numbers of primes? Yes, it is slower for <= 20 million primes (and some beyond), but faster for >= 50 million (and some before), according to the few tests I made. > > I had the following for ages (well, at least two weeks) but I thought it > was slower and took more memory (that was _before_ the 'no-share' and > 'feeder' stuff). I can see the only difference in that you've re-written > spMerge in a tail-recursive style with explicitly deconstructed parts; It's not tail-recursive, the recursive call is inside a celebrate. As it turns out, the important things are 1. a feeder and separate lists of multiples for the feeder and the runner, for the reasons detailed earlier (two-step feeding and larger wheel are pleasing but minor optimisations). 2. a strict pattern in tfold 3. moving the merge inside spMerge (you can have mergeSP (a,b) ~(c,d) = (a ++ bc, m) where (bc,m) = spMerge b c spMerge u [] = ([],merge u d) ... without exploding memory, but it's *much* slower than letting spMerge take three arguments) Now, I have to admit, the only point I _really_ understand is 1. (and why the three-argument spMerge is faster than the two-argument one taking the merge-partner from mergeSP's binding :). Why has mergeSP (a,b) ~(c,d) = let (bc,b') = spMerge b c in (a ++ bc, merge b' d) a memory leak, but mergeSP (a,b) ~(c,d) = let (bc,m) = spMerge' b c d in (a ++ bc, m) not? Well, looking at the core for mergeSP, the fog clears somewhat. The former is translated roughly to mergeSP (a,b) pair = let sm = spMerge b (fst pair) in (a ++ fst sm, merge (snd sm) (snd pair)) It holds on to the pair until the result of the merge is demanded, that is until the entire (a ++ fst sm) is consumed. Only then is the pair released and can be collected. On top of that, as soon as a is consumed and (fst sm) [or bc] is demanded, spMerge forces the evaluation of (fst pair) [c]. After a few levels, the evaluated list will take more space than the thunk. It cannot yet be collected, because pair is still alive. The elements have to be duplicated for (fst sm), because they're intertwined with those of b. On the next level of merging, they have to be duplicated again. The latter is translated roughly to mergeSP (a,b) pair = let sm = spMerge' b (fst pair) (snd pair) in (a ++ fst sm, snd sm) The pair is released as soon as the result of the spMerge' is demanded, that is, when a is consumed. Then the elements of (fst pair) need not be duplicated and they can be discarded almost immediately after they have been produced [for small primes, multiples of larger primes live a little longer, but those are fewer]. So, no duplication, shorter lifespan => no leak. Having seen that, the question is, why can't the compiler see that deconstructing the pair when the first component is needed is better? The first component of the pair is used in no other place, so keeping the pair can't have any advantage, can it? And why does tfold f (a: ~(b: ~(c:xs))) = ... leak, but not tfold f (a:b:c:xs) = ... ? I guess it's similar. tfold f (a: ~(b: ~(c:xs))) = (a `f` (b `f` c)) `f` tfold f ([pairwise f] xs) is tfold f (a:zs) = (a `f` (head zs `f` (head $ tail zs))) `f` tfold f (pairwise f $ drop 2 zs) the latter part holds on to the beginning of zs, leading again to data duplication and too long lifespans. > mine was relying on the compiler (8-L) to de-couple the two pipes and > recognize that the second just passes along the final result, unchanged. > > The two versions seem to me to be _exactly_ operationally equivalent. Well, they're not. The main difference is what we told the compiler _when_ to deconstruct the pairs. You said "at the latest possible moment", I said "as soon as we need the first component". It's not entirely obvious, but it is frequently said that understanding the space (and time) behaviour of lazy evaluation isn't always easy. > All this searching for the code better understood by the compiler is > _*very*_ frustrating, as it doesn't reflect on the semantics of the > code, or even the operational semantics of the code. :-[ > > Weren't the P's supposed to disappear completely in the compiled code? No. Constructors for data types can't disappear completely, only newtype constructors can (and do). > Aren't types just a _behavioral_ definitions??? Aren't we supposed to be > able to substitute equals for equals dammit?? We can. But substituting equals for equals can alter space and time complexity. fromInteger 0 == fromInteger (let xs = [1 .. 10^8] in (product xs + sum xs) `mod` 10) > > Is this the state of our _best_ Haskell compiler???? > Yes. It's still a "do what I tell you to" compiler, even if a pretty slick one, not a "do what I mean" compiler. Sometimes, what you tell the compiler isn't what you wanted. It's easier to predict when you give detailed step by step instructions. From jmillikin at gmail.com Sat Jan 9 00:10:38 2010 From: jmillikin at gmail.com (John Millikin) Date: Fri Jan 8 23:43:45 2010 Subject: [Haskell-cafe] Capped lists and |append| In-Reply-To: <20100109015700.GA7344@kira.casa> References: <3283f7fe1001081538w5d390c14mf5ac33dfc4436be2@mail.gmail.com> <20100109015700.GA7344@kira.casa> Message-ID: <3283f7fe1001082110n1c925767te853ebf2b44c990f@mail.gmail.com> Everything here makes much more sense than the previous implementation -- I've upped 1.2, which splits up |append|, implements the instances in terms of Monoid, etc. Also included is |toList| and |toList_| , which are like functions defined in Felipe's earlier email to me. The first returns the cap and values, the second only the values. Last (but not least), some of the |append*| functions are now defined in terms of |appendWith| from Twan van Laarhoven's email. For example, |appendM = appendWith mappend|. On Fri, Jan 8, 2010 at 17:57, Felipe Lessa wrote: > Of course, you would have to change your 'empty' package to > include the following law: > > "For every data type implementing Empty and Monoid, > empty should be mempty." "empty" turned out to be a dumb idea -- I had hoped to use it for types which support a NIL value but not appending. Turns out, there's not much point to lists which can't be appended. C'est la vie. > Also, you may want to have CappedList an instance of > Control.Functor.Bifunctor from category-extras: > [...] This is probably a good idea, but, I am nervous about making such a small package depend on the huge category-extras and mtl. From will_n48 at yahoo.com Sat Jan 9 02:04:20 2010 From: will_n48 at yahoo.com (Will Ness) Date: Sat Jan 9 01:37:36 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001071713.39165.daniel.is.fischer@web.de> <201001090452.48889.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > Am Freitag 08 Januar 2010 19:45:47 schrieb Will Ness: > > Daniel Fischer web.de> writes: > > > It's not tail-recursive, the recursive call is inside a celebrate. It is (spMerge that is). It calls tail-recursive celebrate in a tail position. What you've done, is to eliminate the outstanding context, buy moving it inward. Your detailed explanation is more clear than that. :) BTW when I run VIP code it is consistently slower than using just pairs, modified with wheel and feeder and all. So what's needed is to re-implement your approach for pairs: mergeSP (a,b) ~(c,d) = let (bc,bd) = spMerge b c d in (a ++ bc, bd) where spMerge u [] d = ([], merge u d) spMerge u@(x:xs) w@(y:ys) d = case compare x y of LT -> consSP x $ spMerge xs w d EQ -> consSP x $ spMerge xs ys d GT -> consSP y $ spMerge u ys d consSP x ~(a,b) = (x:a,b) -- don't forget that magic `~` !!! BTW I'm able to eliminate sharing without a compiler switch by using mtwprimes () = 2:3:5:7:primes where primes = doPrimes 121 primes doPrimes n prs = let (h,t) = span (< n) $ rollFrom 11 in h ++ t `diff` comps prs doPrimes2 n prs = let (h,t) = span (< n) $ rollFrom (12-1) in h ++ t `diff` comps prs mtw2primes () = 2:3:5:7:primes where primes = doPrimes 26 primes2 primes2 = doPrimes2 121 primes2 Using 'splitAt 26' in place of 'span (< 121)' didn't work though. How about them wheels? :) > > Yes. It's still a "do what I tell you to" compiler, even if a pretty slick > one, not a "do what I mean" compiler. Sometimes, what you tell the compiler > isn't what you wanted. > It's easier to predict when you give detailed step by step instructions. > From will_n48 at yahoo.com Sat Jan 9 02:42:52 2010 From: will_n48 at yahoo.com (Will Ness) Date: Sat Jan 9 02:16:07 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001030508.46357.daniel.is.fischer@web.de> <201001040129.22689.daniel.is.fischer@web.de> Message-ID: Heinrich Apfelmus quantentunnel.de> writes: > > Will Ness wrote: > > But I get the impression that GHC isn't working through equational > > reasoning?.. > > I see all this talk about thunks etc. > > Sure it does. Concerning the thunks, they're part of the implementation > of the reduction model (call-by-need aka lazy evaluation). At run-time? I meant to eliminate as much calculation as possible, pre-run-time. I would expect the best efforts of the best minds to go into searching for ways how to eliminate computations altogether, instead of how to perform them better. > >> Concerning the sieves, there is a fundamental difference between the > >> imperative sieve and the functional sieves, regardless of whether the > >> latter start at p or p^2 or use a priority queue. [...] > > > > We can directy jump to the next multiple too, it is called (+). :) :) > > > > But seriously, the real issue is that we have to merge the produced > > streams of multiples, while the mutable-storage code works on same one, > > so its "merging cost" is zero. > > Not quite, I think there are two things going on: > > 1. In contrast to the standard imperative version, we are implementing > an on-line algorithm that produces arbitrarily many primes on demand. > Any imperative on-line version will need to think about storage for > pending prime filters as well. True. > 2. Even the imperative algorithm can be interpreted as "merging" arrays, > just that the composites are magically merged at the right place (at > distance p from each other) because arrays offer O(1) "jumps". i.e. with a merging cost of zero. :) > In contrast, the functional version needs O(log something) time to > calculate where to put the next composite. when thinking it terms of the finally produced sequence, yes. We have to produce numbers one by one and take care of their ordering ourselves; _they_ just /throw/ the numbers at the shared canvas and let _it_ take care of ordering them automagically, _later_, on the final sweep through. ISWYM. > > > If you could take a look at the tree-merging primes and why it uses > > too much memory, it would be great. > > Fortunately, Daniel already took a detailed look. :) Yes he really came through! He finally found, and fixed, the space leak. It was hiding in mergeSP_BAD (a,b) ~(c,d) = let (bc,b') = spMerge b c in (a ++ bc, merge b' d) where spMerge :: (Ord a) => [a] -> [a] -> ([a],[a]) spMerge a@(x:xs) b@(y:ys) = case compare x y of LT -> (x:c,d) where (c,d) = spMerge xs b EQ -> (x:c,d) where (c,d) = spMerge xs ys GT -> (y:c,d) where (c,d) = spMerge a ys spMerge a [] = ([] ,a) spMerge [] b = ([] ,b) which really ought to have been mergeSP (a,b) ~(c,d) = let ~(bc,bd) = spMerge b c d in (a ++ bc, bd) where spMerge u [] d = ([], merge u d) spMerge u@(x:xs) w@(y:ys) d = case compare x y of LT -> spCons x $ spMerge xs w d EQ -> spCons x $ spMerge xs ys d GT -> spCons y $ spMerge u ys d spCons x ~(a,b) = (x:a,b) Can you spot the difference? :) :) > Aww, why remove the cutesy name? The VIPs will be angry for being ignored! It runs faster on plain pairs, and on less memory, equals for equals. For some reason. :) From will_n48 at yahoo.com Sat Jan 9 04:51:44 2010 From: will_n48 at yahoo.com (Will Ness) Date: Sat Jan 9 04:24:55 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001071713.39165.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > > Am Donnerstag 07 Januar 2010 11:43:44 schrieb Heinrich Apfelmus: > > Will Ness wrote: > > > Heinrich Apfelmus writes: > > The below code is now a well-behaved memory citizen (3MB for the 100 millionth prime, about the same as the PQ code). It still is considerably slower than the PQ code. > In terms of MUT times as reported by +RTS -sstderr - as well as (MUT+GC) times - (measured once for prime No. 5*10^5, 10^6, 2*10^6, 4*10^6, 10^7 to get a rough tendency), it seems to scale a wee bit better than any of the other tfold versions I created, but a little worse than the PQ versions. > The relation of MUT times isn't too bad, but the GC times are rather abysmal (30-40%). > > ---------------------------------------------------------------------- > > data People a = P { vips :: [a], dorks :: [a] } > > celebrate x p = P (x:vips p) (dorks p) > > mergeSP p1@(P a _) p2 = P (a ++ vips mrgd) (dorks mrgd) > where > mrgd = spMerge (dorks p1) (vips p2) (dorks p2) > spMerge l1 [] l3 = P [] (merge l1 l3) > spMerge ~l1@(x:xs) l2@(y:ys) l3 = case compare x y of > LT -> celebrate x (spMerge xs l2 l3) > EQ -> celebrate x (spMerge xs ys l3) > GT -> celebrate y (spMerge l1 ys l3) > I forgot to say something *very* important. :) Here it is. Yippee-hurray! :) From kitaev at iqi.caltech.edu Sat Jan 9 05:23:12 2010 From: kitaev at iqi.caltech.edu (Alexei Kitaev) Date: Sat Jan 9 04:56:17 2010 Subject: [Haskell-cafe] space leaks and optimizations In-Reply-To: <3e1162e61001080717i25e54a1bl16c983d0e8ebc68d@mail.gmail.com> References: <4B471126.4010807@iqi.caltech.edu> <3e1162e61001080717i25e54a1bl16c983d0e8ebc68d@mail.gmail.com> Message-ID: <4B485910.7070701@iqi.caltech.edu> Dear David, Thank you for your comments. I understand your suggestion that a program should contain some "synchronization points" where the values are evaluated. But this is not easy. Maybe I should just practice more. I while ago I played with the strict and lazy ST monads and was able to achieve the desired behavior, though with difficulty. Unfortunately, there is no universal solution, and one cannot always use standard idioms. For example, the lazy version of ST (and State) has the problem you described, while the strict version exhibits a space leak when used with mapM or sequence. Simply put, one cannot construct a lazy producer out of a strict state. I wrote a special version of sequence, which uses ST.Lazy but forces the evaluation of the implicit state at each step: import Control.Monad import Control.Monad.ST import qualified Control.Monad.ST.Lazy as Lazy seqLST :: [Lazy.ST s a] -> Lazy.ST s [a] seqLST xs = syncLST (f xs) where f [] = return [] f (x:xs) = liftM2 (:) x (seqLST xs) syncLST :: Lazy.ST s a -> Lazy.ST s a syncLST = join . Lazy.strictToLazyST . Lazy.lazyToStrictST . return For the lazy State monad, syncLState m = State $ \s -> s `seq` runState m s I am not completely satisfied with this solution. For one thing, it's slow and can hardly be optimized. It's also not clear whether one should evaluate the input state as I did (there was some reason but I don't remember) or the output state. I think that a better idea would be to use strict (ST s) together with a lazy continuation, (STC s a). It's basically a function s -> a, but one has to wrap it with some GHC-specific types like State#. Mathematically, (STC s a) is an algebra over the (ST s) monad. I'll try that when I have time. More generally, I am looking for reliable and easy to use tools and idioms for space-conscious programming. I appreciate the design of the strict ST and State monads. In particular, ST has a nice invariant that, at any point, the implicit state is fully evaluated. However, I spend a lot of time figuring how the strict and lazy monads actually work. Is there any documentation? Reading the discussion related to your blog, I realized that strict State is different in that it does not actually force the state. But forcing can be achieved by wrapping all actions with the following function: sState :: (s -> (a,s)) -> State s a sState f = State $ \s -> case f s of (a,s') -> s' `seq` (a,s') I hope that somebody will answer my other questions about the operational semantics and optimizations. -Alexei David Leimbach wrote: >> >> 2) While each step is predictable, the overall behavior of a lazy >> program can be rather surprising. So one must be very careful. GHC >> provides two ways to control the evaluation order, seq and bang >> patterns, but I am not sure which of these (if any) is the right tool. >> Consider the following example (from the Real World Haskell book): >> mean :: [Double] -> Double >> mean xs = sum / fromIntegral num where >> (num,sum) = foldl' f (0,0) xs :: (Int, Double) >> f (n,s) x = (n+1, s+x) >> Although it uses foldl', there is a space leak because Haskell tuples >> are not strict. There are two possible fixes: >> f (!n,!s) x = (n+1, s+x) >> or >> f (n,s) x = let n1=n+1; s1=s+x in n1 `seq` s1 `seq` (n1,s1) >> The first one is short, but less natural than the second one, where the >> offending thunks are suppressed on the spot. Unfortunately, the syntax >> is awkward; it would be nice to write something like >> f (n,s) x = (!n+1, !n+1) >> Well, I am becoming too grumpy, perhaps the bang patterns are fine. More >> important question: are there established practices to *avoid* space >> leaks rather than fixing them afterwards? >> >> > I believe the expectation is to learn to not be surprised in the areas where > lazy or non-strict evaluation can be overused, and to learn all the > advantages of non-strict evaluation vs strict, and the power it gives, such > that an imperative programmer doesn't feel surprised or angry when things go > wrong. > > I blogged about writing a long running service in Haskell that ran into > problems with the lazy State monad, and lazy Data.Map, and I discussed how I > had to force evaluations of everything to get the program under control. > This wasn't for a hobby, this was for a production system. I believe I've > a much better handle on strict vs non-strict than when I started the > project, but I felt pretty lost for a while in the process of doing it. > > I was even using the Maybe monad with it's MonadPlus implementation to avoid > using case statements around deconstruction, which I'm sure exacerbated some > of my problem. However, since Haskell will evaluate the outer-most stuff > first, the trick seems to be to find the point at which you *really* need > the values computed, then tell Haskell to get on with it. You kind of have > to have an explicit sequence point where all things need to be resolved, and > you have to be able to see those in your code. Sometimes you can get away > with only doing small pieces at a time. > > I had about the worst situation I've ever seen for data growth in my code. > I had a pile of non-strict expressions, that were all dependencies for the > next, running forever, and never getting evaluated except at asynchronous > and user-controlled moments. If these expressions had been evaluated > strictly, they would have taken up constant space, but since they were all > thunks, I got linear data growth over time, until I blew up. > > Some advice I've gotten since then was to think about using case for > strictness rather than explicitly using seq. Turns out case's pattern > matching is pretty strict, and that you can often get by with that. I > haven't spent a lot of time with core output, but my understanding is that > it's all let and case. > > > >> 3) The standard library was not designed with space efficiency in mind; >> for example, there is sum but no sum'. >> > > Actually I think that the standard library was designed to be consistent > with the way the language is documented to behave. That is to say that it's > non-strict by default everywhere it's possible to be so. > Control.Monad.State selects Control.Monad.State.Lazy by default instead of > Control.Monad.State.Strict, but both exist. > > Yes, in some cases there's no strict equivalent provided, but is writing a > strict sum really a big problem? I think there's stricter folds included > because they're not quite as trivial, but once you have a strict fold isn't > strict sum pretty easy? I suppose the type of the contained element in the > list could make a big difference in whether the strict fold is strict > enough, but where do you stop providing strict versions of functions for > people? It seems a line must be drawn somewhere, and the right solution is > to properly educate Haskell programmer about both the power and drawbacks of > non-strict evaluation, and when it's really necessary to turn things off. > Giving examples is fine, but one must learn to see the patterns where there > is a problem that could brew. > > Real World Haskell teaches us about the profiling tools that helped me > uncover my problems. > > >> >> Best regards, >> Alexei >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > From felipe.lessa at gmail.com Sat Jan 9 06:33:30 2010 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Sat Jan 9 06:06:22 2010 Subject: [Haskell-cafe] Capped lists and |append| In-Reply-To: <3283f7fe1001082110n1c925767te853ebf2b44c990f@mail.gmail.com> References: <3283f7fe1001081538w5d390c14mf5ac33dfc4436be2@mail.gmail.com> <20100109015700.GA7344@kira.casa> <3283f7fe1001082110n1c925767te853ebf2b44c990f@mail.gmail.com> Message-ID: <20100109113330.GA4763@kira.casa> On Fri, Jan 08, 2010 at 09:10:38PM -0800, John Millikin wrote: > > Also, you may want to have CappedList an instance of > > Control.Functor.Bifunctor from category-extras: > > [...] > > This is probably a good idea, but, I am nervous about making such a > small package depend on the huge category-extras and mtl. Well, then just provide the plain function in the module bimap :: (a -> b) -> (cap -> cap') -> CappedList cap a -> CappedList cap' b bimap f g = foldr (Next . f) (Cap . g) :) -- Felipe. From daniel.is.fischer at web.de Sat Jan 9 08:59:01 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sat Jan 9 08:33:28 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001090452.48889.daniel.is.fischer@web.de> Message-ID: <201001091459.01382.daniel.is.fischer@web.de> Am Samstag 09 Januar 2010 08:04:20 schrieb Will Ness: > Daniel Fischer web.de> writes: > > Am Freitag 08 Januar 2010 19:45:47 schrieb Will Ness: > > > Daniel Fischer web.de> writes: > > > > It's not tail-recursive, the recursive call is inside a celebrate. > > It is (spMerge that is). No. "In computer science, tail recursion (or tail-end recursion) is a special case of recursion in which the last operation of the function, the tail call, is a recursive call." The last operation of spMerge is a call to celebrate or the pair constructor (be that P or (,)). Doesn't matter, though, as for lazy languages, tail recursion isn't very important. > It calls tail-recursive celebrate in a tail > position. What you've done, is to eliminate the outstanding context, by > moving it inward. Your detailed explanation is more clear than that. :) > > BTW when I run VIP code it is consistently slower than using just pairs, I can't reproduce that. Ceteris paribus, I get the exact same allocation and GC figures whether I use People or (,), running times identical enough (difference between People and (,) is smaller than the difference between runs of the same; the difference between the fastest and the slowest run of the two is less than 0.5%). I think it must be the other changes you made. > modified with wheel and feeder and all. So what's needed is to > re-implement your approach for pairs: > > mergeSP (a,b) ~(c,d) = let (bc,bd) = spMerge b c d > in (a ++ bc, bd) > where > spMerge u [] d = ([], merge u d) > spMerge u@(x:xs) w@(y:ys) d = case compare x y of > LT -> consSP x $ spMerge xs w d > EQ -> consSP x $ spMerge xs ys d > GT -> consSP y $ spMerge u ys d > > consSP x ~(a,b) = (x:a,b) -- don't forget that magic `~` !!! I called that (<:). > > > BTW I'm able to eliminate sharing without a compiler switch by using > Yes, I can too. But it's easy to make a false step and trigger sharing. I can get a nice speedup (~15%, mostly due to much less garbage collecting) by doing the final merge in a function without unnecessarily wrapping the result in a pair (whose secondcomponent is ignored): -- Doesn't need -fno-cse anymore, -- but it needs -XScopedTypeVariables for the local type signatures primes :: forall a. Integral a => () -> [a] primes () = 2:3:5:7:11:13:calcPrimes 17 primes'' ?? where calcPrimes s cs = rollFrom s `minus` compos cs bootstrap = 17:19:23:29:31:37:calcPrimes 41 bootstrap primes' = calcPrimes 17 bootstrap primes'' = calcPrimes 17 primes' pmults :: a -> ([a],[a]) pmults p = case map (*p) (rollFrom p) of (x:xs) -> ([x],xs) multip :: [a] -> [([a],[a])] multip ps = map pmults ps compos :: [a] -> [a] compos ps = case pairwise mergeSP (multip ps) of ((a,b):cs) -> a ++ funMerge b (pairwise mergeSP cs) funMerge b (x:y:zs) = let (c,d) = mergeSP x y in mfun b c d (pairwise mergeSP zs) mfun u@(x:xs) w@(y:ys) d l = case compare x y of LT -> x:mfun xs w d l EQ -> x:mfun xs ys d l GT -> y:mfun u ys d l mfun u [] d l = funMerge (merge u d) l This uses a different folding structure again, which seems to give slightly better performance than the original tree-fold structure. In contrast to the VippyPrimes, it profits much from a larger allocation area, running with +RTS -A2M gives a >10% speedup for prime # 10M/20M, +RTS -A8M nearly 20%. -A16M and -A32M buy a little more, but in that range at least, it's not much (may be significant for larger targets). Still way slower than PQ, but the gap is narrowing. > > mtwprimes () = 2:3:5:7:primes > where > primes = doPrimes 121 primes > > doPrimes n prs = let (h,t) = span (< n) $ rollFrom 11 > in h ++ t `diff` comps prs > doPrimes2 n prs = let (h,t) = span (< n) $ rollFrom (12-1) > in h ++ t `diff` comps prs > > mtw2primes () = 2:3:5:7:primes > where > primes = doPrimes 26 primes2 > primes2 = doPrimes2 121 primes2 > > > Using 'splitAt 26' in place of 'span (< 121)' didn't work though. > > > How about them wheels? :) > Well, what about them? From daniel.is.fischer at web.de Sat Jan 9 09:06:12 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sat Jan 9 08:40:38 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001071713.39165.daniel.is.fischer@web.de> Message-ID: <201001091506.12997.daniel.is.fischer@web.de> Am Freitag 08 Januar 2010 18:37:21 schrieb Will Ness: > Daniel Fischer web.de> writes: > > Am Donnerstag 07 Januar 2010 11:43:44 schrieb Heinrich Apfelmus: > > > Will Ness wrote: > > > > > > Hm? In my world view, there is only reduction to normal form and I > > > don't see how "allocate its own storage" fits in there. Okasaki > > > having shown something to that end would be new to me? > > > > Perhaps what was meant was "storage must be allocated for each filter" > > (which, however, seems trivial). > > I still contend that in case of nested filters, where each filter has > only one consumer, even that isn't ultimately necessary (a chain of > pointers could be formed). That's because there's no "peek"s, only > "pull"s there. If the filters are used in merge situation, then there > will be some "peek"s so current value must be somehow stored, though > it's better to be made explicit and thus static (the place for it, I > mean, instead of the "rolling" cons cell). Such implementation technique > would prevent some extra gc. > Well, for each filter we need to store 1. a pointer to where in the wheel we are 2. the prime by which to multiply the steps of the wheel 3. the current value of the filter (which number to reject next) I don't see how to use less. It's not much, but it's not zero storage. From will_n48 at yahoo.com Sat Jan 9 11:23:19 2010 From: will_n48 at yahoo.com (Will Ness) Date: Sat Jan 9 10:58:13 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001090452.48889.daniel.is.fischer@web.de> <201001091459.01382.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > Am Samstag 09 Januar 2010 08:04:20 schrieb Will Ness: > > Daniel Fischer web.de> writes: > > > Am Freitag 08 Januar 2010 19:45:47 schrieb Will Ness: > > > > Daniel Fischer web.de> writes: > > > > > > It's not tail-recursive, the recursive call is inside a celebrate. > > > > It is (spMerge that is). > > No. > "In computer science, tail recursion (or tail-end recursion) is a special > case of recursion in which the last operation of the function, the tail > call, is a recursive call." As far as I understand it, when a function makes a tail call to a tail recursive function (be it itself or some other function) it is itself tail recursive. I.e. that call may be replaced with a direct jump, with no new context to be created. That is what your version accomplishes, too. Mine really held to that pair ~(c,d) when it wanted to call (merge _ d) _after_ the call to spMerge. By passing the pre-decomposed part of a pair, 'd', into the process environment of spMerge, you've made it tail recursive - it carried along all the context it needed. That's what've eliminated the space leak, so I'd say tail recursion does play a role under lazy evaluation - when a compiler isn't smart enough to do _that_ for us by itself. _Were_ it reliably smart, even non- recursive functions like my initial variant would work just as well. > The last operation of spMerge is a call to celebrate or the pair > constructor (be that P or (,)). Doesn't matter, though, as for lazy > languages, tail recursion isn't very important. > > > It calls tail-recursive celebrate in a tail > > position. What you've done, is to eliminate the outstanding context, by > > moving it inward. Your detailed explanation is more clear than that. :) > > > > BTW when I run VIP code it is consistently slower than using just pairs, > > I can't reproduce that. Ceteris paribus, I get the exact same allocation > and GC figures whether I use People or (,), running times identical enough > (difference between People and (,) is smaller than the difference between > runs of the same; the difference between the fastest and the slowest run of > the two is less than 0.5%). I think it must be the other changes you made. I just take the VIP code as it is on a web page, and my intial variant without the wheel, and compare. Then I add the wheel in the same fashion, and then feeder, and compare again. When I tested that Monid instance code I too compared it to the straight pairs, and it was slower. Don't know why. > > modified with wheel and feeder and all. So what's needed is to > > re-implement your approach for pairs: > > > > mergeSP (a,b) ~(c,d) = let (bc,bd) = spMerge b c d > > in (a ++ bc, bd) > > where > > spMerge b [] d = ([], merge b d) > > spMerge b@(x:xs) c@(y:ys) d = case compare x y of > > LT -> consSP x $ spMerge xs c d > > EQ -> consSP x $ spMerge xs ys d > > GT -> consSP y $ spMerge b ys d > > > > consSP x ~(bc,bd) = (x:bc,bd) -- don't forget that magic `~` !!! > > I called that (<:). > > > > > BTW I'm able to eliminate sharing without a compiler switch by using > > > > Yes, I can too. But it's easy to make a false step and trigger sharing. yes indeed. It's seems unpredictable. Fortunately GHC couldn't tell that (12-1) was 11 by the looks of it. :) Your idea certainly seems right, that there ought to be some control over sharing on a per-function basis somehow without these ridiculous code tricks. > I can get a nice speedup (~15%, mostly due to much less garbage collecting) by doing the final merge in a function without unnecessarily wrapping the result in a pair Will have to wrap my head around _that_. But that would be fighting with the compiler again. I don't like that, I much rather fight with the problem at hand. There shouldn't be any pairs in the compiled code in the first place. They just guide the staging of (++) and (merge) intertwined between the producer streams. At each finite step, when the second part of a pair comes into play, it is only after its first part was completely consumed. I guess the next thing to try would be to actually create a data type MergeNode and arrange _those_ in a tree and see if that helps. That would be the next half-step towards the PQ itself. > This uses a different folding structure again, which I am yet to decipher. :) > > How about them wheels? :) > > Well, what about them? I dunno, it makes for a real easy wheel derivation, and coming out of our discussion of euler's sieve it's a nice cross-pollination. :) Having yet another list representation suddenly cleared up the whole issue (two of them). I'll repost it one last time as I've made some corrections to it: > euler ks@(p:rs) = p : euler (rs `minus` map (*p) ks) > primes = euler [2..] > primes = euler $ listFrom [2] 1 > = 2:euler ( listFrom [3] 1 `minus` map(2*) (listFrom [2] 1)) ) > listFrom [3,4] 2 `minus` listFrom [4] 2 > == listFrom [3] 2 == > = 2:3:euler (listFrom [5] 2 `minus` map(3*) (listFrom [3] 2)) > listFrom [5,7,9] 6 `minus` listFrom [9] 6 > == listFrom [5,7] 6 == listFrom xs by = concat $ iterate (map (+ by)) xs rolls = unfoldr (Just . nextRoll) ([2],1) nextRoll r@(xs@(p:xt),b) = ( (p,r') , r') where r' = (xs',p*b) xs' = (concat $ take p $ iterate (map (+ b)) $ xt ++ [p+b]) `minus` map (p*) xs nthWheel n = let (ps,rs) = unzip $ take n rolls (x:xs,b) = last rs in ((ps, x), zipWith (-) (xs++[x+b]) (x:xs)) eulerPrimes n = let (ps,rs) = unzip $ take n rolls (qs@(q:_),b) = last rs in ps ++ takeWhile (< q^2) qs (BTW I've noticed that when I reply in Gmane, all the text below double hyphen, if present in the post to which I'm replying, just disappears. This may be an artefact of some specific browser.) From dave at zednenem.com Sat Jan 9 12:14:02 2010 From: dave at zednenem.com (David Menendez) Date: Sat Jan 9 11:46:48 2010 Subject: [Haskell-cafe] Capped lists and |append| In-Reply-To: <3283f7fe1001081538w5d390c14mf5ac33dfc4436be2@mail.gmail.com> References: <3283f7fe1001081538w5d390c14mf5ac33dfc4436be2@mail.gmail.com> Message-ID: <49a77b7a1001090914k33032b11wdfe3a6874bd3658e@mail.gmail.com> On Fri, Jan 8, 2010 at 6:38 PM, John Millikin wrote: > Earlier today I uploaded the capped-list package; I didn't think there > would be any interest, since it's a relatively trivial data structure, > but already there's been three emails and an IRC convo about it. > > In short, this is Heinrich Apfelmus's "Train" type from > , > which showed up in a thread I posted regarding lazy error handling > . > The structure of a Train / CappedList (I like my name better) is: > > ? ?data Train a b = Wagon a (Train a b) | Loco ?b > ? ?data CappedList cap a = Next a (CappedList cap a) | Cap cap The order of the type parameters is important. In particular, Train is a free monad, with (>>=) acting as a generalized append. instance Monad (Train a) where return = Loco Loco a >>= f = f a Wagon x t = Wagon x (t >>= f) Monad instances for CappedList are also possible, but more complex: instance Monoid cap => Monad (CappedList cap) where return a = Next a mempty Cap c >>= f = Cap c Next a as >>= f = f a `mappend` (as >>= f) (I can't check what you've uploaded because Hackage is down, so my apologies if I'm telling you things you already know.) -- Dave Menendez From apfelmus at quantentunnel.de Sat Jan 9 12:48:01 2010 From: apfelmus at quantentunnel.de (Heinrich Apfelmus) Date: Sat Jan 9 12:21:13 2010 Subject: [Haskell-cafe] Re: Space Efficiency When Sorting a List of Many Lists In-Reply-To: References: <20100104144030.949BD3244D3@www.haskell.org> Message-ID: Peter Green wrote: > Heinrich, thanks for some great help and food for thought! My pleasure. :) >> Thanks for describing the background of this problem in detail! I was >> mainly asking because I'm always looking for interesting Haskell topics >> that can be turned into a tutorial of sorts, and this problem makes a >> great example. > > Another interesting problem is starting from a file of single wagers and > trying to compress them (i.e. inverse of 'explosion'. I believe this > problem is analogous to Set Cover and therefore NP-Complete. Heuristics > are the order of the day here. Interesting indeed! What kind of heuristics do you employ there? It seems quite difficult to me, somehow. >> [...] >> main = interact (unlines . toCSV . sortExplode . fromCSV . lines) >> > Thank you *very* much for this code! I will try to get my head around > it. I understand the broad outline you posted elsewhere, but will take > me a while to fully grasp the above as I'm only up to ~p200 in Real > World Haskell :). > > As for performance of your code above on my file of compressed wagers > which expands to 3.7M single wagers: > > (My original version posted here and using vanilla sort) > 541 MB total memory in use (5 MB lost due to fragmentation) > INIT time 0.00s ( 0.01s elapsed) > MUT time 13.98s ( 15.82s elapsed) > GC time 8.69s ( 9.64s elapsed) > EXIT time 0.00s ( 0.00s elapsed) > Total time 22.67s ( 25.47s elapsed) > > (Your much improved version) > 10 MB total memory in use (1 MB lost due to fragmentation) > INIT time 0.00s ( 0.00s elapsed) > MUT time 7.61s ( 9.38s elapsed) > GC time 3.48s ( 3.58s elapsed) > EXIT time 0.00s ( 0.00s elapsed) > Total time 11.08s ( 12.95s elapsed) > > Very impressive and thanks again! Category theory saves the day. ;) The code is based on three observations: 1) Sorting and exploding can be interleaved to create version that can stream results in an on-line fashion. 2) There is a standard formulation of this pattern in terms of folds and unfolds (= catamorphisms and anamorphisms). 3) Lazy evaluation can be used to make this look like an off-line algorithm. To my surprise, I don't have good references for these, but maybe the following can help a bit. Something similar to 1) can be found in Graham Hutton. The countdown problem. http://www.cs.nott.ac.uk/~gmh/bib.html#countdown and Richard Bird. A program to solve Sudoku. http://www.cs.tufts.edu/~nr/comp150fp/archive/richard-bird/sudoku.pdf The standard reference for 2) is Meijer et al. Functional programming with bananas, lenses, envelopes and barbed wire. http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125 and 3) is folklore, maybe John Hughes. Why functional programming matters. http://www.cs.chalmers.se/~rjmh/Papers/whyfp.html could serve as an introduction to lazy evaluation. >> Note that there's also the possibility of not expanding the compressed >> wagers at all, and perform set operations directly. For instance, it is >> straightforward to intersect two such sets of size n in O(n^2) time. >> Since n ~ 5000 , n^2 is about the same ballpark as the exploded single >> wager combinations. > > Not sure I quite understand you here. In my mind, set elements *are* > single combinations. It is possible for two quite different-looking > files of compressed wagers to contain exactly the same single wager > elements. So I'm not sure how to compare without some notion of > explosion to single combinations. What I mean is that there are two ways to represent sets of wagers: * A list of single combinations -> [Row a] * A list of compressed wagers -> [Row [a]] To perform set operations, you first convert the latter into the former. But the idea is that there might be a way of performing set operations without doing any conversion. Namely, the compressed wagers are cartesian products which behave well under intersection: the intersection of two compressed wagers is again a compressed wager intersectC :: Eq a => Row [a] -> Row [a] -> Row [a] intersectC [] [] = [] intersectC (xs:xrow) (ys:yrow) = intersect xs ys : intersectC xrow yrow In formulas: intersect (cartesian x) (cartesian y) = cartesian (intersectC x y) for compressed wagers x, y :: Row [a] with intersect = list intersection, for instance Data.List.intersect cartesian = converts a compressed wager to a list of single combinations This allows you to intersect two lists of compressed wagers directly intersect' :: [Row [a]] -> [Row [a]] -> [Row [a]] intersect' xs ys = filter (not . null) $ [intersectC x y | x<-xs, y<-ys] Unfortunately, the result will have quadratic size; but if you have significantly less compressed wagers than single combinations, this may be worth a try. Not to mention that you might be able to compress the result again. Mathematically, this exploits the equations (A ? B) ? (C ? D) = (A ? C) ? (B ? D) "The intersection of two rectangles is another rectangle" and (A ? B) ? (C ? D) = (A ? C) ? (A ? D) ? (B ? C) ? (B ? D) where A,B,C,D are sets. Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com From nicolas.pouillard at gmail.com Sat Jan 9 13:06:30 2010 From: nicolas.pouillard at gmail.com (Nicolas Pouillard) Date: Sat Jan 9 12:39:15 2010 Subject: [Haskell-cafe] Capped lists and |append| In-Reply-To: <3283f7fe1001081538w5d390c14mf5ac33dfc4436be2@mail.gmail.com> References: <3283f7fe1001081538w5d390c14mf5ac33dfc4436be2@mail.gmail.com> Message-ID: <1263058697-sup-5416@peray> Excerpts from John Millikin's message of Sat Jan 09 00:38:15 +0100 2010: > Earlier today I uploaded the capped-list package; I didn't think there > would be any interest, since it's a relatively trivial data structure, > but already there's been three emails and an IRC convo about it. > > In short, this is Heinrich Apfelmus's "Train" type from > , > which showed up in a thread I posted regarding lazy error handling > . > The structure of a Train / CappedList (I like my name better) is: > > data Train a b = Wagon a (Train a b) | Loco b > data CappedList cap a = Next a (CappedList cap a) | Cap cap > > Since uploading, there's been a big problem pointed out to me > regarding this structure, namely the possible definitions of |append|. > Because the list terminus is itself a value, but isn't / shouldn't be > the same type as the elements, either obvious implementation will drop > it. I would suggest: appendWith :: (cap1 -> cap2 -> cap3) -> CappedList cap1 a -> CappedList cap2 a -> CappedList cap3 a Here is some functions I written when reading about this data-type: data Train a b = Wagon a (Train a b) | Caboose b trainToList :: (b -> [a]) -> Train a b -> [a] trainToList f (Wagon x xs) = x : trainToList f xs trainToList f (Caboose x) = f x addCaboose :: b -> [a] -> Train a b addCaboose b [] = Caboose b addCaboose b (x:xs) = Wagon x (addCaboose b xs) caboose :: Train a b -> b caboose (Wagon _ xs) = caboose xs caboose (Caboose x) = x dropCaboose :: Train a b -> [a] dropCaboose = trainToList (const []) updateCaboose :: (b -> Train a c) -> Train a b -> Train a c updateCaboose f (Wagon x xs) = Wagon x (updateCaboose f xs) updateCaboose f (Caboose x) = f x -- change caboose's contents mapCaboose :: (b -> c) -> Train a b -> Train a c mapCaboose f = updateCaboose (Caboose . f) -- append trains and merge cabooses appendTrain :: (b -> c -> d) -> Train a b -> Train a c -> Train a d appendTrain f xs ys = updateCaboose (\b -> updateCaboose (Caboose . f b) ys) xs -- concat trains and merge cabooses concatTrain :: (b -> c -> c) -> c -> [Train a b] -> Train a c concatTrain f = foldr (appendTrain f) . Caboose foldl'TrainWith :: (a -> c -> d) -> (a -> b -> a) -> a -> Train b c -> Train b d foldl'TrainWith p f z (Wagon x xs) = z `seq` Wagon x (foldl'TrainWith p f (f z x) xs) foldl'TrainWith p f z (Caboose x) = Caboose (p z x) foldl'Train :: (a -> b -> a) -> a -> Train b c -> Train b (a,c) foldl'Train = foldl'TrainWith (,) sumTrain :: Num n => Train n a -> Train n (n, a) sumTrain = foldl'Train (+) 0 productTrain :: Num n => Train n a -> Train n (n, a) productTrain = foldl'Train (*) 1 -- For instance to compute both the sum and the product of a train -- modularly: -- -- fst . caboose . sumTrain . productTrain :: Num n => Train n a -> (n , n) concatAndSumCabooses :: Num b => [Train a b] -> Train a b concatAndSumCabooses = concatTrain (+) 0 -- Nicolas Pouillard http://nicolaspouillard.fr From kowey at darcs.net Sat Jan 9 15:39:24 2010 From: kowey at darcs.net (Eric Y. Kow) Date: Sat Jan 9 15:12:11 2010 Subject: [Haskell-cafe] Darcs fundraising 2010 - send us to ZuriHac! ($2000 by 15 Feb) Message-ID: <20100109203923.GC967@dewdrop.local> Dear Haskellers, Since 2008, the Darcs Team has made a big push to find hacking time. We've been streamlining our patch approval processes, running Google Summer of Code projects and holding bi-annual hacking sprints. These efforts are starting to pay off, but we're not quite there yet and we still need your help! If you love Darcs and you want to see it succeed, if you want to see it get faster and easier to use, the best thing you can do is to send us your patches (how about attending a sprint?). But if you cannot do this, you can still support the cause. The 4th Darcs Hacking Sprint will be taking place in March as part of the Zurich Haskell Hackathon. Zurich presents a opportunity for us pull a lot of the Darcs team together, to recruit new developers to the project, and also to mingle with the wider Haskell community. We would love to subsidise travel costs to make it easier for developers to attend this sprint and the one after. Do you think you can help? How about sending just $20 our way? Donating to Darcs is now easier than ever, as we are now proud members of the Software Freedom Conservancy. You can either send us a cheque or use Paypal or Google Checkout. Furthermore, donations from US tax-payers will now be tax-deductible. More details below, or at Many thanks! Eric PS. If you could send me an email when you make a donation, I can provide a daily update on our fundraising status! Last year, we managed to raise a thousand dollars to send Darcs hackers to the Utrecht and Vienna hackathons. This year, I want to see if we can raise $2000 for Darcs hacking by the 14th of February. Stay tuned at http://darcs.net/donations.html for our progress. Only $1710 to go... :-) Donating by check (USA) ---------------------------------------------------------------------- If you have a US bank account, we prefer donations by check as they will go the longest way. Checks should be made payable to "Software Freedom Conservancy, Inc.", with "Directed donation: Darcs" in the memo. They can be mailed to Software Freedom Conservancy 1995 BROADWAY FL 17 NEW YORK NY 10023-5882 USA Donating by Paypal or Google Checkout ---------------------------------------------------------------------- Please visit http://darcs.net/donations.html for more details. -- Eric Kow PGP Key ID: 08AC04F9 -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 195 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100109/64e04e19/attachment.bin From gcross at phys.washington.edu Sat Jan 9 16:44:03 2010 From: gcross at phys.washington.edu (Gregory Crosswhite) Date: Sat Jan 9 16:16:57 2010 Subject: [Haskell-cafe] HackageDB Question Message-ID: <797CCC96-A042-45D6-88BA-B2EE500A4CA0@phys.washington.edu> How does HackageDB generate the documentation for uploaded packages? Specifically, if I am using my own build system rather than Cabal, then what do I need to do (e.g., what interface do I need to supply) for HackageDB to correctly generate the documentation? I've glanced through the source code posted at http://darcs.haskell.org/hackage-scripts/, but I am having trouble finding the code which generates the documentation. Thanks! Greg From ross at soi.city.ac.uk Sat Jan 9 17:14:03 2010 From: ross at soi.city.ac.uk (Ross Paterson) Date: Sat Jan 9 16:46:29 2010 Subject: [Haskell-cafe] HackageDB Question In-Reply-To: <797CCC96-A042-45D6-88BA-B2EE500A4CA0@phys.washington.edu> References: <797CCC96-A042-45D6-88BA-B2EE500A4CA0@phys.washington.edu> Message-ID: <20100109221403.GA18394@soi.city.ac.uk> On Sat, Jan 09, 2010 at 01:44:03PM -0800, Gregory Crosswhite wrote: > How does HackageDB generate the documentation for uploaded packages? Specifically, if I am using my own build system rather than Cabal, then what do I need to do (e.g., what interface do I need to supply) for HackageDB to correctly generate the documentation? I assume you're using Cabal, but you mean a custom Setup.hs. It relies on your Setup.hs doing the same as the simple one (as documented in the Cabal User's Guide) for setup configure --haddock-option=... setup haddock --html-location=... --hyperlink-source setup haddock --hoogle From wren at freegeek.org Sat Jan 9 18:35:47 2010 From: wren at freegeek.org (wren ng thornton) Date: Sat Jan 9 18:02:02 2010 Subject: [Haskell-cafe] Lambda's In-Reply-To: <4c44d90b0912311009l7a376094s7c8a932136b504b4@mail.gmail.com> References: <29bf512f0912310035nff870d9y25dd1f97bac2c1d3@mail.gmail.com> <29bf512f0912311004v3b13edfdp337671e71575bb4@mail.gmail.com> <4c44d90b0912311009l7a376094s7c8a932136b504b4@mail.gmail.com> Message-ID: <4B4912D3.7080706@freegeek.org> Thomas DuBuisson wrote: > ----- Michael Snoyman : >> ----- Ivan Miljenovic : >>> ----- Michael Snoyman : >>>> Some of us prefer not to look at that kind of material. I'd appreciate >>>> if, in the future, you could either refrain from sending such links or >>>> making it clear that they contain objectionable content. >>> >>> Agreed; however, looking at the URL does hint that it's NSFW: >> >> That's true, but frankly I've come to expect a certain standard on this >> mailing list which is almost always respected. I would prefer *not* needing >> to start second guessing every link posted here. > > I agree with Michael in this - such material is out of place for the cafe. +1. This list is not the appropriate venue for that sort of thing. Even if folks don't mind the NSFW, some of us work to combat the sexist culture that pervades computer science and prevents women from embracing a love of mathematics and programming. Haskell is generally more welcoming than other communities; don't wreck it. -- Live well, ~wren From wren at freegeek.org Sat Jan 9 18:45:10 2010 From: wren at freegeek.org (wren ng thornton) Date: Sat Jan 9 18:11:24 2010 Subject: [Haskell-cafe] Re: Data.Ring -- Pre-announce In-Reply-To: References: Message-ID: <4B491506.3030400@freegeek.org> Tom Tobin wrote: > ----- Heinrich Apfelmus wrote: >> Since the name Ring is already taken by an ubiquitous mathematical >> structure, and thus already in hackage for example as Algebra.Ring in >> the numeric-prelude , I suggest to call the data structure Necklace >> instead. > > Is Necklace a known name for this data structure? If not Ring, I was > thinking Circular might be an appropriate name. I'm not sure if there's a canonical name, except perhaps "circular queue". Necklace is cute, though Circular or CircleQueue might be better. I'd also advise strongly against using Ring in order to avoid confusing nomenclature. (Loop should be avoided for similar reasons.) -- Live well, ~wren From korpios at korpios.com Sat Jan 9 19:55:22 2010 From: korpios at korpios.com (Tom Tobin) Date: Sat Jan 9 19:28:07 2010 Subject: [Haskell-cafe] Lambda's In-Reply-To: <4B4912D3.7080706@freegeek.org> References: <29bf512f0912310035nff870d9y25dd1f97bac2c1d3@mail.gmail.com> <29bf512f0912311004v3b13edfdp337671e71575bb4@mail.gmail.com> <4c44d90b0912311009l7a376094s7c8a932136b504b4@mail.gmail.com> <4B4912D3.7080706@freegeek.org> Message-ID: On Sat, Jan 9, 2010 at 5:35 PM, wren ng thornton wrote: > Even if folks don't mind the NSFW, some of us work to combat the sexist > culture that pervades computer science and prevents women from embracing > a love of mathematics and programming. ::sigh:: As much as I didn't care for the original post, I care for politics even less. ^_^ Let's just leave it at "don't post so-called 'NSFW' content" as a healthy rule of thumb. From jason.dusek at gmail.com Sat Jan 9 20:08:48 2010 From: jason.dusek at gmail.com (Jason Dusek) Date: Sat Jan 9 19:41:34 2010 Subject: [Haskell-cafe] Lambda's In-Reply-To: <29bf512f0912310035nff870d9y25dd1f97bac2c1d3@mail.gmail.com> References: <29bf512f0912310035nff870d9y25dd1f97bac2c1d3@mail.gmail.com> Message-ID: <42784f261001091708n72433682h4f60d908f5e27c1d@mail.gmail.com> I believe GMail put the original message in my SPAM folder. Which is just as well. Let me re-affirm the collective rejection of this post. Very no! -- Jason Dusek From tphyahoo at gmail.com Sun Jan 10 00:24:03 2010 From: tphyahoo at gmail.com (Thomas Hartman) Date: Sat Jan 9 23:56:47 2010 Subject: [Haskell-cafe] unexpected behavior from filterM doesFileExist =<< getDirectoryContents Message-ID: <910ddf451001092124p26261d08wf5ecc033e5a8a74a@mail.gmail.com> Can somebody explain this? > getDirectoryContents inD ["..","#sanity.txt#",".","sanity.txt","etc.txt","patchTagDir.txt","jail.txt","notjail.txt","alldata.txt","allobjs.txt","namesNSizes.txt"] > filterM doesFileExist =<< getDirectoryContents inD > ["sanity.txt"] From allbery at ece.cmu.edu Sun Jan 10 00:30:31 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Sun Jan 10 00:03:39 2010 Subject: [Haskell-cafe] unexpected behavior from filterM doesFileExist =<< getDirectoryContents In-Reply-To: <910ddf451001092124p26261d08wf5ecc033e5a8a74a@mail.gmail.com> References: <910ddf451001092124p26261d08wf5ecc033e5a8a74a@mail.gmail.com> Message-ID: <498E3611-B5D1-40F5-833F-0A7BB4B7E5C1@ece.cmu.edu> On Jan 10, 2010, at 00:24 , Thomas Hartman wrote: > Can somebody explain this? > >> getDirectoryContents inD > > ["..","#sanity > .txt > #",".","sanity > .txt > ","etc > .txt > ","patchTagDir > .txt > ","jail > .txt","notjail.txt","alldata.txt","allobjs.txt","namesNSizes.txt"] > >> filterM doesFileExist =<< getDirectoryContents inD > >> ["sanity.txt"] My first guess is that inD isn't "."; getDirectoryContents doesn't fully qualify the names it returns, so doesFileExist looks in the current directory for the bare names returned. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100110/cc9e84a4/PGP.bin From tphyahoo at gmail.com Sun Jan 10 01:33:14 2010 From: tphyahoo at gmail.com (Thomas Hartman) Date: Sun Jan 10 01:05:57 2010 Subject: [Haskell-cafe] unexpected behavior from filterM doesFileExist =<< getDirectoryContents In-Reply-To: <498E3611-B5D1-40F5-833F-0A7BB4B7E5C1@ece.cmu.edu> References: <910ddf451001092124p26261d08wf5ecc033e5a8a74a@mail.gmail.com> <498E3611-B5D1-40F5-833F-0A7BB4B7E5C1@ece.cmu.edu> Message-ID: <910ddf451001092233m7bb5b2fbob1779dc0814545e8@mail.gmail.com> Thanks, that was it. Dud question. 2010/1/9 Brandon S. Allbery KF8NH : > On Jan 10, 2010, at 00:24 , Thomas Hartman wrote: >> >> Can somebody explain this? >> >>> getDirectoryContents inD >> >> ["..","#sanity >> .txt >> #",".","sanity >> .txt >> ","etc >> .txt >> ","patchTagDir >> .txt >> ","jail >> .txt","notjail.txt","alldata.txt","allobjs.txt","namesNSizes.txt"] >> >>> filterM doesFileExist =<< getDirectoryContents inD >> >>> ["sanity.txt"] > > > My first guess is that inD isn't "."; getDirectoryContents doesn't fully > qualify the names it returns, so doesFileExist looks in the current > directory for the bare names returned. > > -- > brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com > system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu > electrical and computer engineering, carnegie mellon university ? ?KF8NH > > > From ivan.miljenovic at gmail.com Sun Jan 10 06:32:51 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Sun Jan 10 06:05:43 2010 Subject: [Haskell-cafe] ANNOUNCE: SourceGraph-0.6.0.2 In-Reply-To: <87tyuw1xgq.fsf@gmail.com> (Ivan Lazar Miljenovic's message of "Sat, 09 Jan 2010 00:29:41 +1000") References: <87y6k81ygu.fsf@gmail.com> <87tyuw1xgq.fsf@gmail.com> Message-ID: <87my0mqjoc.fsf_-_@gmail.com> I've just uploaded a new version that works with haskell-src-exts-1.6.0 (all it needed was to increase the upper bound in the cabal file! \o/). On another note, anyone know why Niklas Broberg hasn't been making any release statements recently to say what the changes are, etc. for haskell-src-exts? Ivan Lazar Miljenovic writes: > I realised soon after I sent the announcement email that there was a bug > in one of the new "subtle" features that I didn't list, namely the > background shading of directories in import visualisation. As such, > SourceGraph 0.6.0.1 contains this fix. > > There were also two other features in 0.6.0.0 that I forgot to mention: > > * SourceGraph will (well, should; I haven't managed to come across a > situation where it occurs anyway) no longer throw a fit if Graphviz > throws an error when visualising a graph; instead it will just put an > error message into the generated report. > > * The generated Dot code is also saved in the SourceGraph/graphs/ > subdirectory, so you can tweak the call graphs of your programs. > > Ivan Lazar Miljenovic writes: > >> I'm pleased to announce the latest releases of SourceGraph [1] and >> Graphalyze [2]. >> >> [1]: http://hackage.haskell.org/package/SourceGraph >> [2]: http://hackage.haskell.org/package/Graphalyze >> >> SourceGraph is a program that performs static code analysis on Haskell >> projects on the by applying graph theoretic techniques to the project's >> call graph. Graphalyze is a library for analysing discrete data using >> graph theory, and as such performs the heavy lifting for SourceGraph. >> >> Sample analysis reports generated by SourceGraph are available at >> http://code.haskell.org/~ivanm/Sample_SourceGraph/SampleReports.html . >> I will also be demoing SourceGraph at PEPM [3] in Madrid on 19 January. >> >> [3]: http://www.program-transformation.org/PEPM10/ >> >> Changes since the previous version include: >> >> * Now supports "implicitly exported" entities (as requested by Curt >> Sampson). This includes instantiated class methods from other >> modules and functions, etc. that start with an underscore (see >> http://www.haskell.org/ghc/docs/latest/html/users_guide/options-sanity.html >> for more information). >> >> * All inaccessible entities are now reported, not just those that were >> root nodes in the call graph. >> >> * Edges are now colour-coded based upon whether they are part of a >> clique, cycle or a chain. >> >> * Level-based analyses: visualise how deep an entity is from those >> exported entities. >> >> * A re-done TODO that lists in detail what is planned for SourceGraph. >> >> * Lots of under-the-hood changes that don't sound as interesting as the >> above :-( -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From niklas.broberg at gmail.com Sun Jan 10 07:43:41 2010 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Sun Jan 10 07:16:24 2010 Subject: [Haskell-cafe] ANNOUNCE: SourceGraph-0.6.0.2 In-Reply-To: <87my0mqjoc.fsf_-_@gmail.com> References: <87y6k81ygu.fsf@gmail.com> <87tyuw1xgq.fsf@gmail.com> <87my0mqjoc.fsf_-_@gmail.com> Message-ID: > On another note, anyone know why Niklas Broberg hasn't been making any > release statements recently to say what the changes are, etc. for > haskell-src-exts? Because it's been so many relatively small releases of late that I haven't wanted to spam the lists. :-) If you want to keep up to date, the changes can be found here: http://code.haskell.org/haskell-src-exts/CHANGELOG Cheers, /Niklas From ndmitchell at gmail.com Sun Jan 10 08:06:53 2010 From: ndmitchell at gmail.com (Neil Mitchell) Date: Sun Jan 10 07:39:35 2010 Subject: [Haskell-cafe] Hackage down Message-ID: <404396ef1001100506v1413c47jdd6628eadfd31797@mail.gmail.com> Hi Hackage is down: http://downforeveryoneorjustme.com/hackage.haskell.org Thanks, Neil From ivan.miljenovic at gmail.com Sun Jan 10 08:15:06 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Sun Jan 10 07:47:54 2010 Subject: [Haskell-cafe] ANNOUNCE: SourceGraph-0.6.0.2 In-Reply-To: (Niklas Broberg's message of "Sun, 10 Jan 2010 13:43:41 +0100") References: <87y6k81ygu.fsf@gmail.com> <87tyuw1xgq.fsf@gmail.com> <87my0mqjoc.fsf_-_@gmail.com> Message-ID: <87iqbaqexx.fsf@gmail.com> Niklas Broberg writes: > Because it's been so many relatively small releases of late that I > haven't wanted to spam the lists. :-) I for one say spam away! Especially with a change like 1.5 -> 1.6. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From will_n48 at yahoo.com Sun Jan 10 11:28:01 2010 From: will_n48 at yahoo.com (Will Ness) Date: Sun Jan 10 11:01:08 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001071713.39165.daniel.is.fischer@web.de> <201001090452.48889.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > Am Freitag 08 Januar 2010 19:45:47 schrieb Will Ness: > > Daniel Fischer web.de> writes: > > > > > > > mergeSP :: Integral a => People a -> People a -> People a > > > mergeSP p1@(P a _) p2 = P (a ++ vips mrgd) (dorks mrgd) > > > where > > > mrgd = spMerge (dorks p1) (vips p2) (dorks p2) > > > spMerge l1 [] l3 = P [] (merge l1 l3) > > > spMerge ~l1@(x:xs) l2@(y:ys) l3 = case compare x y of > > > LT -> celebrate x (spMerge xs l2 l3) > > > EQ -> celebrate x (spMerge xs ys l3) > > > GT -> celebrate y (spMerge l1 ys l3) > > > > > > ---------------------------------------------------------------------- Actually, the minimal edit that does the trick (of eliminating the space leak that you've identified) for my original code is just mergeSP (a,b) ~(c,d) = let (bc,bd) = spMerge b c d in (a ++ bc, bd) where spMerge b [] d = ([] ,merge b d) spMerge b@(x:xs) c@(y:ys) d = case compare x y of LT -> (x:u,v) where (u,v) = spMerge xs c d EQ -> (x:u,v) where (u,v) = spMerge xs ys d GT -> (y:u,v) where (u,v) = spMerge b ys d spMerge [] c d = ([] ,merge c d) which hardly looks at all different at the first glance. Just for reference, it was {- mergeSP (a,b) ~(c,d) = let (bc,b') = spMerge b c in (a ++ bc, merge b' d) where spMerge b@(x:xs) c@(y:ys) = case compare x y of LT -> (x:u,v) where (u,v) = spMerge xs c EQ -> (x:u,v) where (u,v) = spMerge xs ys GT -> (y:u,v) where (u,v) = spMerge b ys spMerge b [] = ([] ,b) spMerge [] c = ([] ,c) -} spMerge of course is not tail recursive here in both versions if seen through the imperative eyes. But lazy evaluation makes it effectively so. The important thing is, when the final point is reached, there's no outstanding context - everything is present. There should be a name for such concept. This is very similar to late instantiation in Prolog (programming with "holes"), and I think this *would* pass as a tail-recursive function /there/. Even in the new code the compiler could've internally held on to the original pair and only deconstructed the 'd' out of it at the final call to merge, recreating the space leak. It could just as well have recognized that 'd' isn't changed inside spMerge (we're pure in Haskell after all) and deconstructed the pair in the original code. Something is missing here. > As it turns out, the important things are > > 1. a feeder and separate lists of multiples for the feeder and the runner, > for the reasons detailed earlier (two-step feeding and larger wheel are > pleasing but minor optimisations). > > 2. a strict pattern in tfold > > 3. moving the merge inside spMerge > > Is this the state of our _best_ Haskell compiler???? > > > > Yes. It's still a "do what I tell you to" compiler, even if a pretty slick > one, not a "do what I mean" compiler. Sometimes, what you tell the compiler > isn't what you wanted. > It's easier to predict when you give detailed step by step instructions. > From jfredett at gmail.com Sun Jan 10 12:01:19 2010 From: jfredett at gmail.com (jfredett@gmail.com) Date: Sun Jan 10 11:34:07 2010 Subject: [Haskell-cafe] Haskell Weekly News: Issue 145 - January 10, 2010 Message-ID: <4b4a07df.9553f10a.6e3c.17fd@mx.google.com> --------------------------------------------------------------------------- Haskell Weekly News http://sequence.complete.org/hwn/20100110 Issue 145 - January 10, 2010 --------------------------------------------------------------------------- Welcome to issue 145 of HWN, a newsletter covering developments in the [1]Haskell community. Welcome back Haskellers to the HWN! After a short hiatus we return with a megaedition covering the last three weeks of Haskell news and discussion. Needless to say, lots of new package and event announcements, as well as some really great discussions (the discussion about 'lawless' uninstances of Functors was particularly interesting) over the holiday break. Hopefully everyone had a safe and happy holiday season, and is back now steadily working off the winter-weight (in accordance with resolutions or no) by tapping steadily at the keyboard, producing wonderful new packages for me to place in this, your Haskell Weekly News! Announcements Last CfP for TGC 2010: EXTENDED deadline Jan. 20 2010. Emilio Tuosto [2]announced an extension to the TGC'10 call for papers. SourceGraph-0.6.0.0 and Graphalyze-0.9.0.0. Ivan Lazar Miljenovic [3]announced new releases of the SourceGraph and Graphalyze packages. Streaming Component Combinators 0.4. Mario Blazevic [4]announced version 0.4 of Streaming Component Combinators (SCC). safer-file-handles-0.1. Bas van Dijk [5]announced a new member of the 'monadic regions' family -- safer-file-handles. This package provides safety features on top of System.IO for handling file handles and operations. HOR 2010 1st CALL FOR ABSTRACTS. Frederic Blanqui [6]1f4e gmane.comp.lang.haskell.general/17710 announced the first call for abstracts for the Fifth International Workshop on Higher-Order Rewriting. vty-4.2.1.0. Corey O'Connor [7]announced a new version of the vty package. stm-io-hooks-0.6.0. Peter Robinson [8]announced a new version of stm-io-hooks. This version includes major interface changes, including the elimation of the 'onRetry' combinator. hecc-0.2. Marcel Fourne [9]announced the second release of his elliptic curve cryptography package, hecc. This release includes a license change to the BSD3 license, speed improvements, and new algorithms for point multiplication, as well as other changes. ghc-6.12.1 binary package for OpenSolaris. Michael Lee [10]announced a binary package availability of ghc-6.12 for OpenSolaris. Final Call for Participation: TLDI'10. Andrew Kennedy [11]announced the final call for participation in TLDI'10, the Workshop on Types in Language Design and Implementation. Haskell Web News: Looking back on 2009. Don Stewart [12]announced The Haskell Web News, a monthly summary of the hottest news about the Haskell programming language. hakyll-0.4. Jasper Van der Jeugt [13]announced the release of hakyll, a static site generator library. system-uuid-1.2.0. Jason Dusek [14]announced a new release of system-uuid. New versions of ALL the monadic regions packages. Bas van Dijk [15]announced a new version of all of the monadic regions packages, explanation of what this means is best left to the original post, linked previously. tuntap-0.0.1. John Van Enk [16]announced a new package, extracted from his in-progress VPN project. This package provides access to the TUN/TAP device in Linux. CPython / libpython bindings. John Millikin [17]announced a package providing bindings to the C API for CPython/libpython. Discussion Typed Configuration Files. Sebastian Fischer [18]asked about whether there was an analogue to CmdArgs for config files. Review request for my permutations implementation. CK Kashyap [19]asked for a review of his implementation of a function for finding permutations -- in addition to a review he asked for earlier for code involving monads. The result is a nice pair of threads with introductory material about idiomatic, efficient Haskell code. lawless instances of Functor. Paul Brauner [20]asked about 'lawless' instances (Editor's Note: more so -- 'uninstances', since by definition, it cannot be a functor without satisfying the laws, even if it an instance can be written) of the `Functor` class. This is in an effort to better understand how Functors work in Haskell and in the wider theory. Blog noise [21]Haskell news from the [22]blogosphere. Blog posts from people new to the Haskell community are marked with >>>, be sure to welcome them! * Neil Mitchell: [23]Using .ghci files to run projects. * Tom Moertel: [24]A formal language for recipes: brain dump. * Mark Jason Dominus: [25]A monad for probability and provenance. * Alex Mason: [26]A small follow up. * Russell O'Connor: [27]Constructive Classical Completeness. * Galois, Inc: [28]GHC Nominated for Programming Language Award. * Neil Brown: [29]CHP vs CML, Forking and Picky Receivers. * Conal Elliott: [30]Is Haskell a purely functional language?. * Conal Elliott: [31]Can functional programming be liberated from the von Neumann paradigm?. * Real-World Haskell: [32]Real World Haskell in Japaneseâ宿¦ã§å¦ã¶é¢æ°åè¨èªããã°ã©ãã³ã°. * Conal Elliott: [33]Garbage collecting the semantics of FRP. * Alex Mason: [34]Why I love Cereal. * Mark Jason Dominus: [35]A short bibliography of probability monads. * Conal Elliott: [36]Communication, curiosity, and personal style. * Epilogue for Epigram: [37]Bidirectional Basics. * Neil Mitchell: [38]Explaining Haskell IO without Monads. * Conal Elliott: [39]Is program proving viable and useful?. * Conal Elliott: [40]Why program with continuous time?. Quotes of the Week * fasta: Haskell is like an efficient version of Python and is used for the same things. * koeien37: there are the languages that everybody complains about, and the languages that nobody use * Pseudonym: Olegs can be warded off by adding a note claiming that it's impossible to implement in the type system. * elly: I leave for five minutes and godel numbering of endofunctors is invokved as a potential proof that the universe is simulated. Thanks, #haskell :P * kmc: a monad is like an invisible train filled with jello traveling backwards in time * conal: "Obviously" is one of those words that is most useful when it is least true * Jafet: Javascript is pretty much a DSL for making your web browser take up more CPU * copumpkin: limpac: in this channel we're all automata with no feelings, except for the occasional feeling of hate. * dmhouse: I'm not sure it's working correctly but it sure is fast... * Cale: We need a bunch of "Will it monad?" video clips, with "It monads!" at the end of each. * merijn: I run on HST (Hacker Standard Time) which is essentially current time zone -3 * ray: [about an anti-FP blog post] i came up with some contrived example, announced that it's impossible, and therefore FP sucks * hiredman: I used to think "dons" was a title, like people who were recognized as being really good at haskell were called dons About the Haskell Weekly News New editions are posted to [41]the Haskell mailing list as well as to [42]the Haskell Sequence and [43]Planet Haskell. [44]RSS is also available, and headlines appear on [45]haskell.org. To help create new editions of this newsletter, please see the information on [46]how to contribute. Send stories to jfredett . at . gmail . dot . com. The darcs repository is available at darcs get [47]http://patch-tag.com/r/jfredett/HWN2/pullrepo HWN2 . References 1. http://haskell.org/ 2. http://article.gmane.org/gmane.comp.lang.haskell.general/17716 3. http://article.gmane.org/gmane.comp.lang.haskell.general/17714 4. http://article.gmane.org/gmane.comp.lang.haskell.general/17713 5. http://article.gmane.org/gmane.comp.lang.haskell.general/17711 6. http://article.gmane.org/ 7. http://article.gmane.org/gmane.comp.lang.haskell.general/17705 8. http://article.gmane.org/gmane.comp.lang.haskell.general/17704 9. http://article.gmane.org/gmane.comp.lang.haskell.general/17701 10. http://article.gmane.org/gmane.comp.lang.haskell.general/17700 11. http://article.gmane.org/gmane.comp.lang.haskell.general/17699 12. http://article.gmane.org/gmane.comp.lang.haskell.general/17698 13. http://article.gmane.org/gmane.comp.lang.haskell.cafe/68864 14. http://article.gmane.org/gmane.comp.lang.haskell.cafe/68857 15. http://article.gmane.org/gmane.comp.lang.haskell.cafe/68827 16. http://article.gmane.org/gmane.comp.lang.haskell.cafe/68807 17. http://article.gmane.org/gmane.comp.lang.haskell.cafe/68388 18. http://thread.gmane.org/gmane.comp.lang.haskell.cafe/68865 19. http://thread.gmane.org/gmane.comp.lang.haskell.cafe/68811 20. http://thread.gmane.org/gmane.comp.lang.haskell.cafe/68711 21. http://planet.haskell.org/ 22. http://haskell.org/haskellwiki/Blog_articles 23. http://neilmitchell.blogspot.com/2010/01/using-ghci-files-to-run-projects.html 24. http://blog.moertel.com/articles/2010/01/08/a-formal-language-for-recipes-brain-dump 25. http://blog.plover.com/prog/haskell/probmonad.html 26. http://random.axman6.com/blog/?p=139 27. http://r6.ca/blog/20100107T035902Z.html 28. http://www.galois.com/blog/2010/01/06/ghc-nominated-for-programming-language-award/ 29. http://chplib.wordpress.com/2010/01/06/chp-vs-cml-forking-and-picky-receivers/ 30. http://conal.net/blog/posts/is-haskell-a-purely-functional-language/ 31. http://conal.net/blog/posts/can-functional-programming-be-liberated-from-the-von-neumann-paradigm/ 32. http://www.realworldhaskell.org/blog/2010/01/05/real-world-haskell%e2%80%94%e5%ae%9f%e6%88%a6%e3%81%a7%e5%ad%a6%e3%81%b6%e9%96%a2%e6%95%b0%e5%9e%8b%e8%a8%80%e8%aa%9e%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%9f%e3%83%b3%e3%82%b0/ 33. http://conal.net/blog/posts/garbage-collecting-the-semantics-of-frp/ 34. http://random.axman6.com/blog/?p=124 35. http://blog.plover.com/prog/haskell/probmonad-refs.html 36. http://conal.net/blog/posts/communication-curiosity-and-personal-style/ 37. http://www.e-pig.org/epilogue/?p=283 38. http://neilmitchell.blogspot.com/2010/01/haskell-io-without-monads.html 39. http://conal.net/blog/posts/is-program-proving-viable-and-useful/ 40. http://conal.net/blog/posts/why-program-with-continuous-time/ 41. http://www.haskell.org/mailman/listinfo/haskell 42. http://sequence.complete.org/ 43. http://planet.haskell.org/ 44. http://sequence.complete.org/node/feed 45. http://haskell.org/ 46. http://haskell.org/haskellwiki/HWN 47. http://patch-tag.com/r/jfredett/HWN2/pullrepo%20HWN2 From gue.schmidt at web.de Sun Jan 10 13:38:53 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Sun Jan 10 13:12:00 2010 Subject: [Haskell-cafe] Design question, HTML for GUIs? Message-ID: <4B4A1EBD.1080605@web.de> Hi everyone, as probably most people I find the GUI part of any application to be the hardest part. It just occurred to me that I *could* write my wxHaskell desktop application as a web app too. When the app starts, a haskell web server start listening on localhost port 8080 for example and I fire up a browser to page localhost:8080 without the user actually knowing too much about it. Is that a totally stupid idea? Which haskell web servers would make good candidates? Are there any *continuation* based web server in haskell, something similar to Smalltalk's Seaside? Is Hyena continuation-based? G?nther From gwern0 at gmail.com Sun Jan 10 13:57:08 2010 From: gwern0 at gmail.com (Gwern Branwen) Date: Sun Jan 10 13:29:50 2010 Subject: [Haskell-cafe] Design question, HTML for GUIs? In-Reply-To: <4B4A1EBD.1080605@web.de> References: <4B4A1EBD.1080605@web.de> Message-ID: 2010/1/10 G?nther Schmidt : > Hi everyone, > > as probably most people I find the GUI part of any application to be the > hardest part. > > It just occurred to me that I *could* write my wxHaskell desktop application > as a web app too. > > When the app starts, a haskell web server start listening on localhost port > 8080 for example and I fire up a browser to page localhost:8080 without the > user actually knowing too much about it. > > Is that a totally stupid idea? > Which haskell web servers would make good candidates? No; Happstack. See Gitit for an example - it is a wiki, but people use it locally all the time, such as myself or Don Stewart. -- gwern From jochem at functor.nl Sun Jan 10 14:00:51 2010 From: jochem at functor.nl (Jochem Berndsen) Date: Sun Jan 10 13:33:34 2010 Subject: [Haskell-cafe] Design question, HTML for GUIs? In-Reply-To: <4B4A1EBD.1080605@web.de> References: <4B4A1EBD.1080605@web.de> Message-ID: <4B4A23E3.5090206@functor.nl> G?nther Schmidt wrote: > as probably most people I find the GUI part of any application to be the > hardest part. > > It just occurred to me that I *could* write my wxHaskell desktop > application as a web app too. > > When the app starts, a haskell web server start listening on localhost > port 8080 for example and I fire up a browser to page localhost:8080 > without the user actually knowing too much about it. > > Is that a totally stupid idea? No, this is not (necessarily) a stupid idea. In fact it might be a good idea in a lot of cases. A downside is, that you lose the functionality for user access control provided by the OS on multi-user machines (i.e., other users working on the same machine can connect to localhost:8080 too). This might or might not be a concern for you. Regards, Jochem -- Jochem Berndsen | jochem@functor.nl | jochem@????.com From jgm at berkeley.edu Sun Jan 10 16:20:27 2010 From: jgm at berkeley.edu (John MacFarlane) Date: Sun Jan 10 15:54:53 2010 Subject: [Haskell-cafe] Re: Design question, HTML for GUIs? In-Reply-To: <4B4A1EBD.1080605@web.de> References: <4B4A1EBD.1080605@web.de> Message-ID: <20100110212026.GA14420@protagoras.phil.berkeley.edu> +++ G?nther Schmidt [Jan 10 10 19:38 ]: > Hi everyone, > > as probably most people I find the GUI part of any application to be > the hardest part. > > It just occurred to me that I *could* write my wxHaskell desktop > application as a web app too. > > When the app starts, a haskell web server start listening on > localhost port 8080 for example and I fire up a browser to page > localhost:8080 without the user actually knowing too much about it. > > Is that a totally stupid idea? > Which haskell web servers would make good candidates? > Are there any *continuation* based web server in haskell, something > similar to Smalltalk's Seaside? Happstack is not continuation based, but Chris Eidhof shows how to use Happstack with continuations here: http://gist.github.com/260052 And Chris Smith has built a package: http://bifunctor.homelinux.net/~roel/cgi-bin/hackage-scripts/package/happstack-dlg-0.1.1 John From michael at snoyman.com Sun Jan 10 16:32:27 2010 From: michael at snoyman.com (Michael Snoyman) Date: Sun Jan 10 16:05:11 2010 Subject: [Haskell-cafe] Design question, HTML for GUIs? In-Reply-To: <4B4A1EBD.1080605@web.de> References: <4B4A1EBD.1080605@web.de> Message-ID: <29bf512f1001101332i67175417v94a5dd84cdf00709@mail.gmail.com> I wrote a package to turn Hack applications into standalone apps using Webkit. The code is available at http://github.com/snoyberg/hack-handler-webkit. However, it's currently Linux-only. However, if I was going to write a desktop app based on an HTML GUI, I would bundle Webkit like this. It fixes such annoyances as "I closed the window but the program is still running." Michael 2010/1/10 G?nther Schmidt > Hi everyone, > > as probably most people I find the GUI part of any application to be the > hardest part. > > It just occurred to me that I *could* write my wxHaskell desktop > application as a web app too. > > When the app starts, a haskell web server start listening on localhost port > 8080 for example and I fire up a browser to page localhost:8080 without the > user actually knowing too much about it. > > Is that a totally stupid idea? > Which haskell web servers would make good candidates? > Are there any *continuation* based web server in haskell, something similar > to Smalltalk's Seaside? > Is Hyena continuation-based? > > G?nther > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100110/b8329954/attachment-0001.html From sebf at informatik.uni-kiel.de Sun Jan 10 17:29:29 2010 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Sun Jan 10 17:02:11 2010 Subject: [Haskell-cafe] Typed Configuration Files In-Reply-To: References: <0102AD94-4A7C-47F0-A412-748FF4850448@informatik.uni-kiel.de> Message-ID: >> Is there something similar for parsing config files? > > If you write one I most certainly will use it! ;) You (we) can already start using the cmdargs package to parse config files. Upon my feature request to add a function to the cmdargs package that allows to add default arguments, Neil pointed out that the function System.Environment.withArgs can be used to get the same effect without changes to the cmdargs package. Here is a complete example: {-# LANGUAGE DeriveDataTypeable #-} import System.Environment import System.Console.CmdArgs data Conf = Conf { option :: Bool } deriving (Show,Data,Typeable) myConf = mode $ Conf { option = enum False [True,False] } main = print =<< getConfig "my.conf" "My Program v0.0" myConf getConfig configFileName welcomeMsg modeDesc = do originalArgs <- getArgs argsFromFile <- words `fmap` readFile configFileName withArgs (argsFromFile ++ originalArgs) (cmdArgs welcomeMsg [modeDesc]) If you save the String '--true' in the file 'my.conf', this program reads the config from the file and prints it: # runhaskell typed-config.hs Conf {option = True} You can overwrite the default behaviour with command line arguments: # runhaskell typed-config.hs --false Conf {option = False} After parsing a config file into command-line arguments, the parsing of the typed `Config` comes for free. Sebastian P.S.: Instead of the `words` function one would use some smarter function that translates real config files into command-line arguments, but the fez-conf package (which provides such functionality) segfaults on my computer. Depending on how one specifies the mode value, one may not be able to overwrite default options. For example, the usual translation of the boolean field above is a single flag --option that can be present or absent. I did not find a way to unset a set flag other than declaring it as an enum flag. This could be improved if flags without arguments would support optional arguments like '--option=yes/no' or similar. (Btw. the documentation of enum seems wrong, the given example does not typecheck). -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From gue.schmidt at web.de Sun Jan 10 21:44:45 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Sun Jan 10 21:17:51 2010 Subject: [Haskell-cafe] mtl and transformers Message-ID: <4B4A909D.6060901@web.de> Hi, when I cabal-installed the iteratee package, the transformers package was also installed as a dependency. Now when I run applications that import Control.Monad.Transformers I get this: Could not find module `Control.Monad.Trans': it was found in multiple packages: transformers-0.1.4.0 mtl-1.1.0.2 What's the work around for situations like this? G?nther From ivan.miljenovic at gmail.com Sun Jan 10 21:49:44 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Sun Jan 10 21:22:30 2010 Subject: [Haskell-cafe] mtl and transformers In-Reply-To: <4B4A909D.6060901@web.de> (=?utf-8?Q?=22G=C3=BCnther?= Schmidt"'s message of "Mon, 11 Jan 2010 03:44:45 +0100") References: <4B4A909D.6060901@web.de> Message-ID: <87y6k5we2f.fsf@gmail.com> G?nther Schmidt writes: > Could not find module `Control.Monad.Trans': > it was found in multiple packages: transformers-0.1.4.0 > mtl-1.1.0.2 There's a way of specifying it at the top of whichever file you're using, but so far my workaround in this situation is to use "ghc-pkg hide" on whichever of those packages I don't use in my code. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From gue.schmidt at web.de Sun Jan 10 21:59:28 2010 From: gue.schmidt at web.de (=?UTF-8?B?R8O8bnRoZXIgU2NobWlkdA==?=) Date: Sun Jan 10 21:32:11 2010 Subject: [Haskell-cafe] mtl and transformers In-Reply-To: <87y6k5we2f.fsf@gmail.com> References: <4B4A909D.6060901@web.de> <87y6k5we2f.fsf@gmail.com> Message-ID: <4B4A9410.2030708@web.de> Hi Ivan, ghc-pkg hide works fine, thanks! G?nther Am 11.01.10 03:49, schrieb Ivan Lazar Miljenovic: > G?nther Schmidt writes: > >> Could not find module `Control.Monad.Trans': >> it was found in multiple packages: transformers-0.1.4.0 >> mtl-1.1.0.2 >> > There's a way of specifying it at the top of whichever file you're > using, but so far my workaround in this situation is to use "ghc-pkg > hide" on whichever of those packages I don't use in my code. > > From valery.vv at gmail.com Mon Jan 11 02:54:13 2010 From: valery.vv at gmail.com (Valery V. Vorotyntsev) Date: Mon Jan 11 02:26:54 2010 Subject: [Haskell-cafe] mtl and transformers In-Reply-To: <4B4A9410.2030708@web.de> References: <4B4A909D.6060901@web.de> <87y6k5we2f.fsf@gmail.com> <4B4A9410.2030708@web.de> Message-ID: >> G?nther Schmidt: >> >>> Could not find module `Control.Monad.Trans': >>> it was found in multiple packages: transformers-0.1.4.0 >>> mtl-1.1.0.2 > Ivan Lazar Miljenovic: >> >> There's a way of specifying it at the top of whichever file you're >> using, but so far my workaround in this situation is to use "ghc-pkg >> hide" on whichever of those packages I don't use in my code. G?nther Schmidt: > > ghc-pkg hide works fine, thanks! As an alternative, you can use `LANGUAGE PackageImports' pragma: | {-# LANGUAGE PackageImports #-} | | import "transformers" Control.Monad.Trans See http://thread.gmane.org/gmane.comp.lang.haskell.libraries/12134/focus=12155 PS: Have fun with iteratees! -- vvv From martijn at van.steenbergen.nl Mon Jan 11 04:03:09 2010 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Mon Jan 11 03:36:01 2010 Subject: [Haskell-cafe] mtl and transformers In-Reply-To: <4B4A909D.6060901@web.de> References: <4B4A909D.6060901@web.de> Message-ID: <4B4AE94D.2020703@van.steenbergen.nl> G?nther Schmidt wrote: > Hi, > > when I cabal-installed the iteratee package, the transformers package > was also installed as a dependency. > > Now when I run applications that import Control.Monad.Transformers I get > this: > > Could not find module `Control.Monad.Trans': > it was found in multiple packages: transformers-0.1.4.0 mtl-1.1.0.2 Another solution is to build your applications using Cabal and specify your dependency on mtl in the cabal file. HTH, Martijn. From ivan.miljenovic at gmail.com Mon Jan 11 04:11:20 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Mon Jan 11 03:44:06 2010 Subject: [Haskell-cafe] mtl and transformers In-Reply-To: <4B4AE94D.2020703@van.steenbergen.nl> (Martijn van Steenbergen's message of "Mon, 11 Jan 2010 10:03:09 +0100") References: <4B4A909D.6060901@web.de> <4B4AE94D.2020703@van.steenbergen.nl> Message-ID: <87hbqtvwef.fsf@gmail.com> Martijn van Steenbergen writes: > Another solution is to build your applications using Cabal and specify > your dependency on mtl in the cabal file. But until we have "cabal ghci", this completely fails for actual hacking purposes... -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From ganesh.sittampalam at credit-suisse.com Mon Jan 11 04:16:21 2010 From: ganesh.sittampalam at credit-suisse.com (Sittampalam, Ganesh) Date: Mon Jan 11 03:49:17 2010 Subject: [Haskell-cafe] mtl and transformers In-Reply-To: <87hbqtvwef.fsf@gmail.com> References: <4B4A909D.6060901@web.de> <4B4AE94D.2020703@van.steenbergen.nl> <87hbqtvwef.fsf@gmail.com> Message-ID: <16442B752A06A74AB4D9F9A5FF076E4B03B9FE78@ELON17P32001A.csfb.cs-group.com> Ivan Lazar Miljenovic wrote: > Martijn van Steenbergen writes: >> Another solution is to build your applications using Cabal and >> specify your dependency on mtl in the cabal file. > > But until we have "cabal ghci", this completely fails for actual > hacking purposes... Just do cabal build -v, then cut and paste the ghc --make command-line and replace --make with --interactive. Obviously rather a hack, but remarkably usable in practice, in my experience. Ganesh =============================================================================== Please access the attached hyperlink for an important electronic communications disclaimer: http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html =============================================================================== From v.dijk.bas at gmail.com Mon Jan 11 06:07:10 2010 From: v.dijk.bas at gmail.com (Bas van Dijk) Date: Mon Jan 11 05:40:11 2010 Subject: [Haskell-cafe] mtl and transformers In-Reply-To: <16442B752A06A74AB4D9F9A5FF076E4B03B9FE78@ELON17P32001A.csfb.cs-group.com> References: <4B4A909D.6060901@web.de> <4B4AE94D.2020703@van.steenbergen.nl> <87hbqtvwef.fsf@gmail.com> <16442B752A06A74AB4D9F9A5FF076E4B03B9FE78@ELON17P32001A.csfb.cs-group.com> Message-ID: On Mon, Jan 11, 2010 at 10:16 AM, Sittampalam, Ganesh wrote: > Ivan Lazar Miljenovic wrote: >> Martijn van Steenbergen writes: >>> Another solution is to build your applications using Cabal and >>> specify your dependency on mtl in the cabal file. >> >> But until we have "cabal ghci", this completely fails for actual >> hacking purposes... > > Just do cabal build -v, then cut and paste the ghc --make command-line and replace --make with --interactive. Thanks for this tip! I always make a ghci.sh bash script in each of my projects that calls "ghci -hide-all-packages -package x -package y -package z". However a "cabal ghci" or "cabal interactive" command that does this automatically would be ideal. I see there already is a ticket[1] about it. regards, Bas [1] http://hackage.haskell.org/trac/hackage/ticket/382 From jeremy.odonoghue at gmail.com Mon Jan 11 06:54:13 2010 From: jeremy.odonoghue at gmail.com (Jeremy O'Donoghue) Date: Mon Jan 11 06:27:05 2010 Subject: [Haskell-cafe] New blog: mainly Haskell and wxHaskell related Message-ID: Hi all, I have just started a new blog at http://wewantarock.wordpress.com. At least initially, my intention is to provide a set of 'tutorial' style articles to help new wxHaskell users get beyond the 'Hello World' stage by offering a few worked examples on things you might want to do to put together a usable application. The idea is to offer something which fits between the first tutorial and the reference documents. The first few postings will explain the anatomy of a complete custom wxHaskell control written in Haskell. Comments gratefully accepted, including (gentle please - I'm not dons!) criticism of my Haskell style. Regards Jeremy O'Donoghue From hjgtuyl at chello.nl Mon Jan 11 07:33:04 2010 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Mon Jan 11 07:05:40 2010 Subject: [Haskell-cafe] Cabal bug? Message-ID: L.S., I had a strange response from Cabal: >cabal upgrade hlint Resolving dependencies... cabal: cannot configure containers-0.3.0.0. It requires base >=4.2 && <6 For the dependency on base >=4.2 && <6 there are these packages: base-4.2.0.0. However none of them are available. base-4.2.0.0 was excluded because of the top level dependency base -any So, base-4.2.0.0 cannot be used, because any version of base is OK? Is this a bug in Cabal? Regards, Henk-Jan van Tuyl -- http://Van.Tuyl.eu/ http://members.chello.nl/hjgtuyl/tourdemonad.html -- From ivan.miljenovic at gmail.com Mon Jan 11 07:54:20 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Mon Jan 11 07:27:08 2010 Subject: [Haskell-cafe] Cabal bug? In-Reply-To: (Henk-Jan van Tuyl's message of "Mon, 11 Jan 2010 13:33:04 +0100") References: Message-ID: <878wc4x0n7.fsf@gmail.com> "Henk-Jan van Tuyl" writes: > I had a strange response from Cabal: > >cabal upgrade hlint I thought upgrade was disabled... what version of cabal-install do you have? > Resolving dependencies... > cabal: cannot configure containers-0.3.0.0. It requires base >=4.2 && <6 > For the dependency on base >=4.2 && <6 there are these packages: > base-4.2.0.0. Base 4.2 and containers-0.3 come with/are for GHC-6.12.* > So, base-4.2.0.0 cannot be used, because any version of base is OK? Is > this a bug in Cabal? The latest version of hlint doesn't need containers-0.3; so just do "cabal install --reinstall hlint" to get the new version. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From ben.franksen at online.de Mon Jan 11 07:55:01 2010 From: ben.franksen at online.de (Benjamin Franksen) Date: Mon Jan 11 07:28:05 2010 Subject: [Haskell-cafe] Re: Approaches to dependent types (DT) References: <4ACF3682.80000@comp.dit.ie> <200910100318.38874.dan.doel@gmail.com> <4B464C25.4040003@comp.dit.ie> Message-ID: pbrowne wrote: > Dependent Types (DT) > The purpose of dependent types (DT) is to allow programmers to specify > dependencies between the parameters of a multiple parameter class. 'Dependent type' means result type (of a function) can depend on argument values. This is not (directly) supported in Haskell. What you are talking about is called 'functional dependencies', not 'dependent types'. Sometimes abbreviated as 'fundeps'. > DTs > can be seen as a move towards more general purpose parametric type > classes. This is at least misleading, as adding a functional dependency does not make the class more general, but more special, as it reduces the number of possible instances. Cheers Ben From sebf at informatik.uni-kiel.de Mon Jan 11 07:58:37 2010 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Mon Jan 11 07:31:17 2010 Subject: [Haskell-cafe] short licensing question Message-ID: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> Hello Caf?, when writing a Haskell library that uses two other Haskell libraries -- one licensed under BSD3 and one under LGPL -- what are allowed possibilities for licensing the written package? PublicDomain? BSD3? LGPL? Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From valery.vv at gmail.com Mon Jan 11 08:02:08 2010 From: valery.vv at gmail.com (Valery V. Vorotyntsev) Date: Mon Jan 11 07:34:50 2010 Subject: [Haskell-cafe] mtl and transformers In-Reply-To: References: <4B4A909D.6060901@web.de> <4B4AE94D.2020703@van.steenbergen.nl> <87hbqtvwef.fsf@gmail.com> <16442B752A06A74AB4D9F9A5FF076E4B03B9FE78@ELON17P32001A.csfb.cs-group.com> Message-ID: Bas van Dijk wrote: > I always make a ghci.sh bash script in each of my projects that calls > "ghci -hide-all-packages -package x -package y -package z". However a > "cabal ghci" or "cabal interactive" command that does this > automatically would be ideal. I see there already is a ticket[1] about > it. > > regards, > Bas > > [1] http://hackage.haskell.org/trac/hackage/ticket/382 Shell script can be replaced with .ghci file. See http://neilmitchell.blogspot.com/2010/01/using-ghci-files-to-run-projects.html (Just my two cents.) -- vvv From dons at galois.com Mon Jan 11 08:08:24 2010 From: dons at galois.com (Don Stewart) Date: Mon Jan 11 07:41:06 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> Message-ID: <20100111130824.GA7184@whirlpool.galois.com> sebf: > Hello Caf?, > > when writing a Haskell library that uses two other Haskell libraries -- > one licensed under BSD3 and one under LGPL -- what are allowed > possibilities for licensing the written package? PublicDomain? BSD3? > LGPL? > Libraries don't link in other things as such -- the .cabal file is the only thing that ties them together -- so you can use whatever license you like. Any resulting binaries might contain a mixture of such libraries, and the most restrictive license will usually be the license of the result. -- Don From svein.ove at aas.no Mon Jan 11 08:15:24 2010 From: svein.ove at aas.no (Svein Ove Aas) Date: Mon Jan 11 07:48:04 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <20100111130824.GA7184@whirlpool.galois.com> References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> <20100111130824.GA7184@whirlpool.galois.com> Message-ID: <221b53ab1001110515u67b6b3d4n2e3d05dcb27926cb@mail.gmail.com> On Mon, Jan 11, 2010 at 2:08 PM, Don Stewart wrote: > sebf: >> Hello Caf?, >> >> when writing a Haskell library that uses two other Haskell libraries -- >> one licensed under BSD3 and one under LGPL -- what are allowed >> possibilities for licensing the written package? PublicDomain? BSD3? >> LGPL? >> > > Libraries don't link in other things as such -- the .cabal file is the only > thing that ties them together -- so you can use whatever license you > like. > > Any resulting binaries might contain a mixture of such libraries, and > the most restrictive license will usually be the license of the result. > So, let's look at binaries then. In this case, LGPL is a problem. It requires you to offer a way to re-link such binaries against new versions/implementations of the library, which in practice requires it to be either open source or dynamically linked. Dynamic linking doesn't exist in GHC 6.10 and below. LGPL is thus restricted to open-source applications there. In 6.12.. well, dynamic linking exists, but in practice trying to replace a library implementation won't work. In fact, there's code in specifically to prevent it from working (well, crashing, really). So LGPL isn't very useful on that either. In practice, then, LGPL'd haskell libraries are probably useless for the stated purpose of supporting closed-source applications. You'd have to modify the license, or rather find something that fits better. I'm sure that exists, and chances are the author will be understanding if you ask. -- Svein Ove Aas From Patrick.Browne at comp.dit.ie Mon Jan 11 08:44:17 2010 From: Patrick.Browne at comp.dit.ie (pbrowne) Date: Mon Jan 11 08:16:58 2010 Subject: [Haskell-cafe] Re: Approaches to dependent types (DT) In-Reply-To: References: <4ACF3682.80000@comp.dit.ie> <200910100318.38874.dan.doel@gmail.com> <4B464C25.4040003@comp.dit.ie> Message-ID: <4B4B2B31.70607@comp.dit.ie> Ben, I have added your input. Thanks for putting me right. Pat Functional Dependencies The purpose of functional dependencies (FD) is to allow programmers to specify dependencies between the parameters of a multiple parameter class. FD reduces the number of possible instances, or models of a class. Note, the notion of FD is distinct from the concept of 'Dependent types', where the result type (of a function) can depend on argument values. FD are declared in a class header, where the type of one class parameter is declared to depend on another class parameter. Consider the following example: class Named object name | object -> name where namef :: object -> name instance (Eq name, Named object name) => Eq object where object1 == object2 = (namef object1) == (namef object2) The first part of the class definition Named takes two type variables as parameters; namely object and name. We say, that object determines name or alternatively that name is determined by object. This is denoted in the second part of the class header (i.e. | object -> name). With DTs, the dependent type depends on values of the determining type. Hence, a FD involves a relation between Haskell?s value-level and the type-level (or type system). The Named class contains the signature, but not the definition, of one function called namef. Note, the in the definition of namef, the argument and return type (object -> name) are textually identical to that occurring in the class header, however the semantic is that of function definition rather that of type dependency. In the instance declaration, the part before the => is called the context, while the part after the => is called the head of the instance declaration. The context contains one or more class assertions, which is a list of classes each with their respective type variables, asserting that a type variable is a parameter of a particular class. The context for the above example includes two previously defined classes. The Eq class is defined in the Haskell prelude and our user defined Named class. The instance asserts: If (type of name is an instance of the Eq class) and (type pair (object, name) is an instance of Named) then object is an instance of Eq The new Eq instance defined is quite general, it asserts that every type object is an instance of the Eq class. It does not say that every type object that is an instance of Named is also an instance of Eq. Now we consider the definition of equality (==) for the type object in the instance body. Initially, the definition determines the type name in a type->type dependency (e.g. via the function call namef object1). When the two names have been calculated the function uses this information to define equality on values of type object via equality on values of type name. Benjamin Franksen wrote: > pbrowne wrote: >> Dependent Types (DT) >> The purpose of dependent types (DT) is to allow programmers to specify >> dependencies between the parameters of a multiple parameter class. > > 'Dependent type' means result type (of a function) can depend on argument > values. This is not (directly) supported in Haskell. > > What you are talking about is called 'functional dependencies', not > 'dependent types'. Sometimes abbreviated as 'fundeps'. > >> DTs >> can be seen as a move towards more general purpose parametric type >> classes. > > This is at least misleading, as adding a functional dependency does not make > the class more general, but more special, as it reduces the number of > possible instances. > > Cheers > Ben > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From ketil at malde.org Mon Jan 11 09:13:38 2010 From: ketil at malde.org (Ketil Malde) Date: Mon Jan 11 08:46:10 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <221b53ab1001110515u67b6b3d4n2e3d05dcb27926cb@mail.gmail.com> (Svein Ove Aas's message of "Mon, 11 Jan 2010 14:15:24 +0100") References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> <20100111130824.GA7184@whirlpool.galois.com> <221b53ab1001110515u67b6b3d4n2e3d05dcb27926cb@mail.gmail.com> Message-ID: <87ljg4d90t.fsf@malde.org> Svein Ove Aas writes: >>> when writing a Haskell library that uses two other Haskell libraries -- >>> one licensed under BSD3 and one under LGPL -- what are allowed >>> possibilities for licensing the written package? >> Any resulting binaries might contain a mixture of such libraries, and >> the most restrictive license will usually be the license of the result. > In this case, LGPL is a problem. It requires you to offer a way to > re-link such binaries against new versions/implementations of the > library, which in practice requires it to be either open source or > dynamically linked. Isn't it possible to provide the proprietary bits as compiled object files (.o or .a) to be linked by the recipient? -k -- If I haven't seen further, it is by standing in the footprints of giants From duncan.coutts at googlemail.com Mon Jan 11 10:23:46 2010 From: duncan.coutts at googlemail.com (Duncan Coutts) Date: Mon Jan 11 09:56:30 2010 Subject: [Haskell-cafe] Cabal bug? In-Reply-To: References: Message-ID: <1263223426.4399.25537.camel@localhost> On Mon, 2010-01-11 at 13:33 +0100, Henk-Jan van Tuyl wrote: > L.S., > > > I had a strange response from Cabal: > >cabal upgrade hlint > Resolving dependencies... > cabal: cannot configure containers-0.3.0.0. It requires base >=4.2 && <6 > For the dependency on base >=4.2 && <6 there are these packages: > base-4.2.0.0. > However none of them are available. > base-4.2.0.0 was excluded because of the top level dependency base -any > > So, base-4.2.0.0 cannot be used, because any version of base is OK? Is > this a bug in Cabal? It's a bug in the sense that the error message is misleading. What it actually means is "base-4.2.0.0 cannot be used, because an installed version of base is required". The pretty printing for "installed constraints" (as opposed to version constraints) is borked. Duncan From shan2 at kth.se Mon Jan 11 12:00:37 2010 From: shan2 at kth.se (Seyed Hosein Attarzadeh Niaki) Date: Mon Jan 11 11:33:26 2010 Subject: [Haskell-cafe] Update for type-level library (0.2.4) In-Reply-To: <4B4B1CB9.5050506@kth.se> References: <4B4B1CB9.5050506@kth.se> Message-ID: <4B4B5935.4040703@kth.se> Dear Haskell developers, A new version of the type-level library for type-level programming is pushed into the development repository and uploaded to the Hackage database. This is only a minor update to fix the compatibility issues with base 4, GHC>=6.10 and cabal-install (not backward compatible). Bests, Hosein Attarzadeh From Andrejs.Sisojevs at nextmail.ru Mon Jan 11 12:30:25 2010 From: Andrejs.Sisojevs at nextmail.ru (Andrey Sisoyev) Date: Mon Jan 11 12:03:05 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <221b53ab1001110515u67b6b3d4n2e3d05dcb27926cb@mail.gmail.com> References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> <20100111130824.GA7184@whirlpool.galois.com> <221b53ab1001110515u67b6b3d4n2e3d05dcb27926cb@mail.gmail.com> Message-ID: <27114282.post@talk.nabble.com> Svein Ove Aas wrote: > > In this case, LGPL is a problem. It requires you to offer a way to > re-link such binaries against new versions/implementations of the > library, which in practice requires it to be either open source or > dynamically linked. > Don't understand that. Can't we just put a constraint: "our binary works only with versions x.x.x-y.y.y of this LGPL licensed library"? The Cabal provides a way to put such constraint in build-depends... Andrey -- View this message in context: http://old.nabble.com/short-licensing-question-tp27110059p27114282.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From korpios at korpios.com Mon Jan 11 13:02:46 2010 From: korpios at korpios.com (Tom Tobin) Date: Mon Jan 11 12:35:27 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> Message-ID: On Mon, Jan 11, 2010 at 6:58 AM, Sebastian Fischer wrote: > when writing a Haskell library that uses two other Haskell libraries -- one > licensed under BSD3 and one under LGPL -- what are allowed possibilities for > licensing the written package? PublicDomain? BSD3? LGPL? There was a long thread on licensing recently: http://www.mail-archive.com/haskell-cafe@haskell.org/msg68237.html I'm still waiting to hear back from the SFLC regarding the questions we came up with, and I'll post them as soon as I get them. I think in your case you can license the library you're writing any way you'd like, but distributing a statically linked binary might leave you with additional obligations under the LGPL. (Things get wonderfully more confusing when one of the libraries is the GPL, but hopefully we'll have more insight regarding that soon.) I'm not a lawyer, though, and I suggest that you take any advice from non-lawyers as hints rather than definitive answers. If you want an answer from a lawyer, the SFLC can be useful: http://www.softwarefreedom.org/ From nccb2 at kent.ac.uk Mon Jan 11 13:03:26 2010 From: nccb2 at kent.ac.uk (Neil Brown) Date: Mon Jan 11 12:35:33 2010 Subject: [Haskell-cafe] ANN: chp-2.0.0, chp-plus-1.0.0 Message-ID: <4B4B67EE.7020003@kent.ac.uk> Hi, I've just released version 2.0.0 of the Communicating Haskell Processes (CHP) message-passing concurrency library onto Hackage. The main change from 1.x is that I have split the functionality into two libraries: the core functionality remains in the chp package (now version 2.0.0), while some of the additional capabilities have been moved out to the new chp-plus package (version 1.0.0). This should help in the long run by keeping the packages from becoming too large, and by allowing me to trim the dependencies of the core chp package. I've written more about the changes here, for those who it will affect: http://chplib.wordpress.com/2010/01/11/splitting-chp/ This will require small changes to your build system if you're using CHP and you upgrade to the new versions. The new versions should also fix build troubles with GHC 6.12 -- let me know if you have any troubles installing under 6.10 or 6.12. Hackage links: http://hackage.haskell.org/package/chp-2.0.0 http://hackage.haskell.org/package/chp-plus-1.0.0 Thanks, Neil. From ott at mirix.org Mon Jan 11 14:18:50 2010 From: ott at mirix.org (Matthias-Christian Ott) Date: Mon Jan 11 13:50:27 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> Message-ID: <20100111191850.GB23718@qp> On Mon, Jan 11, 2010 at 12:02:46PM -0600, Tom Tobin wrote: > On Mon, Jan 11, 2010 at 6:58 AM, Sebastian Fischer > wrote: > > when writing a Haskell library that uses two other Haskell libraries -- one > > licensed under BSD3 and one under LGPL -- what are allowed possibilities for > > licensing the written package? PublicDomain? BSD3? LGPL? > > There was a long thread on licensing recently: > > http://www.mail-archive.com/haskell-cafe@haskell.org/msg68237.html > > I'm still waiting to hear back from the SFLC regarding the questions > we came up with, and I'll post them as soon as I get them. I think in > your case you can license the library you're writing any way you'd > like, but distributing a statically linked binary might leave you with > additional obligations under the LGPL. (Things get wonderfully more > confusing when one of the libraries is the GPL, but hopefully we'll > have more insight regarding that soon.) I'm not a lawyer, though, and > I suggest that you take any advice from non-lawyers as hints rather > than definitive answers. If you want an answer from a lawyer, the > SFLC can be useful: > > http://www.softwarefreedom.org/ You can also ask the Freedom Task Force of the FSFE: http://fsfe.org/projects/ftf/ftf.en.html They may offer better legal advice for Europe. Regards, Matthias-Christian From sebf at informatik.uni-kiel.de Mon Jan 11 14:43:16 2010 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Mon Jan 11 14:15:56 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <20100111130824.GA7184@whirlpool.galois.com> References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> <20100111130824.GA7184@whirlpool.galois.com> Message-ID: <98343483-513F-413C-816F-C4F6E2BC8AF5@informatik.uni-kiel.de> On Jan 11, 2010, at 2:08 PM, Don Stewart wrote: > Libraries don't link in other things as such -- the .cabal file is > the only > thing that ties them together -- so you can use whatever license you > like. On Jan 11, 2010, at 7:02 PM, Tom Tobin wrote: > I think in > your case you can license the library you're writing any way you'd > like, but distributing a statically linked binary might leave you with > additional obligations under the LGPL. Thank you all for your comments. It seems consensus that it is no problem to depend on LGPL libraries if no binary that links to LGPL'ed code is distributed. I understand that this consensus is no definite legal advice, though. What reasons do people have to use a BSD license over a Public Domain license, for example with the license text from: ? Is the only difference that, with a BSD license, the copyright notice must be maintained? Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From jeremy at n-heptane.com Mon Jan 11 15:01:11 2010 From: jeremy at n-heptane.com (Jeremy Shaw) Date: Mon Jan 11 14:34:01 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <98343483-513F-413C-816F-C4F6E2BC8AF5@informatik.uni-kiel.de> References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> <20100111130824.GA7184@whirlpool.galois.com> <98343483-513F-413C-816F-C4F6E2BC8AF5@informatik.uni-kiel.de> Message-ID: <63863C2A-06E5-47E2-92BE-4B1732FEF0CE@n-heptane.com> > What reasons do people have to use a BSD license over a Public > Domain license, for example with the license text from: > ? Is the only difference that, with a BSD license, the copyright > notice must be maintained? I've heard rumors that you can't license your code as public domain in some countries. Not sure if the BSD3 helps with that though. But, one reason I license my Haskell code as BSD3 is that GHC and most(?) of the libraries on hackage are BSD3. And the BSD3 license is very widely known. As a result, I don't expect to have to deal with licensing issues. If I used a different license, then people would have to wonder... even if the license was more liberal. I figure people want to code, not think about licenses :p Also, I think it is kind of rude/conceited to license my code as GPL when it builds on so much BSD3 code. As if my code is some how so much better that the BSD3 isn't good enough for it :p - jeremy From wren at freegeek.org Mon Jan 11 15:08:51 2010 From: wren at freegeek.org (wren ng thornton) Date: Mon Jan 11 14:34:56 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <98343483-513F-413C-816F-C4F6E2BC8AF5@informatik.uni-kiel.de> References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> <20100111130824.GA7184@whirlpool.galois.com> <98343483-513F-413C-816F-C4F6E2BC8AF5@informatik.uni-kiel.de> Message-ID: <4B4B8553.1010203@freegeek.org> Sebastian Fischer wrote: > What reasons do people have to use a BSD license over a Public Domain > license, for example with the license text from: > ? Is the only difference > that, with a BSD license, the copyright notice must be maintained? One important reason is that "public domain" does not exist (or is not the same) in all countries, which can make international sharing a hassle. If you feel the BSD3 is too restrictive, another alternative is the WTFPL[1][2] which provides a formal contract of, essentially, public domain privileges (and is GPL-compatible). [1] http://sam.zoy.org/wtfpl/ [2] http://en.wikipedia.org/wiki/WTFPL -- Live well, ~wren From gue.schmidt at web.de Mon Jan 11 16:14:02 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Mon Jan 11 15:47:08 2010 Subject: [Haskell-cafe] Parsers (Parsec and Iteratee-based Parsers) Message-ID: <4B4B949A.5050309@web.de> Hi, are there any examples how to build parsers using the library in Oleg's iteratee package? I've been using parsec for almost all my parsing needs, in fact it was parsec that got me started with Haskell. I'd like to try to build a few parsers based on the left-fold-enumerator thingy and compare this approach to parsec. Any good tips how to get started? G?nther From dagit at codersbase.com Mon Jan 11 16:36:49 2010 From: dagit at codersbase.com (Jason Dagit) Date: Mon Jan 11 16:09:28 2010 Subject: [Haskell-cafe] Parsers (Parsec and Iteratee-based Parsers) In-Reply-To: <4B4B949A.5050309@web.de> References: <4B4B949A.5050309@web.de> Message-ID: 2010/1/11 G?nther Schmidt > Hi, > > are there any examples how to build parsers using the library in Oleg's > iteratee package? > > I've been using parsec for almost all my parsing needs, in fact it was > parsec that got me started with Haskell. > I think you should be in contact with John Lato. Last time we had correspondence he mentioned a hybrid between iteratees and parsec. Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100111/84e787a5/attachment.html From korpios at korpios.com Mon Jan 11 17:04:08 2010 From: korpios at korpios.com (Tom Tobin) Date: Mon Jan 11 16:36:47 2010 Subject: [Haskell-cafe] Haskell-iPhone mailing list? Message-ID: Is there a mailing list for efforts to get Haskell running on the iPhone? As I've been maintaining an iPhone app for my employer (and nearly foaming at the mouth with hatred for Objective-C), I'd love to see a more sane option in this space. I've seen the wiki page [1], but I'm not aware of any other space for collaboration here. [1] http://www.haskell.org/haskellwiki/IPhone From jwlato at gmail.com Mon Jan 11 17:48:55 2010 From: jwlato at gmail.com (John Lato) Date: Mon Jan 11 17:21:34 2010 Subject: [Haskell-cafe] Parsers (Parsec and Iteratee-based Parsers) In-Reply-To: References: <4B4B949A.5050309@web.de> Message-ID: <9979e72e1001111448w123e38c1i90ae4276ea800ae3@mail.gmail.com> 2010/1/11 Jason Dagit : > > > 2010/1/11 G?nther Schmidt >> >> Hi, >> >> are there any examples how to build parsers using the library in Oleg's >> iteratee package? >> >> I've been using parsec for almost all my parsing needs, in fact it was >> parsec that got me started with Haskell. > > I think you should be in contact with John Lato.? Last time we had > correspondence he mentioned a hybrid between iteratees and parsec. > I don't know if I'd call it a hybrid, however there is a way to embed Parsec parsers (v.3 only) in iteratee. The necessary code is available at: http://inmachina.net/~jwlato/haskell/ParsecIteratee.hs It's intended to be used for embedding relatively small parsers in iteratees. It does concatenate chunks, so if it looks too far into the stream it can be inefficient. Chunks of up to 2000 characters shouldn't require more than 1 concat (depending on what other functions you're using). This code is available as Public Domain. Thanks to Erik de Castro Lopo for suggesting integrating iteratee and parsec in some manner. It's still pretty new, so suggestions are welcome. If you want to build parsers directly with iteratee, there currently aren't any published tutorials although I can provide some working code if you like. The interface is much lower-level than Parsec. John From gue.schmidt at web.de Mon Jan 11 18:09:09 2010 From: gue.schmidt at web.de (=?ISO-8859-1?Q?G=FCnther_Schmidt?=) Date: Mon Jan 11 17:41:51 2010 Subject: [Haskell-cafe] Parsers (Parsec and Iteratee-based Parsers) In-Reply-To: <9979e72e1001111448w123e38c1i90ae4276ea800ae3@mail.gmail.com> References: <4B4B949A.5050309@web.de> <9979e72e1001111448w123e38c1i90ae4276ea800ae3@mail.gmail.com> Message-ID: <4B4BAF95.7030108@web.de> Hi John, thanks for responding. As I said I've been using Parsec quite a lot, but wonder if there is a different approach possible/feasible to parsing. Parsec (2x) isn't an "online" parser, ie, it doesn't produce a result before the whole parse is completed. There is AFAIK one alternative, the uulib, but at first glance it seemed very elaborate, so I wonder if Oleg's Iteratee offers something simpler. I am not in particular looking for some sort of parsec-iteratee-hybrid, I'd be quite happy with something entirely based on Iteratee. In the Iteratee package there are 2 sample parsers, one for TIFF and one for WAVE files. I wish I could say that the accompanying documentation is sufficient for me to get the idea, alas it's not. G?nther From gue.schmidt at web.de Mon Jan 11 19:35:10 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Mon Jan 11 19:08:13 2010 Subject: [Haskell-cafe] Tokenizing and Parsec Message-ID: <4B4BC3BE.7050806@web.de> Hi all, I've used Parsec to "tokenize" data from a text file. It was actually quite easy, everything is correctly identified. So now I have a list/stream of self defined "Tokens" and now I'm stuck. Because now I need to write my own parsec-token-parsers to parse this token stream in a context-sensitive way. Uhm, how do I that then? G?nther a Token is something like: data Token = ZE String | OPS | OPSShort String | OPSLong String | Other String | ZECd String deriving Show From keithshep at gmail.com Mon Jan 11 19:59:29 2010 From: keithshep at gmail.com (Keith Sheppard) Date: Mon Jan 11 19:32:10 2010 Subject: [Haskell-cafe] hackage build errors Message-ID: <92e42b741001111659j68884d30qc1104b0dc57dac76@mail.gmail.com> Hello Cafe, I noticed on my package's hackage page there is a build failure message: http://hackage.haskell.org/package/txt-sushi I don't know if these are real errors or not (I don't experience them on OS X and it's pure Haskell code) but I did poke around and noticed that some popular packages on hackage also have build failures: http://hackage.haskell.org/package/xmonad http://hackage.haskell.org/package/haddock http://hackage.haskell.org/package/pandoc http://hackage.haskell.org/package/alex http://hackage.haskell.org/package/hlint ... so what should I make of these errors? Are they useful in some way or just a problem with the build environment? (If that's the case I think they should probably be removed since they're confusing for potential users) Best Keith -- keithsheppard.name From uhollerbach at gmail.com Mon Jan 11 22:20:51 2010 From: uhollerbach at gmail.com (Uwe Hollerbach) Date: Mon Jan 11 21:53:29 2010 Subject: [Haskell-cafe] Tokenizing and Parsec In-Reply-To: <4B4BC3BE.7050806@web.de> References: <4B4BC3BE.7050806@web.de> Message-ID: <65d7a7e1001111920rc7b530brdd218f1028db22df@mail.gmail.com> Hi, G?nther, you could write functions that pattern-match on various sequences of tokens in a list, you could for example have a look at the file Evaluator.hs in my scheme interpreter haskeem, or you could build up more-complex data structures entirely within parsec, and for this I would point you at the file Parser.hs in my accounting program umm; both are on hackage. Undoubtedly there are many more and probably better examples, but I think these are at least a start... regards, Uwe On 1/11/10, G?nther Schmidt wrote: > Hi all, > > I've used Parsec to "tokenize" data from a text file. It was actually > quite easy, everything is correctly identified. > > So now I have a list/stream of self defined "Tokens" and now I'm stuck. > Because now I need to write my own parsec-token-parsers to parse this > token stream in a context-sensitive way. > > Uhm, how do I that then? > > G?nther > > a Token is something like: > > data Token = ZE String > | OPS > | OPSShort String > | OPSLong String > | Other String > | ZECd String > deriving Show > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From jeffzaroyko at gmail.com Mon Jan 11 22:46:07 2010 From: jeffzaroyko at gmail.com (Jeff Zaroyko) Date: Mon Jan 11 22:18:46 2010 Subject: [Haskell-cafe] Parsers (Parsec and Iteratee-based Parsers) In-Reply-To: <4B4BAF95.7030108@web.de> References: <4B4B949A.5050309@web.de> <9979e72e1001111448w123e38c1i90ae4276ea800ae3@mail.gmail.com> <4B4BAF95.7030108@web.de> Message-ID: 2010/1/12 G?nther Schmidt : > Hi John, > > thanks for responding. As I said I've been using Parsec quite a lot, but > wonder if there is a different approach possible/feasible to parsing. Parsec > (2x) isn't an "online" parser, ie, it doesn't produce a result before the > whole parse is completed. > This appears to be a common source of confusion. You can produce a result by not trying to parse the entire input in one go, instead parse as much as you want to consume, then return the rest of the input with the tokens that you have collected. For example, in Parsec 2 a regular approach I use is something like: get1 = do token <- parse1token remaining <- getInput return (remaining,token) Jeff From drcygnus at gmail.com Tue Jan 12 01:54:10 2010 From: drcygnus at gmail.com (Jonathan Daugherty) Date: Tue Jan 12 01:26:47 2010 Subject: [Haskell-cafe] hackage build errors In-Reply-To: <92e42b741001111659j68884d30qc1104b0dc57dac76@mail.gmail.com> References: <92e42b741001111659j68884d30qc1104b0dc57dac76@mail.gmail.com> Message-ID: > I noticed on my package's hackage page there is a build failure message: > http://hackage.haskell.org/package/txt-sushi > > I don't know if these are real errors or not (I don't experience them > on OS X and it's pure Haskell code) but I did poke around and noticed > that some popular packages on hackage also have build failures: Just as an extra data point, I've found that some of the build errors on Hackage are due to the machine's build state and not due to any intrinsic failure in the package in question. Furthermore, Hackage does not generate Haddock for these packages even though generating Haddock would still be 1) possible and 2) useful. I think it would be better to divorce the build process from the Haddock generation, since they aren't necessarily related (and Haddock builds will fail if the package *is* trivially broken.) -- Jonathan Daugherty From stephen.tetley at gmail.com Tue Jan 12 03:42:23 2010 From: stephen.tetley at gmail.com (Stephen Tetley) Date: Tue Jan 12 03:15:01 2010 Subject: [Haskell-cafe] Tokenizing and Parsec In-Reply-To: <4B4BC3BE.7050806@web.de> References: <4B4BC3BE.7050806@web.de> Message-ID: <5fdc56d71001120042p1fdae5dbmf9efaadb51793939@mail.gmail.com> 2010/1/12 G?nther Schmidt : > [Snip...] I need to write my own parsec-token-parsers to parse this token > stream in a context-sensitive way. > > Uhm, how do I that then? > Hi G?nther Get the Parsec manual from Daan Leijen's home page then see the section '2.11 Advanced: Seperate scanners'. Though mentioned rarely, Parsec in its regular mode is a scannerless parser. Unless you have complex formatting problems (e.g. indentation sensitivity, vis Python or Haskell's syntax) scannerless parsers are often much more convenient than parsers+lexers (see the grammar formalism SDF for many examples). For Parsec, if you want a separate scanner there's quite a lot of boilerplate you need to manufacture if you want to use the technique in section 2.11. Usually I can get by with the Token and Language modules or do a few tricks with the 'symbol' parser instead. Parsec is monadic so (>>=) allows you to write context-sensitive parsers, see section '3.1. Parsec Prim' for a discussion and example. Again, writing a context-sensitive parser can often be more trouble than studying the format of the input and working out a context-free grammar (if there is one). Best wishes Stephen From duncan.coutts at googlemail.com Tue Jan 12 03:43:38 2010 From: duncan.coutts at googlemail.com (Duncan Coutts) Date: Tue Jan 12 03:16:18 2010 Subject: [Haskell-cafe] hackage build errors In-Reply-To: <92e42b741001111659j68884d30qc1104b0dc57dac76@mail.gmail.com> References: <92e42b741001111659j68884d30qc1104b0dc57dac76@mail.gmail.com> Message-ID: <1263285818.4399.31035.camel@localhost> On Mon, 2010-01-11 at 19:59 -0500, Keith Sheppard wrote: > so what should I make of these errors? Are they useful in some way or > just a problem with the build environment? The latter. > (If that's the case I think they should probably be removed since > they're confusing for potential users) It is confusing. On the other hand if we remove the build results for all packages then there's no useful info at all. Is partial info better than none? Personally I rather agree with you, I argued for not displaying any results until it was of sufficient quality. On the other hand, if I'd had my way then perhaps there still wouldn't be any build info at all! Duncan From duncan.coutts at googlemail.com Tue Jan 12 04:03:38 2010 From: duncan.coutts at googlemail.com (Duncan Coutts) Date: Tue Jan 12 03:36:19 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <27114282.post@talk.nabble.com> References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> <20100111130824.GA7184@whirlpool.galois.com> <221b53ab1001110515u67b6b3d4n2e3d05dcb27926cb@mail.gmail.com> <27114282.post@talk.nabble.com> Message-ID: <1263287018.4399.31165.camel@localhost> On Mon, 2010-01-11 at 09:30 -0800, Andrey Sisoyev wrote: > > Svein Ove Aas wrote: > > > > In this case, LGPL is a problem. It requires you to offer a way to > > re-link such binaries against new versions/implementations of the > > library, which in practice requires it to be either open source or > > dynamically linked. > > > > Don't understand that. Can't we just put a constraint: "our binary works > only with versions x.x.x-y.y.y of this LGPL licensed library"? The Cabal > provides a way to put such constraint in build-depends... It's not referring to totally new versions of a library with a different API/ABI. The LGPL requires that the user of the program is not prevented from making some small tweak to the LGPL library and relinking it against your program. Of course if the user makes it ABI incompatible then that's their fault. So the LGPL requires it be relinkable, which you can do by providing a copy of your application as a .o file which can then be linked against the LGPL lib to make a final program. Or if you're using shared/dynamic libs then its easier. If you want to do this in practise with Haskell, GHC and an LGPL Haskell package then here's what I recommend: ld -r -x -o main.o ${objects} Then make your actual executable as: ghc main.o -o main -package ${pkg1} -package ${pkg2} ... etc Then you distribute the executable "main" and also the relinkable form "main.o" to your users, along with a copy of the LGPL license. Any user can then perform the last step themselves and if they're really lucky they might get that to work with a slightly modified version of the LGPL'ed package. In practise of course this isn't that easy for the user because GHC does not make it easy to make ABI compatible packages. However it is my understanding that this procedure will comply with the LGPL. Duncan From noteed at gmail.com Tue Jan 12 04:24:22 2010 From: noteed at gmail.com (minh thu) Date: Tue Jan 12 03:57:21 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <1263287018.4399.31165.camel@localhost> References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> <20100111130824.GA7184@whirlpool.galois.com> <221b53ab1001110515u67b6b3d4n2e3d05dcb27926cb@mail.gmail.com> <27114282.post@talk.nabble.com> <1263287018.4399.31165.camel@localhost> Message-ID: <40a414c21001120124k332c8cf0v2b8cfe895dd049a0@mail.gmail.com> 2010/1/12 Duncan Coutts : > On Mon, 2010-01-11 at 09:30 -0800, Andrey Sisoyev wrote: >> >> Svein Ove Aas wrote: >> > >> > In this case, LGPL is a problem. It requires you to offer a way to >> > re-link such binaries against new versions/implementations of the >> > library, which in practice requires it to be either open source or >> > dynamically linked. >> > >> >> Don't understand that. Can't we just put a constraint: "our binary works >> only with versions x.x.x-y.y.y of this LGPL licensed library"? The Cabal >> provides a way to put such constraint in build-depends... > > It's not referring to totally new versions of a library with a different > API/ABI. The LGPL requires that the user of the program is not prevented > from making some small tweak to the LGPL library and relinking it > against your program. Of course if the user makes it ABI incompatible > then that's their fault. > > So the LGPL requires it be relinkable, which you can do by providing a > copy of your application as a .o file which can then be linked against > the LGPL lib to make a final program. Or if you're using shared/dynamic > libs then its easier. > > If you want to do this in practise with Haskell, GHC and an LGPL Haskell > package then here's what I recommend: > > ld -r -x -o main.o ${objects} > > Then make your actual executable as: > > ghc main.o -o main -package ${pkg1} -package ${pkg2} ... etc > > Then you distribute the executable "main" and also the relinkable form > "main.o" to your users, along with a copy of the LGPL license. > > Any user can then perform the last step themselves and if they're really > lucky they might get that to work with a slightly modified version of > the LGPL'ed package. In practise of course this isn't that easy for the > user because GHC does not make it easy to make ABI compatible packages. > However it is my understanding that this procedure will comply with the > LGPL. In short, if I understand you correctly, you would just have to provide your code in unlinked form regardless of the existence of some tool to create another ABI-compatible version of the LGPL library. This alongside of the last discussion (which also roughly said you can license the code as you want when it is the client responsability to link the final binary) makes the (L)GPL quite useless (as a "freedom" keeper) whenever the code is made for specific clients... Thu From magnus at therning.org Tue Jan 12 04:47:34 2010 From: magnus at therning.org (Magnus Therning) Date: Tue Jan 12 04:20:12 2010 Subject: [Haskell-cafe] Tokenizing and Parsec In-Reply-To: <4B4BC3BE.7050806@web.de> References: <4B4BC3BE.7050806@web.de> Message-ID: 2010/1/12 G?nther Schmidt : > Hi all, > > I've used Parsec to "tokenize" data from a text file. It was actually quite > easy, everything is correctly identified. > > So now I have a list/stream of self defined "Tokens" and now I'm stuck. > Because now I need to write my own parsec-token-parsers to parse this token > stream in a context-sensitive way. > > Uhm, how do I that then? > > G?nther > > a Token is something like: > > data Token = ZE String > ? ? ? ? ? | OPS > ? ? ? ? ? | OPSShort String > ? ? ? ? ? | OPSLong String > ? ? ? ? ? | Other String > ? ? ? ? ? | ZECd String > ? ? ? ? ? ? deriving Show Maybe this can be of help (though it's for Parsec 2): http://therning.org/magnus/archives/367 It's not the only example of this either, tagsoup-parsec is available on Hackage. /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe From apfelmus at quantentunnel.de Tue Jan 12 05:30:07 2010 From: apfelmus at quantentunnel.de (Heinrich Apfelmus) Date: Tue Jan 12 05:03:18 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: <201001090452.48889.daniel.is.fischer@web.de> References: <201001071713.39165.daniel.is.fischer@web.de> <201001090452.48889.daniel.is.fischer@web.de> Message-ID: Daniel Fischer wrote: > Why has > > mergeSP (a,b) ~(c,d) > = let (bc,b') = spMerge b c in (a ++ bc, merge b' d) > > a memory leak, but > > mergeSP (a,b) ~(c,d) > = let (bc,m) = spMerge' b c d in (a ++ bc, m) > > not? > > Well, looking at the core for mergeSP, the fog clears somewhat. The former > is translated roughly to > > mergeSP (a,b) pair > = let sm = spMerge b (fst pair) > in (a ++ fst sm, merge (snd sm) (snd pair)) > > It holds on to the pair until the result of the merge is demanded, that is > until the entire (a ++ fst sm) is consumed. Only then is the pair released > and can be collected. On top of that, as soon as a is consumed and (fst sm) > [or bc] is demanded, spMerge forces the evaluation of (fst pair) [c]. After > a few levels, the evaluated list will take more space than the thunk. It > cannot yet be collected, because pair is still alive. The elements have to > be duplicated for (fst sm), because they're intertwined with those of b. > On the next level of merging, they have to be duplicated again. > > The latter is translated roughly to > > mergeSP (a,b) pair > = let sm = spMerge' b (fst pair) (snd pair) > in (a ++ fst sm, snd sm) > > The pair is released as soon as the result of the spMerge' is demanded, > that is, when a is consumed. Then the elements of (fst pair) need not be > duplicated and they can be discarded almost immediately after they have > been produced [for small primes, multiples of larger primes live a little > longer, but those are fewer]. > > So, no duplication, shorter lifespan => no leak. > Having seen that, the question is, why can't the compiler see that > deconstructing the pair when the first component is needed is better? The > first component of the pair is used in no other place, so keeping the pair > can't have any advantage, can it? Tricky stuff. It is known that pairs/records are prone to unwanted retention, see for example the recent thread http://thread.gmane.org/gmane.comp.lang.haskell.cafe/66903/focus=67871 or Jan Sparud. Fixing some space leaks without a garbage collector. http://citeseer.ist.psu.edu/240848.html It is exactly because these troubles that I'm advocating the original VIP data structure that buries the dorks (that name is awesome :D) deep inside the structure. :) In any case, it appears to me that the lazy pattern match in mergeSP is actually unnecessary! This is because mergeSP returns a pair constructor immediately, so infinite nesting works even when the second argument is demanded. In other words, mergeSP :: Integral a => People a -> People a -> People a mergeSP (P a b) (P c d) = P (a ++ bc) (merge b' d) where P bc b' = spMerge b c spMerge [] ys = P [] ys spMerge xs [] = P [] xs spMerge xs@(x:xt) ys@(y:yt) = case compare x y of LT -> celebrate x (spMerge xt ys) EQ -> celebrate x (spMerge xt yt) GT -> celebrate y (spMerge xs yt) should work fine and do away with the memory issue because the pair is now deconstructed immediately. Hm, a strict second argument might however mean that the tree produced by tfold is demanded too early. > And why does > > tfold f (a: ~(b: ~(c:xs))) = ... > > leak, but not > > tfold f (a:b:c:xs) = ... > > ? > > I guess it's similar. > > tfold f (a: ~(b: ~(c:xs))) > = (a `f` (b `f` c)) `f` tfold f ([pairwise f] xs) > > is > > tfold f (a:zs) > = (a `f` (head zs `f` (head $ tail zs))) > `f` tfold f (pairwise f $ drop 2 zs) > > the latter part holds on to the beginning of zs, leading again to data > duplication and too long lifespans. Same issue with retaining pairs while only the components are needed. Ideally, we ought to be able to "couple" the two components, i.e. the idea is that tail zs is reduced to a pointer to the tail whenever head zs is demanded and vice versa. I think that's what Sparud does in his paper, not sure how well it's implemented in GHC, I vaguely remember a bug reports. Alternatively, retaining zs in any way might already be too much. Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com From Malcolm.Wallace at cs.york.ac.uk Tue Jan 12 05:31:03 2010 From: Malcolm.Wallace at cs.york.ac.uk (Malcolm Wallace) Date: Tue Jan 12 05:03:41 2010 Subject: [Haskell-cafe] Parsers (Parsec and Iteratee-based Parsers) In-Reply-To: <4B4BAF95.7030108@web.de> References: <4B4B949A.5050309@web.de> <9979e72e1001111448w123e38c1i90ae4276ea800ae3@mail.gmail.com> <4B4BAF95.7030108@web.de> Message-ID: > As I said I've been using Parsec quite a lot, but wonder if there is > a different approach possible/feasible to parsing. Parsec (2x) isn't > an "online" parser, ie, it doesn't produce a result before the whole > parse is completed. > > There is AFAIK one alternative, the uulib, In addition, the polyparse library provides "online", or lazy, parsing. Its interface is somewhat similar to parsec, perhaps even simpler. (Actually, you can freely mix lazy and strict parsing - laziness is provided by applicative combinators, strictness by monadic combinators.) I have not yet looked into whether it would be possible to link polyparse to iteratees. Regards, Malcolm From felipe.lessa at gmail.com Tue Jan 12 06:25:12 2010 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Tue Jan 12 05:57:54 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <40a414c21001120124k332c8cf0v2b8cfe895dd049a0@mail.gmail.com> References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> <20100111130824.GA7184@whirlpool.galois.com> <221b53ab1001110515u67b6b3d4n2e3d05dcb27926cb@mail.gmail.com> <27114282.post@talk.nabble.com> <1263287018.4399.31165.camel@localhost> <40a414c21001120124k332c8cf0v2b8cfe895dd049a0@mail.gmail.com> Message-ID: <20100112112512.GA15962@kira.casa> On Tue, Jan 12, 2010 at 10:24:22AM +0100, minh thu wrote: > 2010/1/12 Duncan Coutts : > > Any user can then perform the last step themselves and if they're really > > lucky they might get that to work with a slightly modified version of > > the LGPL'ed package. In practise of course this isn't that easy for the > > user because GHC does not make it easy to make ABI compatible packages. > > However it is my understanding that this procedure will comply with the > > LGPL. > > In short, if I understand you correctly, you would just have to > provide your code in unlinked form regardless of the existence of some > tool to create another ABI-compatible version of the LGPL library. > > This alongside of the last discussion (which also roughly said you can > license the code as you want when it is the client responsability to > link the final binary) makes the (L)GPL quite useless (as a "freedom" > keeper) whenever the code is made for specific clients... I don't really follow. GHC inlines aggressively between modules. IMHO you would need to disable cross-module inlining. This means GHC would miss a lot of optimization oportunities. Oh, well. For example, if you use an LGPL concrete monad package and I want to CPS transform it, then all primitive operations would have to be changed. That means *any* inlined code from this module would change. Are you saying that this kind of change would count as "ABI incompatible change"? And so LGPL would say nothing about it? Am I missing something? :o) Cheers, -- Felipe. From tittoassini at gmail.com Tue Jan 12 06:43:06 2010 From: tittoassini at gmail.com (Pasqualino "Titto" Assini) Date: Tue Jan 12 06:15:43 2010 Subject: [Haskell-cafe] Parsers (Parsec and Iteratee-based Parsers) In-Reply-To: References: <4B4B949A.5050309@web.de> <9979e72e1001111448w123e38c1i90ae4276ea800ae3@mail.gmail.com> <4B4BAF95.7030108@web.de> Message-ID: <2d34474e1001120343s67129888t3f8eb5d0fc1bfdd@mail.gmail.com> The frisby parser (http://repetae.net/computer/frisby/) that unfortunately is not well known as it has never been uploaded on hackage also supports lazy parsing. titto 2010/1/12 Malcolm Wallace : >> As I said I've been using Parsec quite a lot, but wonder if there is a >> different approach possible/feasible to parsing. Parsec (2x) isn't an >> "online" parser, ie, it doesn't produce a result before the whole parse is >> completed. >> >> There is AFAIK one alternative, the uulib, > > In addition, the polyparse library provides "online", or lazy, parsing. ?Its > interface is somewhat similar to parsec, perhaps even simpler. ?(Actually, > you can freely mix lazy and strict parsing - laziness is provided by > applicative combinators, strictness by monadic combinators.) ?I have not yet > looked into whether it would be possible to link polyparse to iteratees. > > Regards, > ? ?Malcolm > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- Pasqualino "Titto" Assini, Ph.D. http://quicquid.org/ From stephen.tetley at gmail.com Tue Jan 12 07:02:46 2010 From: stephen.tetley at gmail.com (Stephen Tetley) Date: Tue Jan 12 06:35:23 2010 Subject: [Haskell-cafe] Parsers (Parsec and Iteratee-based Parsers) In-Reply-To: <2d34474e1001120343s67129888t3f8eb5d0fc1bfdd@mail.gmail.com> References: <4B4B949A.5050309@web.de> <9979e72e1001111448w123e38c1i90ae4276ea800ae3@mail.gmail.com> <4B4BAF95.7030108@web.de> <2d34474e1001120343s67129888t3f8eb5d0fc1bfdd@mail.gmail.com> Message-ID: <5fdc56d71001120402n882572ag9942b48a81640d58@mail.gmail.com> 2010/1/12 Pasqualino "Titto" Assini : > The frisby parser (http://repetae.net/computer/frisby/) that > unfortunately is not well known as it has never been uploaded on > hackage also supports lazy parsing. Doaitse Swierstra's new version of UU supports online parsing too: http://hackage.haskell.org/package/uu-parsinglib Later versions of the original UU.Parsing look like they incorporate a version the Steps data type from the "Polish Parsers, Step by Step" paper so they will also support online parsing. Its worth re-iterating that the type of the parse result has to support 'lazyness' for the technique to be useful... Best wishes Stephen From duncan.coutts at googlemail.com Tue Jan 12 07:38:23 2010 From: duncan.coutts at googlemail.com (Duncan Coutts) Date: Tue Jan 12 07:11:03 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <40a414c21001120124k332c8cf0v2b8cfe895dd049a0@mail.gmail.com> References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> <20100111130824.GA7184@whirlpool.galois.com> <221b53ab1001110515u67b6b3d4n2e3d05dcb27926cb@mail.gmail.com> <27114282.post@talk.nabble.com> <1263287018.4399.31165.camel@localhost> <40a414c21001120124k332c8cf0v2b8cfe895dd049a0@mail.gmail.com> Message-ID: <1263299903.4399.32436.camel@localhost> On Tue, 2010-01-12 at 10:24 +0100, minh thu wrote: > In short, if I understand you correctly, you would just have to > provide your code in unlinked form regardless of the existence of some > tool to create another ABI-compatible version of the LGPL library. Right. The procedure I mentioned is just to ensure that it is at least possible, so that you don't accidentally provide your code in unlinked form that's totally borked! :-) By making the single large .o form and then using that to make your final exe, then you guarantee that there were no missing symbols or whatever in the .o form that you will provide. > This alongside of the last discussion (which also roughly said you can > license the code as you want when it is the client responsability to > link the final binary) makes the (L)GPL quite useless (as a "freedom" > keeper) whenever the code is made for specific clients... It guarantees your client has the freedoms under the LGPL. If they choose never to redistribute then of course that's up to them and so any improvements you or they have made will not be available for upstream. But that is the intent of the LGPL, to protect the rights of the users *receiving* the code, not to guarantee that modifications are available to the entire world. Duncan From daniel.is.fischer at web.de Tue Jan 12 08:00:25 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Tue Jan 12 07:34:43 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001090452.48889.daniel.is.fischer@web.de> Message-ID: <201001121400.25492.daniel.is.fischer@web.de> Am Dienstag 12 Januar 2010 11:30:07 schrieb Heinrich Apfelmus: > Tricky stuff. It is known that pairs/records are prone to unwanted > retention, see for example the recent thread > > http://thread.gmane.org/gmane.comp.lang.haskell.cafe/66903/focus=67871 > > or > > Jan Sparud. Fixing some space leaks without a garbage collector. > http://citeseer.ist.psu.edu/240848.html "CiteSeerx is momentarily busy, Please try us again, in a few moments. We apologize for any inconvenience." :( tried and re-tried. Took http://bert.md.chalmers.se/pub/cs-reports/papers/sparud/spaceleak- fix.ps.gz finally > > It is exactly because these troubles that I'm advocating the original > VIP data structure that buries the dorks (that name is awesome :D) deep > inside the structure. :) > > > In any case, it appears to me that the lazy pattern match in mergeSP > is actually unnecessary! This is because mergeSP returns a pair > constructor immediately, so infinite nesting works even when the second > argument is demanded. In other words, > > mergeSP :: Integral a => People a -> People a -> People a > mergeSP (P a b) (P c d) = P (a ++ bc) (merge b' d) > where > P bc b' = spMerge b c > spMerge [] ys = P [] ys > spMerge xs [] = P [] xs > spMerge xs@(x:xt) ys@(y:yt) = case compare x y of > LT -> celebrate x (spMerge xt ys) > EQ -> celebrate x (spMerge xt yt) > GT -> celebrate y (spMerge xs yt) > > should work fine and do away with the memory issue because the pair is > now deconstructed immediately. No, <>. For the reason you stated below. In tfold f (a:b:c:xs) = (a `f` (b `f` c)) `f` smartfold f xs , it must compute smartfold f xs too early to match it against P c d. The compiler can't see that smartfold mergeSP always returns a P [well, it might return _|_, mightn't it?]. > > Hm, a strict second argument might however mean that the tree produced > by tfold is demanded too early. > > > > Regards, > Heinrich Apfelmus > > -- > http://apfelmus.nfshost.com From gue.schmidt at web.de Tue Jan 12 11:52:50 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Tue Jan 12 11:54:25 2010 Subject: [Haskell-cafe] on Happstack - "embedded HTML" Message-ID: <4B4CA8E2.6070800@web.de> Hi, I'm just introducing myself to Happstack. I come across an example page where HTML and haskell code is mixed. Is this how happstack produces html, it's haskell code embedded in HTML? G?nther From gue.schmidt at web.de Tue Jan 12 12:54:48 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Tue Jan 12 12:54:21 2010 Subject: [Haskell-cafe] status of wash? Message-ID: <4B4CB768.2080704@web.de> Hi, is WASH still active, what's the current status of it? I'm looking for a Haskell version of Smalltalk's Seaside, at first glance WASH seems to come close. G?nther From mightybyte at gmail.com Tue Jan 12 13:31:27 2010 From: mightybyte at gmail.com (MightyByte) Date: Tue Jan 12 13:04:05 2010 Subject: [Haskell-cafe] on Happstack - "embedded HTML" In-Reply-To: <4B4CA8E2.6070800@web.de> References: <4B4CA8E2.6070800@web.de> Message-ID: The example you came across is probably using HSP [1] to generate HTML. Happstack isn't tied to a specific method of generating HTML. You could use HSP or other libraries such as html-minimalist [2], xhtml [3], HStringTemplate [4], or even plain old manual construction of strings. [1] http://www.cs.chalmers.se/~d00nibro/hsp/ [2] http://hackage.haskell.org/package/html-minimalist [3] http://hackage.haskell.org/package/xhtml [4] http://hackage.haskell.org/package/HStringTemplate 2010/1/12 G?nther Schmidt : > Hi, > > I'm just introducing myself to Happstack. I come across an example page > where HTML and haskell code is mixed. > > Is this how happstack produces html, it's haskell code embedded in HTML? > > G?nther > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From alexey.skladnoy at gmail.com Tue Jan 12 13:33:31 2010 From: alexey.skladnoy at gmail.com (Khudyakov Alexey) Date: Tue Jan 12 13:05:42 2010 Subject: [Haskell-cafe] Tokenizing and Parsec In-Reply-To: <4B4BC3BE.7050806@web.de> References: <4B4BC3BE.7050806@web.de> Message-ID: <201001122133.31582.alexey.skladnoy@gmail.com> ? ????????? ?? 12 ?????? 2010 03:35:10 G?nther Schmidt ???????: > Hi all, > > I've used Parsec to "tokenize" data from a text file. It was actually > quite easy, everything is correctly identified. > > So now I have a list/stream of self defined "Tokens" and now I'm stuck. > Because now I need to write my own parsec-token-parsers to parse this > token stream in a context-sensitive way. > > Uhm, how do I that then? > That's pretty easy actually. You can use function `token' to define you own primitive parsers. It's defined in Parsec.Prim If I'm correctly remember. Also you could want to add information about position in the source code to you lexems. Here is some code to illustrate usage: > > -- | Language lexem > data LexemData = Ident String > | Number Double > | StringLit String > | None > | EOL > deriving (Show,Eq) > > data Lexem = Lexem { lexemPos :: SourcePos > , lexemData :: LexemData > } > deriving Show > > type ParserLex = Parsec [Lexem] () > > num :: ParserLex Double > num = token (show . lexemData) lexemPos (comp . lexemData) > where > comp (Number x) = Just x > comp _ = Nothing From marco-oweber at gmx.de Tue Jan 12 13:37:04 2010 From: marco-oweber at gmx.de (Marc Weber) Date: Tue Jan 12 13:10:07 2010 Subject: [Haskell-cafe] status of wash? In-Reply-To: <4B4CB768.2080704@web.de> References: <4B4CB768.2080704@web.de> Message-ID: <1263320952-sup-2060@nixos> Hi G?nther, the ideas of WASH will never die. However AFAIK the implentation has never been updated to work with servers such as HappStack. I may be wrong about this. I tried making WASH perfect by getting 100% DTD validation: http://github.com/MarcWeber/vxml Somewhen I was lost in the type system. I also noticed that I don't want 100% validation because this actually means you can't write
Because the XHTML DTD does't allow empty uls. It's not a big problem though. It's not ready to be used. That's why I didn't even upload it to hackage. I'll watch this thread and I'll see who can give more information. Marc Weber From niklas.broberg at gmail.com Tue Jan 12 14:04:43 2010 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Tue Jan 12 13:37:21 2010 Subject: [Haskell-cafe] on Happstack - "embedded HTML" In-Reply-To: References: <4B4CA8E2.6070800@web.de> Message-ID: > [1] http://www.cs.chalmers.se/~d00nibro/hsp/ Oops. Seeing this link was a rather painful reminder that I ought to update that page. Last update was 2005, HSP has evolved quite a lot since then... The best way to get info on HSP in its current state is probably to check out some of the stuff that Jeremy Shaw has written. I'm sure he can give you better pointers than me. :-) Cheers, /Niklas From sebf at informatik.uni-kiel.de Tue Jan 12 14:46:48 2010 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Tue Jan 12 14:19:27 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <1263299903.4399.32436.camel@localhost> References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> <20100111130824.GA7184@whirlpool.galois.com> <221b53ab1001110515u67b6b3d4n2e3d05dcb27926cb@mail.gmail.com> <27114282.post@talk.nabble.com> <1263287018.4399.31165.camel@localhost> <40a414c21001120124k332c8cf0v2b8cfe895dd049a0@mail.gmail.com> <1263299903.4399.32436.camel@localhost> Message-ID: <3B657BBD-BD73-4F61-B720-E4C0BB77E43E@informatik.uni-kiel.de> On Jan 12, 2010, at 1:38 PM, Duncan Coutts wrote: > But that is the intent of the LGPL, to protect the rights of the users > *receiving* the code, not to guarantee that modifications are > available > to the entire world. I wonder whether the following statements are valid: When I write a program that uses an LGPL library, I am allowed to distribute the *sources* of my program under a permissive (non- copyleft) license like BSD3. I am not allowed to distribute my program in *binary* form under a permissive license (even if I release the sources too). Am I allowed to distribute the sources under BSD3 and the binary under LGPL? Would that make sense? Maybe not, because anyone who distributes a binary of my program or derivative work must license it under LGPL anyway. Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From sebf at informatik.uni-kiel.de Tue Jan 12 15:21:04 2010 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Tue Jan 12 14:53:41 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <3B657BBD-BD73-4F61-B720-E4C0BB77E43E@informatik.uni-kiel.de> References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> <20100111130824.GA7184@whirlpool.galois.com> <221b53ab1001110515u67b6b3d4n2e3d05dcb27926cb@mail.gmail.com> <27114282.post@talk.nabble.com> <1263287018.4399.31165.camel@localhost> <40a414c21001120124k332c8cf0v2b8cfe895dd049a0@mail.gmail.com> <1263299903.4399.32436.camel@localhost> <3B657BBD-BD73-4F61-B720-E4C0BB77E43E@informatik.uni-kiel.de> Message-ID: <8720B814-94F1-47D2-B226-DF130199F140@informatik.uni-kiel.de> On Jan 12, 2010, at 8:46 PM, Sebastian Fischer wrote: > Am I allowed to distribute the sources under BSD3 and the binary > under LGPL? > > Would that make sense? Maybe not, because anyone who distributes a > binary of my program or derivative work must license it under LGPL > anyway. Well it may make sense. People can write a replacement for the LGPL code, modify my code to use it, and distribute a binary without distributing the sources. They could not do this, if my sources were LGPL licensed. Sounds valid? -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From ketil at malde.org Tue Jan 12 15:21:49 2010 From: ketil at malde.org (Ketil Malde) Date: Tue Jan 12 14:54:24 2010 Subject: [Haskell-cafe] short licensing question In-Reply-To: <3B657BBD-BD73-4F61-B720-E4C0BB77E43E@informatik.uni-kiel.de> (Sebastian Fischer's message of "Tue, 12 Jan 2010 20:46:48 +0100") References: <8D53580D-91C1-4FE7-9997-383B0CDD9B3B@informatik.uni-kiel.de> <20100111130824.GA7184@whirlpool.galois.com> <221b53ab1001110515u67b6b3d4n2e3d05dcb27926cb@mail.gmail.com> <27114282.post@talk.nabble.com> <1263287018.4399.31165.camel@localhost> <40a414c21001120124k332c8cf0v2b8cfe895dd049a0@mail.gmail.com> <1263299903.4399.32436.camel@localhost> <3B657BBD-BD73-4F61-B720-E4C0BB77E43E@informatik.uni-kiel.de> Message-ID: <87skaboyzm.fsf@malde.org> Sebastian Fischer writes: > I wonder whether the following statements are valid: You want my layman's opinion? > When I write a program that uses an LGPL library, I am allowed to > distribute the *sources* of my program under a permissive (non- > copyleft) license like BSD3. Yes. I don't think using an API counts as deriving a work - the alternative would be to difficult and have too many dire consequences that would go against current practice (any program on, say, Linux, would be a derived work of the kernel - and probably vice versa). > I am not allowed to distribute my program in *binary* form under a > permissive license (even if I release the sources too). This would be a shame, since this is the whole raison d'?tre for LGPL. The point of LGPL is to ensure that any recipients of your program is able, should they so desire, to replace the LGPL library with a modified version. > Am I allowed to distribute the sources under BSD3 and the binary under > LGPL? I'm not sure this makes a lot of sense. But clearly, you can't redistribute somebodys LGPL library as BSD3, wether in binary or source form. You may of course distribute your bits as BSD3, which anybody could redistribute as LGPL or GPL. The point of LGPL is to be somewhat less "viral" than the GPL in that you may link LGPL code with otherwise licensed code and even proprietary, binary only code.? E.g. readline, which was explicitly GPL to "force" more software to adopt that license, while LGPL would "encourage" keeping different license. ? Whether the current license achieves this is a different matter, and LGPL is clearly either too strict or too lenient for most people. I like it, though. -k -- If I haven't seen further, it is by standing in the footprints of giants From alistair at abayley.org Tue Jan 12 15:43:11 2010 From: alistair at abayley.org (Alistair Bayley) Date: Tue Jan 12 15:15:48 2010 Subject: [Haskell-cafe] ssh ports for monk and nun? Message-ID: <79d7c4981001121243j708b6127r5cd5312f0cb97246@mail.gmail.com> Trying to get ssh working via putty from behind my company firewall. Had some success in the past with sourceforge because they had ssh daemons listening on ports 80 and 443, to aid prisoners like myself. Does anyone know if the monk (darcs.haskell.org) and nun (code.haskell.org) servers accept ssh on ports other than 22? Thanks, Alistair From jason.dusek at gmail.com Tue Jan 12 15:47:56 2010 From: jason.dusek at gmail.com (Jason Dusek) Date: Tue Jan 12 15:20:32 2010 Subject: [Haskell-cafe] ssh ports for monk and nun? In-Reply-To: <79d7c4981001121243j708b6127r5cd5312f0cb97246@mail.gmail.com> References: <79d7c4981001121243j708b6127r5cd5312f0cb97246@mail.gmail.com> Message-ID: <42784f261001121247p1cb93c11o6edaeecddb3c8887@mail.gmail.com> Monk and nun? -- Jason Dusek From alistair at abayley.org Tue Jan 12 15:54:31 2010 From: alistair at abayley.org (Alistair Bayley) Date: Tue Jan 12 15:27:09 2010 Subject: [Haskell-cafe] ssh ports for monk and nun? In-Reply-To: <42784f261001121247p1cb93c11o6edaeecddb3c8887@mail.gmail.com> References: <79d7c4981001121243j708b6127r5cd5312f0cb97246@mail.gmail.com> <42784f261001121247p1cb93c11o6edaeecddb3c8887@mail.gmail.com> Message-ID: <79d7c4981001121254y66b435fbjdac170a28dcb18a9@mail.gmail.com> 2010/1/12 Jason Dusek : > ?Monk and nun? The haskell.org code/project/... servers: http://www.haskell.org/haskellwiki/Haskell.org_domain From alistair at abayley.org Tue Jan 12 15:57:44 2010 From: alistair at abayley.org (Alistair Bayley) Date: Tue Jan 12 15:30:28 2010 Subject: [Haskell-cafe] Re: ssh ports for monk and nun? In-Reply-To: <79d7c4981001121243j708b6127r5cd5312f0cb97246@mail.gmail.com> References: <79d7c4981001121243j708b6127r5cd5312f0cb97246@mail.gmail.com> Message-ID: <79d7c4981001121257i2a8a230elad85ba04b45b2ec6@mail.gmail.com> > Trying to get ssh working via putty from behind my company firewall. > Had some success in the past with sourceforge because they had ssh > daemons listening on ports 80 and 443, to aid prisoners like myself. > Does anyone know if the monk (darcs.haskell.org) and nun > (code.haskell.org) servers accept ssh on ports other than 22? I should also have said: I'm open to suggestions and advice on using darcs+cabal+ssh with restrictive firewalls and http proxies. I currently have cntlm (an authenticating proxy server) installed, so I can use cabal (and darcs get will work with this too), but I want to be able to push patches too. Alistair From andrewcoppin at btinternet.com Tue Jan 12 16:25:34 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Tue Jan 12 15:57:57 2010 Subject: [Haskell-cafe] Language simplicity Message-ID: <4B4CE8CE.9060202@btinternet.com> OK people, it's random statistics time! Haskell '98 apparently features 25 reserved words. (Not counting "forall" and "mdo" and so on, which AFAIK are not in Haskell '98.) So how does that compare to other languages? C: 32 C++: 62 Borland Turbo Pascal: ~50 [without the OOP extensions added later] Eiffel: 59 VB: The source I checked listed in excess of 120 reserved words, but I'm dubious as to how "reserved" they really are. (Is CInt really reserved? I doubt it!) It also depends wildly on which of the bazillion VB dialects you mean. Java: 50 JavaScript: 36 Smalltalk: 0 Lisp: AFAIK, there are no truly reserved words in Lisp, only predefined functions. (??) Python: 31 Ruby: 38 Tcl: Same analysis as for Lisp I believe. As you can see, this conclusively proves... something. Hmm, I wonder if there's some way to compare the size of the language specification documents? :-} PS. It comes as absolutely no surprise to me that C++ has the most keywords. But then, if I were to add AMOS Professional, that had well over 800 keywords at the last count... From niklas.broberg at gmail.com Tue Jan 12 17:12:20 2010 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Tue Jan 12 16:44:58 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4CE8CE.9060202@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> Message-ID: > Haskell '98 apparently features 25 reserved words. (Not counting "forall" > and "mdo" and so on, which AFAIK are not in Haskell '98.) 21 actually. case, class, data, default, deriving, do, else, if, import, in, infix, infixl, infixr, instance, let, module, newtype, of, then, type, where. There's also three special words that can still be used as identifiers, so aren't reserved: as, qualified, hiding. /Niklas From andrewcoppin at btinternet.com Tue Jan 12 17:22:38 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Tue Jan 12 16:55:00 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> Message-ID: <4B4CF62E.5090206@btinternet.com> Niklas Broberg wrote: >> Haskell '98 apparently features 25 reserved words. (Not counting "forall" >> and "mdo" and so on, which AFAIK are not in Haskell '98.) >> > > 21 actually. case, class, data, default, deriving, do, else, if, > import, in, infix, infixl, infixr, instance, let, module, newtype, of, > then, type, where. There's also three special words that can still be > used as identifiers, so aren't reserved: as, qualified, hiding. > OK. Well the list I saw was for Haskell plus extensions, and I visually filtered out the inapplicable stuff. Apparently I missed something. Also, the number varies depending on whether you consider "reversed words" or "keywords", and I suspect the situation is subtly different for each possible language. I was going vaguely for anything that's hard-wired into a language, and not just part of the standard libraries. (E.g., "return" is definitely NOT any kind of reversed word or keyword.) From gue.schmidt at web.de Tue Jan 12 17:24:16 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Tue Jan 12 16:58:03 2010 Subject: [Haskell-cafe] Windows Automation - COM package - HaskellDirect Message-ID: <4B4CF690.4010002@web.de> Hi all, I want to use Sigbjorn's com-package to do some automation under Windows. There seems to be some program "HaskellDirect" wich can create Haskell modules from type-libs, it's mentioned in the examples to the com package on Sigbjorn's site http://haskell.forkio.com/com-examples . Cabal install com does not seem to build / install the program though. Does anybody know how to get it? G?nther From daniel.is.fischer at web.de Tue Jan 12 17:26:31 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Tue Jan 12 17:00:47 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> Message-ID: <201001122326.31495.daniel.is.fischer@web.de> Am Dienstag 12 Januar 2010 23:12:20 schrieb Niklas Broberg: > > Haskell '98 apparently features 25 reserved words. (Not counting > > "forall" and "mdo" and so on, which AFAIK are not in Haskell '98.) > > 21 actually. case, class, data, default, deriving, do, else, if, > import, in, infix, infixl, infixr, instance, let, module, newtype, of, > then, type, where. There's also three special words that can still be > used as identifiers, so aren't reserved: as, qualified, hiding. Okay, 'as' is easy. But can you find a situation where 'qualified' or 'hiding' would be natural choices for an identifier? I'd love to see those in some code :) > > /Niklas From andrewcoppin at btinternet.com Tue Jan 12 17:32:24 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Tue Jan 12 17:04:45 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <201001122326.31495.daniel.is.fischer@web.de> References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> Message-ID: <4B4CF878.3070407@btinternet.com> Daniel Fischer wrote: > Am Dienstag 12 Januar 2010 23:12:20 schrieb Niklas Broberg: > >>> Haskell '98 apparently features 25 reserved words. (Not counting >>> "forall" and "mdo" and so on, which AFAIK are not in Haskell '98.) >>> >> 21 actually. case, class, data, default, deriving, do, else, if, >> import, in, infix, infixl, infixr, instance, let, module, newtype, of, >> then, type, where. There's also three special words that can still be >> used as identifiers, so aren't reserved: as, qualified, hiding. >> > > Okay, 'as' is easy. But can you find a situation where 'qualified' or > 'hiding' would be natural choices for an identifier? I'd love to see those > in some code :) > I quite often try to use "in-file" and "out-file" abbreviated to "if" and "of" - which obviously fails miserably. And "as" is pretty simple, as you point out. It's weird that us Haskell people complain about there being only 26 letters in the alphabet when all other known programming languages emphasize the use of long, descriptive names like "log_file" instead of "lf"... From mikehartl at web.de Tue Jan 12 17:38:11 2010 From: mikehartl at web.de (Michael Hartl) Date: Tue Jan 12 17:10:47 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4CF62E.5090206@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> <4B4CF62E.5090206@btinternet.com> Message-ID: <1263335891.2758.1.camel@cangaroo> Am Dienstag, den 12.01.2010, 22:22 +0000 schrieb Andrew Coppin: > Niklas Broberg wrote: > >> Haskell '98 apparently features 25 reserved words. (Not counting "forall" > >> and "mdo" and so on, which AFAIK are not in Haskell '98.) > >> > > > > 21 actually. case, class, data, default, deriving, do, else, if, > > import, in, infix, infixl, infixr, instance, let, module, newtype, of, > > then, type, where. There's also three special words that can still be > > used as identifiers, so aren't reserved: as, qualified, hiding. > > > > OK. Well the list I saw was for Haskell plus extensions, and I visually > filtered out the inapplicable stuff. Apparently I missed something. > > Also, the number varies depending on whether you consider "reversed > words" or "keywords", and I suspect the situation is subtly different "reversed words"? There are some in sh for example, namely 'fi' and 'esac', but other than that they are not that common... ;-) > for each possible language. I was going vaguely for anything that's > hard-wired into a language, and not just part of the standard libraries. > (E.g., "return" is definitely NOT any kind of reversed word or keyword.) > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From tonymorris at gmail.com Tue Jan 12 17:44:24 2010 From: tonymorris at gmail.com (Tony Morris) Date: Tue Jan 12 17:16:52 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4CE8CE.9060202@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> Message-ID: <4B4CFB48.7030809@gmail.com> Andrew Coppin wrote: > OK people, it's random statistics time! > > Haskell '98 apparently features 25 reserved words. (Not counting > "forall" and "mdo" and so on, which AFAIK are not in Haskell '98.) So > how does that compare to other languages? > > C: 32 > C++: 62 > Borland Turbo Pascal: ~50 [without the OOP extensions added later] > Eiffel: 59 > VB: The source I checked listed in excess of 120 reserved words, but > I'm dubious as to how "reserved" they really are. (Is CInt really > reserved? I doubt it!) It also depends wildly on which of the > bazillion VB dialects you mean. > Java: 50 > JavaScript: 36 > Smalltalk: 0 > Lisp: AFAIK, there are no truly reserved words in Lisp, only > predefined functions. (??) > Python: 31 > Ruby: 38 > Tcl: Same analysis as for Lisp I believe. > > As you can see, this conclusively proves... something. > > Hmm, I wonder if there's some way to compare the size of the language > specification documents? :-} > > PS. It comes as absolutely no surprise to me that C++ has the most > keywords. But then, if I were to add AMOS Professional, that had well > over 800 keywords at the last count... > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > Java has 53 reserved words. -- Tony Morris http://tmorris.net/ From andrewcoppin at btinternet.com Tue Jan 12 17:54:44 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Tue Jan 12 17:27:06 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4CFB48.7030809@gmail.com> References: <4B4CE8CE.9060202@btinternet.com> <4B4CFB48.7030809@gmail.com> Message-ID: <4B4CFDB4.6060807@btinternet.com> Tony Morris wrote: > Andrew Coppin wrote: > >> Java: 50 >> >> > Java has 53 reserved words. > Damnit. They must have added a few more... (The material I quoted from had notes about which version of Java added certain of the words. I guess it was outdated.) From bulat.ziganshin at gmail.com Tue Jan 12 18:17:07 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Tue Jan 12 17:49:55 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4CFDB4.6060807@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> <4B4CFB48.7030809@gmail.com> <4B4CFDB4.6060807@btinternet.com> Message-ID: <1886626135.20100113021707@gmail.com> Hello Andrew, Wednesday, January 13, 2010, 1:54:44 AM, you wrote: > (The material I quoted from had notes about which version of Java added > certain of the words. I guess it was outdated.) you would be more respected in this list if you will compare haskell 1.0 with java'2010 or better '2020 ;) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From qdunkan at gmail.com Tue Jan 12 18:29:49 2010 From: qdunkan at gmail.com (Evan Laforge) Date: Tue Jan 12 18:02:25 2010 Subject: [Haskell-cafe] wildcards for type variables? Message-ID: <2518b95d1001121529l60701d44y13ecf6614c82d1a6@mail.gmail.com> Occasionally I have a function with an unused argument, whose type I don't want to restrict. Thus: f :: _unused -> A -> B f _ a = b Since it's a little unusual, I try to make it clear that the type is intentionally ignored. But it makes me wonder, would it make sense to allow _ as a type variable name, with the same meaning as in pattern matching? From sylvain.nahas at googlemail.com Tue Jan 12 18:35:54 2010 From: sylvain.nahas at googlemail.com (sylvain) Date: Tue Jan 12 18:08:33 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4CE8CE.9060202@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> Message-ID: <1263339354.4862.122.camel@dell.linuxdev.us.dell.com> Le mardi 12 janvier 2010 ? 21:25 +0000, Andrew Coppin a ?crit : Hi Andrew, > As you can see, this conclusively proves... something. What, exactly? Take Eiffel in its last version: I have identified 11 keywords that are either used for Design By Contract or source-code documentation. These are software engineering tasks that in the other languages you cite are not supported at the grammar level and, if ever, fulfilled by enriching the code using comments, annotations or compiler extensions. Removed, this make Eiffel the less "verbose" object-oriented language of your list, excepted Smalltalk. In any case the less verbose statically typed compiled OO language. One factor is how rich is the set of OO constructs supported by the language. Visibility rule keywords may shrink or extend the list of reserved words. Same for math or logical operators: some languages define as keyword what belongs to libraries in another. Same for exception mechanism. Some languages defines the code block constructs using keywords while other use tokens that are not considered reserved words. Contrast for example the following Ada code (4 keywords): procedure Hello is begin ... end Hello; against the equivalent C (1 keyword): void HelloWorld() { ... } or the equivalent Haskell (0 keywords): helloworld = ... Ada in its 71 reserved words features keywords for concurrent programming that doesn't exist at the same level in the other languages in your list, and an explicit "pragma" keyword to allow the programmer to specify things like the alignement used in the generated binary. So a significant factor in programming language "verbosity" is how much control the language intends to give to the programmer on the implementation level - or said otherwise how abstracted is the language from its run-time environment. Let me order your list: Smalltalk: 0 Lisp: 0 Tcl: 0 Haskell: 21 * Python: 31 C: 32 * JavaScript: 36 Ruby: 38 --- Borland Turbo Pascal: ~50 Java: 53 Eiffel: 59 C++: 62 Interestingly enough, interpreted languages tend to need less keywords, which support my observation above. Let ignore C. Noticeable is Haskell, with little reserved words while being efficiently compiled. It reflects the fact that it does not have elaborated object-oriented constructs, that code is structured using layout rules, that the exception and concurrency mechanisms are provided at the library level, that there is no way to control the code generated, and that there is no built-in support for software engineering like the sort Eiffel provides. It reflects as well the "expressiveness" of Haskell and how good at abstracting the description of a computation from its run-time environment it is. But if you really wanted to compare apples to apples you would, for instance, add GHC pragmas and "magic" things like `par` to the mix. I wonder if the picture would change much? > Hmm, I wonder if there's some way to compare the size of the language > specification documents? :-} Maybe comparing the grammars in a standardized form (BNF) ? Cheers, Sylvain From tomahawkins at gmail.com Tue Jan 12 18:53:48 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Tue Jan 12 18:26:25 2010 Subject: [Haskell-cafe] ANN: afv-0.0.0 Message-ID: <594c1e831001121553l53b51168h151334853e0e9a36@mail.gmail.com> Hi, Here is the first release of Atom's Formal Verifier (AFV) [1], a tool intended to verify Atom -- or human -- generated C code. With the help of the Yices SMT solver [2], AFV uses bounded model checking and k-induction to verify assertions in iteratively called C functions, such as an embedded control loop. For each assertion in a design, AFV will return a pass, a fail, or an inconclusive result -- or it will die trying. In addition to Yices, AFV needs GCC for C preprocessing. This is a very early release. There are many things missing including counter example generation, finite precision modeling, and basic model reduction. And they is a chance -- say about 100% -- that there are bugs with the modeling transformations. In addition, the list of unsupported C syntax is embarrassingly long: - recursive functions - non-unique top level names (e.g. top level names hidden with static) - loops - switch statements - pointers - arrays - type casting - non void functions - functions with arguments - structs - enums - unions - typedefs Still, AFV works well for the handful of tests I have tried so far. AFV comes with a simple example. To run: $ afv example # This generates afv.h and example.c shown below... // Provides assert and assume functions. #include "afv.h" // Periodic function for verification. Implements a simple rolling counter. void example () { // The rolling counter. static int counter = 0; // Assertions. GreaterThanOrEqualTo0: assert(counter >= 0); // The 'counter' must always be greater than or equal to 0. LessThan10: assert(counter < 10); // The 'counter' must always be less than 10. // Implementation 1. if (counter == 10) counter = 0; else counter++; // Implementation 2. // if (counter == 9) // counter = 0; // else // counter = counter + 1; // Implementation 3. // if (counter >= 9) // counter = 0; // else // counter++; // Implementation 4. // if (counter >= 9 || counter < 0) // counter = 0; // else // counter++; // Implementation 5. // counter = (counter + 1) % 10; } To run the verification on the example: $ afv verify example -k 20 example.c # Which returns... parsing example.c ... verifying assertion example.GreaterThanOrEqualTo0.assert ... inconclusive: unable to proved step up to max k = 20 verifying assertion example.LessThan10.assert ... FAILED: disproved basis in k = 11 These results state AFV was unable to prove the "GreaterThanOrEqualTo0" assertion and it disproved the "LessThan10" assertion. The different implementations in the example yield different results. Any feedback or questions are more than welcome. I would like to thank Benedikt Huber and friends for the language-c library [3], Ki Yung Ahn for the yices library [4], and the folks at SRI for their work on the Yices SMT solver. Without these tools and libraries, AFV would not have been possible. -Tom [1] http://hackage.haskell.org/package/afv [2] http://yices.csl.sri.com/ [3] http://hackage.haskell.org/package/language-c [4] http://hackage.haskell.org/package/yices From agocorona at gmail.com Tue Jan 12 19:17:17 2010 From: agocorona at gmail.com (Alberto G. Corona ) Date: Tue Jan 12 18:49:53 2010 Subject: [Haskell-cafe] overloaded overloading? Message-ID: Hi, I sometimes strumble on the same quiestion that forces me to insert functions that process objects of a certain class inside their class definition. This occurs when a computation uses the object internally, neiter as parameter or as a return value or in the case of existential types. An example of the first: class Example a where irec :: IO a pr :: a ? IO String sample2 :: a ? IO () sample2 _ = do x ? irec :: IO a pr x return () sample :: Example a ? a ? IO () sample _ = do x ? irec :: IO a pr x return () With the flag -fglasgow-exts, the following error below appears in sample. without the flag, the error appears in both sample and sample2. I?m too lazy to find what concrete extension is involved and why, anyhow, in the case of sample, the compiler must generate a new type a1 with no context. Could not deduce (Example a1) from the context () arising from a use of `irec' at Control\Workflow\Users.hs:73:7-10 Possible fix: add (Example a1) to the context of an expression type signature In a stmt of a 'do' expression: x <- irec :: IO a In the expression: do x <- irec :: IO a pr x return () -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100112/949a358e/attachment.html From brad.larsen at gmail.com Tue Jan 12 19:25:00 2010 From: brad.larsen at gmail.com (Brad Larsen) Date: Tue Jan 12 18:57:35 2010 Subject: [Haskell-cafe] overloaded overloading? In-Reply-To: References: Message-ID: Alberto, On Tue, Jan 12, 2010 at 7:17 PM, Alberto G. Corona wrote: > Hi, > > I sometimes strumble on the same quiestion that forces me to insert > functions that?process objects of a certain class?inside their?class > definition.? This occurs when a computation uses the object internally, > neiter as parameter or as a return value or in the case of existential > types. An example of the first: > > > class Example a where > ??? irec ::? IO a > ??? pr :: a ?? IO String > ??? sample2 ::? a? ??? IO () > ??? sample2?_? =?? do > ????? x ?? irec :: IO a > ????? pr x > ????? return () > > sample :: Example a ? a? ??? IO () > sample?_? =?? do > ? x ?? irec :: IO a > ? pr x > ? return () > > > With the flag?-fglasgow-exts, the following error below?appears in sample. > without the flag, the error appears in both sample and sample2. I?m too lazy > to find what concrete extension is involved and why, anyhow, in the case > of?sample,?the compiler must?generate a new type a1 with no?context. > > ??? Could not deduce (Example a1) from the context () > ????? arising from a use of `irec' at Control\Workflow\Users.hs:73:7-10 > ??? Possible fix: > ????? add (Example a1) to the context of an expression type signature > ??? In a stmt of a 'do' expression: x <- irec :: IO a > ??? In the expression: > ??????? do x <- irec :: IO a > ?????????? pr x > ?????????? return () > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe In the code for `sample', you give a type signature to x, `IO a'. However, the `a' there is different from the `a' in the signature for `sample'. Perhaps ScopedTypeVariables will help? Sincerely, Brad From daniel.is.fischer at web.de Tue Jan 12 19:33:12 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Tue Jan 12 19:07:29 2010 Subject: [Haskell-cafe] overloaded overloading? In-Reply-To: References: Message-ID: <201001130133.13406.daniel.is.fischer@web.de> Am Mittwoch 13 Januar 2010 01:17:17 schrieb Alberto G. Corona: > Hi, > > I sometimes strumble on the same quiestion that forces me to insert > functions that process objects of a certain class inside their class > definition. This occurs when a computation uses the object internally, > neiter as parameter or as a return value or in the case of existential > types. An example of the first: > > > class Example a where > irec :: IO a > pr :: a ? IO String > sample2 :: a ? IO () > sample2 _ = do > x ? irec :: IO a > pr x > return () > > sample :: Example a ? a ? IO () > sample _ = do > x ? irec :: IO a > pr x > return () > > > With the flag -fglasgow-exts, the following error below appears in > sample. without the flag, the error appears in both sample and sample2. > I?m too lazy to find what concrete extension is involved and why, {-# LANGUAGE ScopedTypeVariables #-} sample :: forall a. Example a => a -> IO () sample _ = do x <- irec :: IO a pr x return () Unless you bring the type variable a into scope, the 'a' in the signature of irec within sample is a fresh type variable, so it looks to the compiler like sample :: Example a => a -> IO () sample _ = do x <- irec :: IO b pr x return () You can make it without language extensions: sample :: Example a => a -> IO () sample dummy = do x <- irec pr (x `asTypeOf` dummy) return () > anyhow, in the case of sample, the compiler must generate a new type a1 > with no context. > > Could not deduce (Example a1) from the context () > arising from a use of `irec' at Control\Workflow\Users.hs:73:7-10 > Possible fix: > add (Example a1) to the context of an expression type signature > In a stmt of a 'do' expression: x <- irec :: IO a > In the expression: > do x <- irec :: IO a > pr x > return () From Eduard.Sergeev at gmail.com Tue Jan 12 19:55:57 2010 From: Eduard.Sergeev at gmail.com (Eduard Sergeev) Date: Tue Jan 12 19:28:32 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4CE8CE.9060202@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> Message-ID: <27137827.post@talk.nabble.com> Andrew Coppin wrote: > > OK people, it's random statistics time! OK, my version of meaningless statistics: C++ (ISO/IEC 14882:1998(E)): 325 pages (712 including standard libraries) C# (ECMA-334): 505 pages (language only) Java: 450 pages (language only?) Scala (2.7): 125 pages (157 including standard library) Eiffel (ECMA-367): 160 pages (language only) ANSI SQL-92: 685 pages (language only) Haskell-98: 77 pages (247 including Prelude) Erlang (4.7.3) 162 pages (251 including builtin functions) Scheme (R5RS): 17 pages (45 including standard procedures) -- View this message in context: http://old.nabble.com/Language-simplicity-tp27134989p27137827.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From allbery at ece.cmu.edu Tue Jan 12 21:00:33 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Tue Jan 12 20:33:35 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <1263335891.2758.1.camel@cangaroo> References: <4B4CE8CE.9060202@btinternet.com> <4B4CF62E.5090206@btinternet.com> <1263335891.2758.1.camel@cangaroo> Message-ID: <3416A23D-4FBF-451D-8648-415633C4A1EB@ece.cmu.edu> On Jan 12, 2010, at 17:38 , Michael Hartl wrote: >> Also, the number varies depending on whether you consider "reversed >> words" or "keywords", and I suspect the situation is subtly different > > "reversed words"? There are some in sh for example, namely 'fi' and > 'esac', but other than that they are not that common... ;-) Algol used them; the Bourne shell picked them up from Algol 60. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100112/775ebeb5/PGP.bin From allbery at ece.cmu.edu Tue Jan 12 21:01:33 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Tue Jan 12 20:34:09 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> Message-ID: <9EE98D56-25E9-4B7E-9CF9-2FE1C12DA9CD@ece.cmu.edu> On Jan 12, 2010, at 17:12 , Niklas Broberg wrote: >> Haskell '98 apparently features 25 reserved words. (Not counting >> "forall" >> and "mdo" and so on, which AFAIK are not in Haskell '98.) > > 21 actually. case, class, data, default, deriving, do, else, if, > import, in, infix, infixl, infixr, instance, let, module, newtype, of, > then, type, where. There's also three special words that can still be > used as identifiers, so aren't reserved: as, qualified, hiding. Are we counting the FFI annex ("foreign")? -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100112/3d1b3b86/PGP.bin From colin at colina.demon.co.uk Tue Jan 12 22:23:08 2010 From: colin at colina.demon.co.uk (Colin Paul Adams) Date: Tue Jan 12 21:55:44 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4CF878.3070407@btinternet.com> (Andrew Coppin's message of "Tue\, 12 Jan 2010 22\:32\:24 +0000") References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> <4B4CF878.3070407@btinternet.com> Message-ID: >>>>> "Andrew" == Andrew Coppin writes: Andrew> It's weird that us Haskell people complain about there Andrew> being only 26 letters in the alphabet Which alphabet? You have plenty of choice in Unicode. -- Colin Adams Preston Lancashire From dnmehay at gmail.com Wed Jan 13 00:57:45 2010 From: dnmehay at gmail.com (DNM) Date: Wed Jan 13 00:30:20 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references Message-ID: <27139612.post@talk.nabble.com> Note: I'm relatively new to Haskell, and my knowledge of C and C++ is basically pretty minimal -- I can read, modify and compile C/C++ programs (usually). I'm trying to interface with some C++ code by writing a little bit of C code that uses that C++ code, and I'm getting "undefined reference" errors when I try to 'ghc --make' a client application to test it. Actually, I'm modifying Nitin Madnani's (freely available) Python SRILM toolkit wrapper code. (SRILM, by the bye, is a C++-based toolkit for training and using statistical n-gram language models. I was surprised that no-one has tried to do this yet -- or at least not that they have shared with the rest of us.) Anyhow, I've verified that my modification of Madnani's C code works by compiling it and running it through a SWIG interface in Madnani's Python code, so I'm pretty confident the C client of SRILM is solid. The culprit is either my Haskell FFI code or the client of that code. Without cooking up a microcosm of my problem with little Foo's and Bar's, I'll just give my actual C, header file and Haskell code (or at least the relevant bits), and then the error. ------------- srilm.h ---------------- #ifdef __cplusplus extern "C" { #else typedef struct Ngram Ngram; /* dummy type to stand in for class */ #endif Ngram* bldLM(int order, const char* filename); void deleteLM(Ngram* ngram); float getSeqProb(Ngram* ngram, const char* ngramstr, unsigned order, unsigned length); #ifdef __cplusplus } #endif ----------------------------------------- ------------- srilm.c ---------------- // Initialize and read in the ngram model Ngram* bldLM(int order, const char* filename) { ... } ... // Delete the ngram model void deleteLM(Ngram* ngram) { delete srilm_vocab; delete ngram; } ... // Get the ngram probability of the given string, given n-gram order 'order' and string length // 'length'. float getSeqProb(Ngram* ngram, const char* ngramstr, unsigned order, unsigned length) { ...} ----------------------------- Next, the Haskell FFI specs and code that marshals data between Haskell and C. ---------------- LM.hs ---------------------- {-# INCLUDE "srilm.h" #-} {-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-} ... module decl's, imports, etc. {- | A dummy placeholder for SRILM n-gram model thingies. -} data Ngram data NGModel = NGModel {ng :: !(ForeignPtr Ngram)} foreign import ccall "srilm.h bldLM" c_blm :: CInt -> CString -> Ptr Ngram foreign import ccall "srilm.h deleteLM" c_dlm :: FunPtr ((Ptr Ngram) -> IO ()) foreign import ccall "srilm.h getSeqProb" c_ngramProb :: Ptr Ngram -> CString -> CUInt -> CUInt -> CFloat {- | Given an n-gram model, an Int representing the n-gram order and a list of strings (word sequence), compute the n-gram probability of the sequence. -} scoreSequence :: NGModel -> Int -> [String] -> Float scoreSequence ngram order seq = unsafePerformIO $ do stringSeq <- newCString (unwords seq) let sc = c_ngramProb (unsafeForeignPtrToPtr $ ng ngram) stringSeq (fromIntegral order) (fromIntegral $ length seq) return (realToFrac sc) ... buildLM :: Int -> String -> NGModel buildLM order fname = NGModel $ unsafePerformIO $ do cFName <- newCString fname let ng = c_blm (fromIntegral order) cFName return $ unsafePerformIO $ newForeignPtr c_dlm ng -------------------------------------------- Now, I've defined a simple app that tries to use this: ------------------- Main.hs ------------------------- module Main where import SRILM.LM(scoreSequence, buildLM) main :: IO () main = do let lm = buildLM 5 "eng.kn.5g.lm" putStrLn $ show $ scoreSequence lm 5 ["the", "prime", "minister", "gave", "a", "speech", "."] ----------------------------------------------------------- But when I try to compile it (after having successfully compiled the C code with g++), I get: $ ghc --make Main.hs Linking Main ... LM.o: In function `r18k_info': (.text+0x122): undefined reference to `bldLM' LM.o: In function `r18m_info': (.text+0x14e): undefined reference to `deleteLM' LM.o: In function `r18o_info': (.text+0x28b): undefined reference to `getSeqProb' collect2: ld returned 1 exit status Any ideas? Note that I'm not confident that everything on the Haskell side is correct, but it seems that ghc can't find my C client of SRILM. As I said, I've compiled this code using g++, and it works when I interface with it through Python. Sorry for the long-windedness, but I figured I'd err on the side of TMI so that I don't have to keep posting more and more code snippets and error messages. Any help is greatly appreciated. (And I'd be happy to share my interface to SRILM to anyone who's interested, once I get it working -- and I get permission from Nitin Madnani to distribute a modified version of his code.) Thanks, Dennis -- View this message in context: http://old.nabble.com/FFI%2C-C-C%2B%2B-and-undefined-references-tp27139612p27139612.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From allbery at ece.cmu.edu Wed Jan 13 01:11:50 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Wed Jan 13 00:44:39 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <27139612.post@talk.nabble.com> References: <27139612.post@talk.nabble.com> Message-ID: <350E8375-EBE0-4893-A956-72AD45666AAB@ece.cmu.edu> On Jan 13, 2010, at 00:57 , DNM wrote: > ------------- srilm.c ---------------- > // Initialize and read in the ngram model > Ngram* bldLM(int order, const char* filename) { ... } > ... > // Delete the ngram model > void deleteLM(Ngram* ngram) { > delete srilm_vocab; > delete ngram; > } > ... > // Get the ngram probability of the given string, given n-gram order > 'order' > and string length > // 'length'. > float getSeqProb(Ngram* ngram, const char* ngramstr, unsigned order, > unsigned length) { ...} > ----------------------------- I think you need to `#include "srilm.h"' in the above, so C++ knows to export the functions with names callable from outside of C++. When you define a function in C++, the actual function symbol defined contains parameter type information unless previously declared in an extern "C" declaration.) While you've named the file with a .c extension, you have used C++-specific content (// comments, "delete" keyword) so I expect the file was compiled in C++ mode; otherwise it should have produced a syntax error from "delete" ("//" comments are a common enough extension that by themselves they probably work in much C code) and as a result the function symbols are mangled. If you add the #include, you bring the extern "C" declarations in scope, and C++ should produce non-mangled function definitions, which should be callable from Haskell. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/35cef4ef/PGP.bin From simon at joyful.com Wed Jan 13 02:08:22 2010 From: simon at joyful.com (Simon Michael) Date: Wed Jan 13 01:41:50 2010 Subject: [Haskell-cafe] Re: Design question, HTML for GUIs? In-Reply-To: <4B4A1EBD.1080605@web.de> References: <4B4A1EBD.1080605@web.de> Message-ID: hledger does this, using happstack (or in theory, any hack back end). http://joyful.com/repos/hledger/Commands/Web.hs might give some ideas. From blancolioni at gmail.com Wed Jan 13 03:43:21 2010 From: blancolioni at gmail.com (Fraser Wilson) Date: Wed Jan 13 03:15:57 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <201001122326.31495.daniel.is.fischer@web.de> References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> Message-ID: On Tue, Jan 12, 2010 at 11:26 PM, Daniel Fischer wrote: > Okay, 'as' is easy. But can you find a situation where 'qualified' or > 'hiding' would be natural choices for an identifier? I'd love to see those > in some code :) > module LordsOfMidnight.Character(Character) where data Character = C { name :: String, location :: (Int,Int), facing :: Direction, hour :: Int, energy :: Int, fear :: Int, riders :: Int, soldiers :: Int, hiding :: Bool } -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/9992c6fb/attachment.html From pseudo.meta at me.com Wed Jan 13 03:49:40 2010 From: pseudo.meta at me.com (Martin Coxall) Date: Wed Jan 13 03:22:46 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4CE8CE.9060202@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> Message-ID: On 12 Jan 2010, at 21:25, Andrew Coppin wrote: > OK people, it's random statistics time! > > Haskell '98 apparently features 25 reserved words. (Not counting "forall" and "mdo" and so on, which AFAIK are not in Haskell '98.) So how does that compare to other languages? > > C: 32 > C++: 62 > Borland Turbo Pascal: ~50 [without the OOP extensions added later] > Eiffel: 59 > VB: The source I checked listed in excess of 120 reserved words, but I'm dubious as to how "reserved" they really are. (Is CInt really reserved? I doubt it!) It also depends wildly on which of the bazillion VB dialects you mean. > Java: 50 > JavaScript: 36 > Smalltalk: 0 There are six singleton pseudo-variables that act as reserved words: true,false, nil, self, super and thisContext. > Lisp: AFAIK, there are no truly reserved words in Lisp, only predefined functions. (??) All Lisps have "special forms" which are evaluated uniquely and differently from function application and are therefore reserved words by another name. For example, Clojure has def, if, do, let, var, quote, fn, loop, recur, throw, try, monitor-enter, monitor-exit, dot, new and set!. > Python: 31 > Ruby: 38 > Tcl: Same analysis as for Lisp I believe. COBOL: Over 400 (!) > > As you can see, this conclusively proves... something. Generally speaking, the most widely used languages seem to be near the upper end of the range. I don't think it really tells you that much. Possibly that a little superficial complexity through syntactic sugar can make your language a lot more human-friendly, but that it's possible to go too far and end up like C++. Martin From pseudo.meta at me.com Wed Jan 13 03:51:24 2010 From: pseudo.meta at me.com (Martin Coxall) Date: Wed Jan 13 03:24:00 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4CF62E.5090206@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> <4B4CF62E.5090206@btinternet.com> Message-ID: On 12 Jan 2010, at 22:22, Andrew Coppin wrote: > Niklas Broberg wrote: >>> Haskell '98 apparently features 25 reserved words. (Not counting "forall" >>> and "mdo" and so on, which AFAIK are not in Haskell '98.) >>> >> >> 21 actually. case, class, data, default, deriving, do, else, if, >> import, in, infix, infixl, infixr, instance, let, module, newtype, of, >> then, type, where. There's also three special words that can still be >> used as identifiers, so aren't reserved: as, qualified, hiding. >> > > OK. Well the list I saw was for Haskell plus extensions, and I visually filtered out the inapplicable stuff. Apparently I missed something. > > Also, the number varies depending on whether you consider "reversed words" or "keywords", Aye, there's a subtle distinction between keywords and reserved words, but I think for the purposes of this discussion, they're the same thing. Martin From marco-oweber at gmx.de Wed Jan 13 03:54:14 2010 From: marco-oweber at gmx.de (Marc Weber) Date: Wed Jan 13 03:26:51 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4CE8CE.9060202@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> Message-ID: <1263372640-sup-6089@nixos> > As you can see, this conclusively proves... something. What about brainfuck? 8 different signs are used. -> http://de.wikipedia.org/wiki/Brainfuck#cite_note-0 The first link points to a page saying there is an interpreter 98 bytes in size.. What does this prove? :-) Marc Weber From apfelmus at quantentunnel.de Wed Jan 13 04:43:42 2010 From: apfelmus at quantentunnel.de (Heinrich Apfelmus) Date: Wed Jan 13 04:16:46 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: <201001121400.25492.daniel.is.fischer@web.de> References: <201001090452.48889.daniel.is.fischer@web.de> <201001121400.25492.daniel.is.fischer@web.de> Message-ID: Daniel Fischer wrote: > Heinrich Apfelmus wrote: >> >> It is exactly because these troubles that I'm advocating the original >> VIP data structure that buries the dorks (that name is awesome :D) deep >> inside the structure. :) In fact, your transformation that fixes the space leaks pretty much emulates the behavior of the old data People a = VIP a (People a) | Dorks [a] structure. This becomes apparent if we put the last two arguments of spMerge back into a pair: mergeSP (P a b) ~(P c d) = let P bc m = spMerge b (P c d) in P (a ++ bc) m where spMerge b (P [] d) = P [] (merge b d) spMerge xs@(x:xt) cd@(P (y:yt) d) = case compare x y of LT -> celebrate x (spMerge xt cd ) EQ -> celebrate x (spMerge xt (P yt d)) GT -> celebrate y (spMerge xs (P yt d)) In particular, forcing dorks (mergeSP ...) also forces the complete VIP list. I wonder whether it's really the liveness of pair in mergeSP (a,b) pair = let sm = spMerge b (fst pair) in (a ++ fst sm, merge (snd sm) (snd pair)) that is responsible for the space leak, for chances are that Sparud's technique applies and pair is properly disposed of. Rather, it could be that we need the stronger property that forcing the second component will evaluate the first to NF. >> In any case, it appears to me that the lazy pattern match in mergeSP >> is actually unnecessary! This is because mergeSP returns a pair >> constructor immediately, so infinite nesting works even when the second >> argument is demanded. [...] > > No, <>. For the reason you stated below. > In > > tfold f (a:b:c:xs) = (a `f` (b `f` c)) `f` smartfold f xs > > , it must compute smartfold f xs too early to match it against P c d. The > compiler can't see that smartfold mergeSP always returns a P [well, it > might return _|_, mightn't it?]. Oops, silly me! Mea culpa, of course mergeSP a (mergeSP b (mergeSP c ..))) or any infinite nesting is not going to work with a strict pattern. >_> <_< Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com From lauri.pesonen at iki.fi Wed Jan 13 04:47:09 2010 From: lauri.pesonen at iki.fi (Lauri Pesonen) Date: Wed Jan 13 04:20:05 2010 Subject: [Haskell-cafe] QuickCheck: test passes in GHCi, fails when compiled Message-ID: I provided a Java solution to a problem of returning the first digit of an integer on StackOverflow and someone wondered if there were any floating point point problems with the solution, so I though I'd implement the algorithm in Haskell and run QuickCheck on it. Everything works fine on GHCi, but if I compile the code and run the test, it fails with -1000, 1000, -1000000. Any ideas why? In any case it seems that the commenter was right and there are some subtle problems with my solution. I'd just like to know more details... import Data.Char import Test.QuickCheck -- my solution getFirstDigit :: Int -> Int getFirstDigit 0 = 0 getFirstDigit x = let x' = abs x digits = (floor $ logBase 10 $ fromIntegral x') in x' `div` (floor $ 10 ** (fromIntegral digits)) -- two reference implementation that agree with each other getFirstDigitRef1 :: Int -> Int getFirstDigitRef1 x = digitToInt $ head $ show $ abs x getFirstDigitRef2 :: Int -> Int getFirstDigitRef2 x | x < 0 = getFirstDigitRef2 (-x) | x < 10 = x | otherwise = getFirstDigitRef2 $ x `div` 10 myTest x = getFirstDigit x == getFirstDigitRef1 x --myTest x = getFirstDigitRef2 x == getFirstDigitRef1 x myCheck n = check (defaultConfig { configMaxTest = n }) myTest main = myCheck 1000000000 -- ! Lauri From ketil at malde.org Wed Jan 13 04:50:46 2010 From: ketil at malde.org (Ketil Malde) Date: Wed Jan 13 04:23:20 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <1263339354.4862.122.camel@dell.linuxdev.us.dell.com> (sylvain's message of "Wed, 13 Jan 2010 00:35:54 +0100") References: <4B4CE8CE.9060202@btinternet.com> <1263339354.4862.122.camel@dell.linuxdev.us.dell.com> Message-ID: <87zl4inxjd.fsf@malde.org> sylvain writes: > Let me order your list: > Smalltalk: 0 > Lisp: 0 > Tcl: 0 If you count reserved tokens, I guess Lisp reserves parentheses and whitespace? > Haskell: 21 * > Python: 31 > C: 32 * > JavaScript: 36 > Ruby: 38 > --- > Borland Turbo Pascal: ~50 > Java: 53 > Eiffel: 59 > C++: 62 > Interestingly enough, interpreted languages tend to need less keywords, > which support my observation above. I can't help but notice that the top three are untyped (all right, "dynamically typed") languages. Static typing seems to require at least a few reserved words (does it make sense to redefine 'data' or 'type' in Haskell?) > But if you really wanted to compare apples to apples you would, for > instance, add GHC pragmas and "magic" things like `par` to the mix. I > wonder if the picture would change much? Looking for a minimal subset that everything else can be implemented in terms of? Still, having 'par' as a user redefinable token lets you replace it with your own implementation (par = seq, for instance :-). So I think there's a benefit, even if it is normally implemented using magic. -k -- If I haven't seen further, it is by standing in the footprints of giants From bugfact at gmail.com Wed Jan 13 04:51:37 2010 From: bugfact at gmail.com (Peter Verswyvelen) Date: Wed Jan 13 04:24:20 2010 Subject: [Haskell-cafe] How to fulfill the "code-reuse" destiny of OOP? In-Reply-To: <87aaz7ovlt.fsf@gregorycollins.net> References: <3bd412d40910291854w67677d4esc0d47763c6a6fd8a@mail.gmail.com> <4AEB38BE.5010100@btinternet.com> <3bd412d40910310503p3b45d004ia69f873114579f2a@mail.gmail.com> <8b70a98a0910310521s646593a3i2558aca5d4088a27@mail.gmail.com> <87aaz7ovlt.fsf@gregorycollins.net> Message-ID: On Sun, Nov 1, 2009 at 2:57 AM, Gregory Collins wrote: > Doing OO-style programming in Haskell is difficult and unnatural, it's > true (although technically speaking it is possible). That said, nobody's > yet to present a convincing argument to me why Java gets a free pass for > lacking closures and typeclasses. > I might be wrong, but doesn't Java's concepts of inner classes and interfaces together with adapter classes can be used to replace closures and typeclasses in a way? An inner class allows you to implicitly capture the parent object ("environment"), just like a closure does in a sense. Interfaces group together methods, like type classes do. Although I'm actually a C# fanboy for doing "industrial" programming, I think the Java designers did an excellent job, finding a good balance in language features, ease of use and readability, and although C# does offer closures and many more FP constructs, I really miss the above Java constructs. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/4c851cfa/attachment.html From pseudo.meta at me.com Wed Jan 13 04:56:04 2010 From: pseudo.meta at me.com (Martin Coxall) Date: Wed Jan 13 04:28:43 2010 Subject: [Haskell-cafe] How to fulfill the "code-reuse" destiny of OOP? In-Reply-To: References: <3bd412d40910291854w67677d4esc0d47763c6a6fd8a@mail.gmail.com> <4AEB38BE.5010100@btinternet.com> <3bd412d40910310503p3b45d004ia69f873114579f2a@mail.gmail.com> <8b70a98a0910310521s646593a3i2558aca5d4088a27@mail.gmail.com> <87aaz7ovlt.fsf@gregorycollins.net> Message-ID: <1202CA08-B5E7-4519-8975-6FD53C662C23@me.com> On 13 Jan 2010, at 09:51, Peter Verswyvelen wrote: > On Sun, Nov 1, 2009 at 2:57 AM, Gregory Collins wrote: > Doing OO-style programming in Haskell is difficult and unnatural, it's > true (although technically speaking it is possible). That said, nobody's > yet to present a convincing argument to me why Java gets a free pass for > lacking closures and typeclasses. > > I might be wrong, but doesn't Java's concepts of inner classes and interfaces together with adapter classes can be used to replace closures and typeclasses in a way? Inner classes are not a semantic replacement for closures, even if you discount horrific syntax. Inner classes do not close over their lexical environment. Martin -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/2bd8300c/attachment.html From bugfact at gmail.com Wed Jan 13 04:57:16 2010 From: bugfact at gmail.com (Peter Verswyvelen) Date: Wed Jan 13 04:29:51 2010 Subject: [Haskell-cafe] Type Inference for Overloading without Restrictions Message-ID: A while ago, someone provided me a link to the paper "Type Inference for Overloading without Restrictions" http://www.dcc.ufmg.br/~camarao/ct-flops99.ps.gz Although I don't understand everything in this paper, I wander what people's opinions are about this regarding a?future?Haskell language revision or extension? Would a feature like this be preferable over typeclasses? Would it be practical to implement? Are people working on this? Thanks, Peter Verswyvelen From ganesh.sittampalam at credit-suisse.com Wed Jan 13 05:00:32 2010 From: ganesh.sittampalam at credit-suisse.com (Sittampalam, Ganesh) Date: Wed Jan 13 04:34:23 2010 Subject: [Haskell-cafe] How to fulfill the "code-reuse" destiny of OOP? In-Reply-To: References: <3bd412d40910291854w67677d4esc0d47763c6a6fd8a@mail.gmail.com><4AEB38BE.5010100@btinternet.com><3bd412d40910310503p3b45d004ia69f873114579f2a@mail.gmail.com><8b70a98a0910310521s646593a3i2558aca5d4088a27@mail.gmail.com><87aaz7ovlt.fsf@gregorycollins.net> Message-ID: <16442B752A06A74AB4D9F9A5FF076E4B08816D0B@ELON17P32001A.csfb.cs-group.com> The problem with interfaces as a replacement for type classes is that they only provide dispatch based on the specific type of the first argument (i.e. the receiver). Type classes allow you to dispatch based on return type, and on the instantiations of generic parameters. Neither of these things is reasonably possible with interfaces. For example you can't directly implement the Read type class with interfaces. Neither can you implement a function of type [a] -> ... where the dispatch is based on the instantiation of a - even if you can add an interface to the [] generic type, you might not have a concrete object of type a to dispatch from if the empty list is passed as an argument. ________________________________ From: haskell-cafe-bounces@haskell.org [mailto:haskell-cafe-bounces@haskell.org] On Behalf Of Peter Verswyvelen Sent: 13 January 2010 09:52 To: Gregory Collins Cc: haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] How to fulfill the "code-reuse" destiny of OOP? On Sun, Nov 1, 2009 at 2:57 AM, Gregory Collins wrote: Doing OO-style programming in Haskell is difficult and unnatural, it's true (although technically speaking it is possible). That said, nobody's yet to present a convincing argument to me why Java gets a free pass for lacking closures and typeclasses. I might be wrong, but doesn't Java's concepts of inner classes and interfaces together with adapter classes can be used to replace closures and typeclasses in a way? An inner class allows you to implicitly capture the parent object ("environment"), just like a closure does in a sense. Interfaces group together methods, like type classes do. Although I'm actually a C# fanboy for doing "industrial" programming, I think the Java designers did an excellent job, finding a good balance in language features, ease of use and readability, and although C# does offer closures and many more FP constructs, I really miss the above Java constructs. =============================================================================== Please access the attached hyperlink for an important electronic communications disclaimer: http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html =============================================================================== -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/c09c8fe4/attachment.html From lauri.pesonen at iki.fi Wed Jan 13 05:07:29 2010 From: lauri.pesonen at iki.fi (Lauri Pesonen) Date: Wed Jan 13 04:40:25 2010 Subject: [Haskell-cafe] Re: QuickCheck: test passes in GHCi, fails when compiled In-Reply-To: References: Message-ID: 2010/1/13 Lauri Pesonen : > I provided a Java solution to a problem of returning the first digit > of an integer on StackOverflow and someone wondered if there were any > floating point point problems with the solution, so I though I'd > implement the algorithm in Haskell and run QuickCheck on it. > Everything works fine on GHCi, but if I compile the code and run the > test, it fails with -1000, 1000, -1000000. Any ideas why? > > In any case it seems that the commenter was right and there are some > subtle problems with my solution. I'd just like to know more > details... Ok, I've figured out why the compiled version fails the check: main = putStrLn $ show $ logBase 10 1000 when compiled returns 2.9999999999999996 on my system (WinXp 32-bit) which then gets truncated to 2. So it seems that there's a precision difference between the compiled and the interpreted code. 'logBase 10 999' on the other hand produces exactly the same value in both cases. I expect this to be a known issue with floats. Sorry for the noise. -- ! Lauri From sebf at informatik.uni-kiel.de Wed Jan 13 05:14:59 2010 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Wed Jan 13 04:47:36 2010 Subject: [Haskell-cafe] How to fulfill the "code-reuse" destiny of OOP? In-Reply-To: <16442B752A06A74AB4D9F9A5FF076E4B08816D0B@ELON17P32001A.csfb.cs-group.com> References: <3bd412d40910291854w67677d4esc0d47763c6a6fd8a@mail.gmail.com><4AEB38BE.5010100@btinternet.com><3bd412d40910310503p3b45d004ia69f873114579f2a@mail.gmail.com><8b70a98a0910310521s646593a3i2558aca5d4088a27@mail.gmail.com><87aaz7ovlt.fsf@gregorycollins.net> <16442B752A06A74AB4D9F9A5FF076E4B08816D0B@ELON17P32001A.csfb.cs-group.com> Message-ID: <1C205C71-3F56-46E2-845E-61CDF264BD6A@informatik.uni-kiel.de> On Jan 13, 2010, at 11:00 AM, Sittampalam, Ganesh wrote: > Type classes allow you to dispatch based on return type, and on the > instantiations of generic parameters. Neither of these things is > reasonably possible with interfaces. There is recent work that generalises the capabilities of interfaces in Java: http://www.informatik.uni-freiburg.de/~wehr/publications/WehrLammelThiemann2007.html http://www.informatik.uni-freiburg.de/~wehr/publications/WehrThiemann2009.html http://www.informatik.uni-freiburg.de/~wehr/publications/Wehr2009.html Seeing type-class features in Java disguise highlights the differences between the two concepts that you mention. Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/9e181b8d/attachment.html From allbery at ece.cmu.edu Wed Jan 13 05:16:55 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Wed Jan 13 04:49:43 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> Message-ID: On Jan 13, 2010, at 03:49 , Martin Coxall wrote: > COBOL: Over 400 (!) If we're going to go that far, FORTRAN and PL/1 have none. FORTRAN is somewhat infamous for this: "DO 10 I = 1, 400" is a loop start, "DO 10 I = 1. 400" (note typo, "." for ",") parses as the assignment "DO10I = 1.400". (This is often cited as the cause of the failure of Mariner 1, but that's an urban legend. See http://catless.ncl.ac.uk/Risks/9.54.html#subj1.1 for discussion, including the possible origin of this UL.) -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/1fe4bca5/PGP.bin From bugfact at gmail.com Wed Jan 13 05:21:02 2010 From: bugfact at gmail.com (Peter Verswyvelen) Date: Wed Jan 13 04:53:36 2010 Subject: [Haskell-cafe] How to fulfill the "code-reuse" destiny of OOP? In-Reply-To: <16442B752A06A74AB4D9F9A5FF076E4B08816D0B@ELON17P32001A.csfb.cs-group.com> References: <3bd412d40910291854w67677d4esc0d47763c6a6fd8a@mail.gmail.com> <4AEB38BE.5010100@btinternet.com> <3bd412d40910310503p3b45d004ia69f873114579f2a@mail.gmail.com> <8b70a98a0910310521s646593a3i2558aca5d4088a27@mail.gmail.com> <87aaz7ovlt.fsf@gregorycollins.net> <16442B752A06A74AB4D9F9A5FF076E4B08816D0B@ELON17P32001A.csfb.cs-group.com> Message-ID: Yes that is true, but often in Haskell I had to use type annotations when the dispatch is based on the return type, so it also has some tradeoffs. Don't get me wrong, I see the advantages of Haskell's type classes and closures, and I love these. But in Java - if you stay close to OO, and don't try to do FP - you can accomplish a lot, albeit with a lot of boilerplate. IMO, it's not because you have less lines of code in Haskell, that the code becomes more readable per se. I'm not a Java expert, but I have no troubles at all reading Java code, even though that code is typically twice as long as similar C# code, and maybe ten times as long as Haskell or ML code (at least if the side effects are kept local enough, which is good practice in OO anyway). But after many years of playing with Haskell, I still fail to read and understand a lot of Haskell code (maybe because it is written by people with a much higher IQ than mine I guess) On Wed, Jan 13, 2010 at 11:00 AM, Sittampalam, Ganesh wrote: > The problem with interfaces as a replacement for type classes is that they > only provide dispatch based on the specific type of the first argument (i.e. > the receiver). > > Type classes allow you to dispatch based on?return type, and on the > instantiations of generic parameters. Neither of these things is reasonably > possible with interfaces. > > For example you can't directly implement the Read type class with > interfaces. Neither can you implement?a function of type [a] -> ... where > the dispatch is based on the instantiation of a - even if you can add an > interface to the [] generic type, you might not have a concrete object of > type a to dispatch from if the empty list is passed as an argument. > > ________________________________ > From: haskell-cafe-bounces@haskell.org > [mailto:haskell-cafe-bounces@haskell.org] On Behalf Of Peter Verswyvelen > Sent: 13 January 2010 09:52 > To: Gregory Collins > Cc: haskell-cafe@haskell.org > Subject: Re: [Haskell-cafe] How to fulfill the "code-reuse" destiny of OOP? > > On Sun, Nov 1, 2009 at 2:57 AM, Gregory Collins > wrote: >> >> Doing OO-style programming in Haskell is difficult and unnatural, it's >> true (although technically speaking it is possible). That said, nobody's >> yet to present a convincing argument to me why Java gets a free pass for >> lacking closures and typeclasses. > > I might be wrong, but doesn't Java's concepts of inner classes and > interfaces together with adapter classes can be used to replace closures and > typeclasses in a way? > An inner class allows you to implicitly capture the parent object > ("environment"), just like a closure does in a sense. > Interfaces group together methods, like type classes do. > Although I'm actually a C# fanboy for doing "industrial" programming, I > think the Java designers did an excellent job, finding a good balance in > language features, ease of use and readability, and although C# does offer > closures and many more FP constructs, I really miss the above Java > constructs. > > > ============================================================================== > Please access the attached hyperlink for an important electronic > communications disclaimer: > http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html > ============================================================================== > From allbery at ece.cmu.edu Wed Jan 13 05:21:43 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Wed Jan 13 04:54:19 2010 Subject: [Haskell-cafe] Re: QuickCheck: test passes in GHCi, fails when compiled In-Reply-To: References: Message-ID: On Jan 13, 2010, at 05:07 , Lauri Pesonen wrote: > I expect this to be a known issue with floats. Sorry for the noise. Yep. There's a faction that wants Float and Double to not be in the Eq typeclass, because floating point calculations can never reliably be compared for equality. (There are some "infinite precision float" packages out there, but transcendentals will still get you in trouble even if repeating decimals don't.) -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/ce905fe8/PGP.bin From malcolm.wallace at cs.york.ac.uk Wed Jan 13 05:22:15 2010 From: malcolm.wallace at cs.york.ac.uk (Malcolm Wallace) Date: Wed Jan 13 04:55:23 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <27139612.post@talk.nabble.com> References: <27139612.post@talk.nabble.com> Message-ID: <61E9624C-CB47-469C-BC29-2FA4A670D845@cs.york.ac.uk> > But when I try to compile it (after having successfully compiled the > C code > with g++), I get: > > $ ghc --make Main.hs You are not telling ghc to link against the C/C++ code, e.g. ghc --make Main.hs srilm.o Regards, Malcolm From ketil at malde.org Wed Jan 13 05:39:13 2010 From: ketil at malde.org (Ketil Malde) Date: Wed Jan 13 05:11:44 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: (Fraser Wilson's message of "Wed, 13 Jan 2010 09:43:21 +0100") References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> Message-ID: <87r5punvam.fsf@malde.org> Fraser Wilson writes: > module LordsOfMidnight.Character(Character) where > > data Character = C { name :: String, > location :: (Int,Int), > facing :: Direction, > hour :: Int, > energy :: Int, > fear :: Int, > riders :: Int, > soldiers :: Int, > hiding :: Bool > } Daniel Fisher thinks again... (With apologies for the rather obscure reference.) -k -- If I haven't seen further, it is by standing in the footprints of giants From ketil at malde.org Wed Jan 13 05:45:28 2010 From: ketil at malde.org (Ketil Malde) Date: Wed Jan 13 05:17:59 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: (Brandon S. Allbery's message of "Wed, 13 Jan 2010 05:16:55 -0500") References: <4B4CE8CE.9060202@btinternet.com> Message-ID: <87my0inv07.fsf@malde.org> "Brandon S. Allbery KF8NH" writes: > If we're going to go that far, FORTRAN and PL/1 have none. FORTRAN is > somewhat infamous for this: There's also the option (perhaps this was PL/1?) of writing constructs like: IF THEN THEN IF ELSE THEN etc. Having few reserved words isn't necessarily a benefit. :-) -k -- If I haven't seen further, it is by standing in the footprints of giants From allbery at ece.cmu.edu Wed Jan 13 05:50:44 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Wed Jan 13 05:23:31 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <87my0inv07.fsf@malde.org> References: <4B4CE8CE.9060202@btinternet.com> <87my0inv07.fsf@malde.org> Message-ID: On Jan 13, 2010, at 05:45 , Ketil Malde wrote: > "Brandon S. Allbery KF8NH" writes: >> If we're going to go that far, FORTRAN and PL/1 have none. FORTRAN >> is >> somewhat infamous for this: > > There's also the option (perhaps this was PL/1?) of writing constructs > like: IF THEN THEN IF ELSE THEN etc. Having few reserved words isn't > necessarily a benefit. :-) That'd be PL/I, and a prime example of why languages use keywords these days (as if FORTRAN weren't enough). :) -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/f45805d2/PGP.bin From dav.vire+haskell at gmail.com Wed Jan 13 05:54:37 2010 From: dav.vire+haskell at gmail.com (David Virebayre) Date: Wed Jan 13 05:27:12 2010 Subject: [Haskell-cafe] wildcards for type variables? In-Reply-To: <2518b95d1001121529l60701d44y13ecf6614c82d1a6@mail.gmail.com> References: <2518b95d1001121529l60701d44y13ecf6614c82d1a6@mail.gmail.com> Message-ID: <4c88418c1001130254g58e11e37g1a4ec6cd1bad63e2@mail.gmail.com> On Wed, Jan 13, 2010 at 12:29 AM, Evan Laforge wrote: > Occasionally I have a function with an unused argument, whose type I > don't want to restrict. ?Thus: > > f :: _unused -> A -> B > f _ a = b I probably misunderstood the problem, why not f:: a -> A -> B David From allbery at ece.cmu.edu Wed Jan 13 05:59:09 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Wed Jan 13 05:31:46 2010 Subject: [Haskell-cafe] wildcards for type variables? In-Reply-To: <4c88418c1001130254g58e11e37g1a4ec6cd1bad63e2@mail.gmail.com> References: <2518b95d1001121529l60701d44y13ecf6614c82d1a6@mail.gmail.com> <4c88418c1001130254g58e11e37g1a4ec6cd1bad63e2@mail.gmail.com> Message-ID: <417DCDA9-6971-4F0A-AA5A-45C10DC5FCC3@ece.cmu.edu> On Jan 13, 2010, at 05:54 , David Virebayre wrote: > On Wed, Jan 13, 2010 at 12:29 AM, Evan Laforge > wrote: >> Occasionally I have a function with an unused argument, whose type I >> don't want to restrict. Thus: >> >> f :: _unused -> A -> B >> f _ a = b > > I probably misunderstood the problem, why not f:: a -> A -> B He's looking for the self-documentation aspect of "this argument is completely irrelevant". Neither rolling a random unused type variable nor "forall"ing it (my first idea) really accomplishes that. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/c27f9bec/PGP.bin From bulat.ziganshin at gmail.com Wed Jan 13 06:33:35 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Wed Jan 13 06:06:14 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <27139612.post@talk.nabble.com> References: <27139612.post@talk.nabble.com> Message-ID: <945952185.20100113143335@gmail.com> Hello DNM, Wednesday, January 13, 2010, 8:57:45 AM, you wrote: > Note: I'm relatively new to Haskell, and my knowledge of C and C++ is > basically pretty > minimal -- I can read, modify and compile C/C++ programs (usually). 1. you use too much unsafePerformIO. since you need newCString, i suggest you to declare C functions as returning IO a so your code will be unsafePerformIO$ do withCString str $ \c_str -> do c_function c_str ... 2. if your function returns Ptr a - then hold in haskell types this Ptr a. no need to convert it back and forth to ForeignPtr 3. why c_dlm is FunPtr in your definition? it should be foreign import ccall "srilm.h deleteLM" c_dlm :: Ptr Ngram -> IO () 4. i don't looked in your code but if C functions defines *modifiable* datastructure - you should use it at Haskell side via imperatiove functions, i.e. those with return type IO a. using unsafePerformIO in this case will lead to Haskell compiler will consider this datatype as permanent and reorder operations on the will so, > data NGModel = NGModel {ng :: !(Ptr Ngram)} > foreign import ccall "srilm.h bldLM" > c_blm :: CInt -> CString -> IO (Ptr Ngram) > foreign import ccall "srilm.h deleteLM" > c_dlm :: Ptr Ngram -> IO () > foreign import ccall "srilm.h getSeqProb" > c_ngramProb :: Ptr Ngram -> CString -> CUInt -> CUInt -> IO CFloat > scoreSequence :: NGModel -> Int -> [String] -> IO Float > scoreSequence ngram order seq = do > withCString (unwords seq) $ \stringSeq -> do > sc <- c_ngramProb (ng ngram) stringSeq (fromIntegral order) (fromIntegral $ length seq) > return (realToFrac sc) and so on -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From daniel.is.fischer at web.de Wed Jan 13 06:33:22 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Jan 13 06:07:38 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001121400.25492.daniel.is.fischer@web.de> Message-ID: <201001131233.23024.daniel.is.fischer@web.de> Am Mittwoch 13 Januar 2010 10:43:42 schrieb Heinrich Apfelmus: > I wonder whether it's really the liveness of ?pair ?in > > ? mergeSP (a,b) pair > ? ? ?= let sm = spMerge b (fst pair) > ? ? ? ?in (a ++ fst sm, merge (snd sm) (snd pair)) > > that is responsible for the space leak, for chances are that Sparud's > technique applies and ?pair ?is properly disposed of. Rather, it could > be that we need the stronger property that forcing the second component > will evaluate the first to NF. I think that is responsible. At least that's how I understand the core: mergeSP (a,b) ~(c,d) = (a ++ bc, merge b' d) where (bc, b') = spMerge b c spMerge ... ---------------------------------------------------------------------- OldMerge.$wmergeSP :: [GHC.Types.Int] -> [GHC.Types.Int] -> ([GHC.Types.Int], [GHC.Types.Int]) -> (# [GHC.Types.Int], [GHC.Types.Int] #) GblId [Arity 3 Str: DmdType LLL] OldMerge.$wmergeSP = \ (ww_sny :: [GHC.Types.Int]) (ww1_snz :: [GHC.Types.Int]) (w_snB :: ([GHC.Types.Int], [GHC.Types.Int])) -> let { ds_so7 [ALWAYS Just D(SS)] :: ([GHC.Types.Int], [GHC.Types.Int]) LclId [Str: DmdType] ds_so7 = case w_snB of _ { (c_adj, _) -> case OldMerge.$wspMerge ww1_snz c_adj of _ { (# ww3_snH, ww4_snI #) -> (ww3_snH, ww4_snI) } } } in (# GHC.Base.++ @ GHC.Types.Int ww_sny (case ds_so7 of _ { (bc_ajQ, _) -> bc_ajQ }), case ds_so7 of _ { (_, b'_ajS) -> case w_snB of _ { (_, d_adk) -> OldMerge.merge b'_ajS d_adk } -- Here, in the second component of the result, -- we reference the entire pair to get the dorks } #) OldMerge.mergeSP :: ([GHC.Types.Int], [GHC.Types.Int]) -> ([GHC.Types.Int], [GHC.Types.Int]) -> ([GHC.Types.Int], [GHC.Types.Int]) GblId [Arity 2 Worker OldMerge.$wmergeSP Str: DmdType U(LL)Lm] OldMerge.mergeSP = __inline_me (\ (w_snw :: ([GHC.Types.Int], [GHC.Types.Int])) (w1_snB :: ([GHC.Types.Int], [GHC.Types.Int])) -> case w_snw of _ { (ww_sny, ww1_snz) -> case OldMerge.$wmergeSP ww_sny ww1_snz w1_snB of _ { (# ww3_snN, ww4_snO #) -> (ww3_snN, ww4_snO) } }) ---------------------------------------------------------------------- vs. mergeSP (a,b) ~(c,d) = (a ++ bc, m) where (bc,m) = spMerge b c d spMerge ... ---------------------------------------------------------------------- NewMerge.$wmergeSP :: [GHC.Types.Int] -> [GHC.Types.Int] -> ([GHC.Types.Int], [GHC.Types.Int]) -> (# [GHC.Types.Int], [GHC.Types.Int] #) GblId [Arity 3 Str: DmdType LLL] NewMerge.$wmergeSP = \ (ww_snB :: [GHC.Types.Int]) (ww1_snC :: [GHC.Types.Int]) (w_snE :: ([GHC.Types.Int], [GHC.Types.Int])) -> let { ds_soa [ALWAYS Just D(SS)] :: ([GHC.Types.Int], [GHC.Types.Int]) LclId [Str: DmdType] ds_soa = case w_snE of _ { (c_adj, d_adk) -> -- There's no reference to the pair after this case NewMerge.$wspMerge ww1_snC c_adj d_adk of _ { (# ww3_snK, ww4_snL #) -> (ww3_snK, ww4_snL) } } } in (# GHC.Base.++ @ GHC.Types.Int ww_snB (case ds_soa of _ { (bc_ajT, _) -> bc_ajT }), case ds_soa of _ { (_, b'_ajV) -> b'_ajV } #) NewMerge.mergeSP :: ([GHC.Types.Int], [GHC.Types.Int]) -> ([GHC.Types.Int], [GHC.Types.Int]) -> ([GHC.Types.Int], [GHC.Types.Int]) GblId [Arity 2 Worker NewMerge.$wmergeSP Str: DmdType U(LL)Lm] NewMerge.mergeSP = __inline_me (\ (w_snz :: ([GHC.Types.Int], [GHC.Types.Int])) (w1_snE :: ([GHC.Types.Int], [GHC.Types.Int])) -> case w_snz of _ { (ww_snB, ww1_snC) -> case NewMerge.$wmergeSP ww_snB ww1_snC w1_snE of _ { (# ww3_snQ, ww4_snR #) -> (ww3_snQ, ww4_snR) } }) ---------------------------------------------------------------------- From aslatter at gmail.com Wed Jan 13 08:16:28 2010 From: aslatter at gmail.com (Antoine Latter) Date: Wed Jan 13 07:49:03 2010 Subject: [Haskell-cafe] wildcards for type variables? In-Reply-To: <417DCDA9-6971-4F0A-AA5A-45C10DC5FCC3@ece.cmu.edu> References: <2518b95d1001121529l60701d44y13ecf6614c82d1a6@mail.gmail.com> <4c88418c1001130254g58e11e37g1a4ec6cd1bad63e2@mail.gmail.com> <417DCDA9-6971-4F0A-AA5A-45C10DC5FCC3@ece.cmu.edu> Message-ID: <694519c51001130516i7cbb2535yc497efc3839db53c@mail.gmail.com> On Wed, Jan 13, 2010 at 4:59 AM, Brandon S. Allbery KF8NH wrote: > On Jan 13, 2010, at 05:54 , David Virebayre wrote: >> >> On Wed, Jan 13, 2010 at 12:29 AM, Evan Laforge wrote: >>> >>> Occasionally I have a function with an unused argument, whose type I >>> don't want to restrict. ?Thus: >>> >>> f :: _unused -> A -> B >>> f _ a = b >> >> I probably misunderstood the problem, why not f:: a -> A -> B > > > He's looking for the self-documentation aspect of "this argument is > completely irrelevant". ?Neither rolling a random unused type variable nor > "forall"ing it (my first idea) really accomplishes that. > Isn't that what we have here? a function of type (a -> A -> B) cannot use the first argument in any meaningful way. But once you start throwing in higher ranked types you might have to think a bit to come to that conclusion. Antoine From greg at gregorycollins.net Wed Jan 13 08:20:00 2010 From: greg at gregorycollins.net (Gregory Collins) Date: Wed Jan 13 07:52:35 2010 Subject: [Haskell-cafe] How to fulfill the "code-reuse" destiny of OOP? In-Reply-To: (Peter Verswyvelen's message of "Wed, 13 Jan 2010 10:51:37 +0100") References: <3bd412d40910291854w67677d4esc0d47763c6a6fd8a@mail.gmail.com> <4AEB38BE.5010100@btinternet.com> <3bd412d40910310503p3b45d004ia69f873114579f2a@mail.gmail.com> <8b70a98a0910310521s646593a3i2558aca5d4088a27@mail.gmail.com> <87aaz7ovlt.fsf@gregorycollins.net> Message-ID: <87bpgy87lr.fsf@gregorycollins.net> Peter Verswyvelen writes: > On Sun, Nov 1, 2009 at 2:57 AM, Gregory Collins wrote: > > Doing OO-style programming in Haskell is difficult and unnatural, > it's true (although technically speaking it is possible). That > said, nobody's yet to present a convincing argument to me why Java > gets a free pass for lacking closures and typeclasses. > > I might be wrong, but doesn't Java's concepts of inner classes and > interfaces together with adapter classes can be used to replace > closures and typeclasses in a way? Maybe, in the same sense that a lawnmower engine strapped to a skateboard is a replacement for a car: it takes you ten times as long to get to your destination and you're cold and wet when you get there. G -- Gregory Collins From sebf at informatik.uni-kiel.de Wed Jan 13 08:22:14 2010 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Wed Jan 13 07:54:49 2010 Subject: [Haskell-cafe] wildcards for type variables? In-Reply-To: <694519c51001130516i7cbb2535yc497efc3839db53c@mail.gmail.com> References: <2518b95d1001121529l60701d44y13ecf6614c82d1a6@mail.gmail.com> <4c88418c1001130254g58e11e37g1a4ec6cd1bad63e2@mail.gmail.com> <417DCDA9-6971-4F0A-AA5A-45C10DC5FCC3@ece.cmu.edu> <694519c51001130516i7cbb2535yc497efc3839db53c@mail.gmail.com> Message-ID: <43BCD272-1EB5-42AE-952F-66DF5268FAAD@informatik.uni-kiel.de> On Jan 13, 2010, at 2:16 PM, Antoine Latter wrote: >> He's looking for the self-documentation aspect of "this argument is >> completely irrelevant". Neither rolling a random unused type >> variable nor >> "forall"ing it (my first idea) really accomplishes that. >> > > Isn't that what we have here? a function of type (a -> A -> B) cannot > use the first argument in any meaningful way. I think, he wants to document that the type variable 'a' is not used in the *type*. Just like you can document that the second argument of 'const' is unused by using a wildcard. You can write const x _ = x instead of const x y = x and it would be nice to write 'const's type as a -> _ -> a rather than a -> b -> a Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From gue.schmidt at web.de Wed Jan 13 08:44:57 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Wed Jan 13 08:17:59 2010 Subject: [Haskell-cafe] what is *hack*? Message-ID: <4B4DCE59.2030402@web.de> Hi, References to a Hack. module came in the responses to my posts on HTML-GUIs. What is Hack then? G?nther From vanenkj at gmail.com Wed Jan 13 08:46:34 2010 From: vanenkj at gmail.com (John Van Enk) Date: Wed Jan 13 08:19:12 2010 Subject: [Haskell-cafe] what is *hack*? In-Reply-To: <4B4DCE59.2030402@web.de> References: <4B4DCE59.2030402@web.de> Message-ID: http://hackage.haskell.org/package/hack 2010/1/13 G?nther Schmidt > Hi, > > References to a Hack. module came in the responses to my posts on > HTML-GUIs. > > What is Hack then? > > > G?nther > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/e953da27/attachment-0001.html From gue.schmidt at web.de Wed Jan 13 08:50:26 2010 From: gue.schmidt at web.de (=?ISO-8859-1?Q?G=FCnther_Schmidt?=) Date: Wed Jan 13 08:23:02 2010 Subject: [Haskell-cafe] what is *hack*? In-Reply-To: References: <4B4DCE59.2030402@web.de> Message-ID: <4B4DCFA2.6050405@web.de> Hi John, thanks, I should have mentioned that I had found it on hackage, I just don't understand what it *is* or what it's supposed to be for. G?nther Am 13.01.10 14:46, schrieb John Van Enk: > http://hackage.haskell.org/package/hack > > 2010/1/13 G?nther Schmidt > > > Hi, > > References to a Hack. module came in the responses to my posts on > HTML-GUIs. > > What is Hack then? > > > G?nther > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/fa7d33d8/attachment.html From vanenkj at gmail.com Wed Jan 13 08:54:39 2010 From: vanenkj at gmail.com (John Van Enk) Date: Wed Jan 13 08:27:14 2010 Subject: [Haskell-cafe] what is *hack*? In-Reply-To: <4B4DCFA2.6050405@web.de> References: <4B4DCE59.2030402@web.de> <4B4DCFA2.6050405@web.de> Message-ID: This may help more: http://wiki.github.com/nfjinjing/hack The Hack project is based off of a project known as "Rack" for ruby. I'm fairly sure the documentation you can find on Rack will help you understand what Hack does. 2010/1/13 G?nther Schmidt > Hi John, > > thanks, I should have mentioned that I had found it on hackage, I just > don't understand what it *is* or what it's supposed to be for. > > G?nther > > > Am 13.01.10 14:46, schrieb John Van Enk: > > http://hackage.haskell.org/package/hack > > 2010/1/13 G?nther Schmidt > >> Hi, >> >> References to a Hack. module came in the responses to my posts on >> HTML-GUIs. >> >> What is Hack then? >> >> >> G?nther >> >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/16d32737/attachment.html From magnus at therning.org Wed Jan 13 09:24:31 2010 From: magnus at therning.org (Magnus Therning) Date: Wed Jan 13 08:57:06 2010 Subject: [Haskell-cafe] what is *hack*? In-Reply-To: References: <4B4DCE59.2030402@web.de> <4B4DCFA2.6050405@web.de> Message-ID: 2010/1/13 John Van Enk : > This may help more: http://wiki.github.com/nfjinjing/hack > > The Hack project is based off of a project known as "Rack" for ruby. I'm > fairly sure the documentation you can find on Rack will help you understand > what Hack does. Not knowing what Rack is myself I found this, and assume that's the Ruby project you refer to: http://rack.rubyforge.org/ /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe From gue.schmidt at web.de Wed Jan 13 09:31:53 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Wed Jan 13 09:04:52 2010 Subject: [Haskell-cafe] Xhtml? Message-ID: <4B4DD959.9050309@web.de> Hi, apologies upfront. As time presses I decided to post questions immediately as soon as I run into dead-ends. I just don't want to give the impression that I'm not willing to do my homework. I'm trying to find documentation on Xhtml, the site on hackage refers to http://www.cse.ogi.edu/~andy/html/intro.htm for an introduction to the library, the link is dead. I managed to locate Andy Gill's current homepage (http://www.cse.ogi.edu/~andy/html/intro.htm) but there is no mention of his html combinatory library. Does anyone else know where an introduction to this library can be retrieved from? G?nther From gue.schmidt at web.de Wed Jan 13 09:42:42 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Wed Jan 13 09:15:41 2010 Subject: [Haskell-cafe] Re: Xhtml? In-Reply-To: <4B4DD959.9050309@web.de> References: <4B4DD959.9050309@web.de> Message-ID: <4B4DDBE2.6070501@web.de> Am 13.01.10 15:31, schrieb G?nther Schmidt: > Hi, > > apologies upfront. As time presses I decided to post questions > immediately as soon as I run into dead-ends. > > I just don't want to give the impression that I'm not willing to do my > homework. > > I'm trying to find documentation on Xhtml, the site on hackage refers to > http://www.cse.ogi.edu/~andy/html/intro.htm for an introduction to the > library, the link is dead. > > I managed to locate Andy Gill's current homepage > (http://www.cse.ogi.edu/~andy/html/intro.htm) but there is no mention of > his html combinatory library. > sry, I meant this site here: http://www.ittc.ku.edu/~andygill/index.php > Does anyone else know where an introduction to this library can be > retrieved from? > > G?nther From michael at snoyman.com Wed Jan 13 09:46:12 2010 From: michael at snoyman.com (Michael Snoyman) Date: Wed Jan 13 09:18:48 2010 Subject: [Haskell-cafe] Web application interface Message-ID: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> Hi, I recently read (again) the wiki page on a web application interface[1] for Haskell. It seems like this basically works out to Hack[2], but using an enumerator instead of lazy bytestring in the response type. Is anyone working on implementing this? If not, I would like to create the package, though I wouldn't mind some community input on some design decisions: * Hack has been fairly well-tested in the past year and I think it provides the features that people want. Therefore, I would want to model the Environment variable for WAI from Hack. I *could* just import Hack in WAI and use the exact same Environment data type. Thoughts? * If using a different data type for Environment, should I replace the String parts with ByteStrings? On the one hand, ByteStrings are the "correct" data type since the HTTP protocol does not specify a character encoding; on the other hand, Strings are easier to deal with. * It's simple to write a function to convert between a lazy bytestring and an enumerator, meaning it would be very easy to write conversion functions between Hack and WAI applications. This would make it simpler for people to use either backend. If someone else is already working on WAI, please let me know, I don't want to have duplicate implementations. The idea here is to consolidate, not split the community. I have a few Hack handlers (simpleserver, cgi, fastcgi) that I would happily convert to WAI handlers as well. Michael [1] http://www.haskell.org/haskellwiki/WebApplicationInterface [2] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hack -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/7309a790/attachment.html From michael at snoyman.com Wed Jan 13 09:48:25 2010 From: michael at snoyman.com (Michael Snoyman) Date: Wed Jan 13 09:21:00 2010 Subject: [Haskell-cafe] what is *hack*? In-Reply-To: <4B4DCFA2.6050405@web.de> References: <4B4DCE59.2030402@web.de> <4B4DCFA2.6050405@web.de> Message-ID: <29bf512f1001130648p6b2eda40y14033470116d4203@mail.gmail.com> G?nther, Hack is a layer between a web application and a web server. It allows you to write a web application once and have it communicate with the server in different ways simply by swapping the handler. For example, I have applications that I test on my local system using hack-handler-simpleserver and then deploy onto an Apache server using either hack-handler-cgi or hack-handler-fastcgi. Michael 2010/1/13 G?nther Schmidt > Hi John, > > thanks, I should have mentioned that I had found it on hackage, I just > don't understand what it *is* or what it's supposed to be for. > > G?nther > > > Am 13.01.10 14:46, schrieb John Van Enk: > > http://hackage.haskell.org/package/hack > > 2010/1/13 G?nther Schmidt > >> Hi, >> >> References to a Hack. module came in the responses to my posts on >> HTML-GUIs. >> >> What is Hack then? >> >> >> G?nther >> >> >> _______________________________________________ >> 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 > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/da2b0eae/attachment.html From noteed at gmail.com Wed Jan 13 09:56:30 2010 From: noteed at gmail.com (minh thu) Date: Wed Jan 13 09:29:26 2010 Subject: [Haskell-cafe] Re: Xhtml? In-Reply-To: <4B4DDBE2.6070501@web.de> References: <4B4DD959.9050309@web.de> <4B4DDBE2.6070501@web.de> Message-ID: <40a414c21001130656l6b0d1a42kaed1b073b4f5b2e9@mail.gmail.com> 2010/1/13 G?nther Schmidt : > Am 13.01.10 15:31, schrieb G?nther Schmidt: >> >> Hi, >> >> apologies upfront. As time presses I decided to post questions >> immediately as soon as I run into dead-ends. >> >> I just don't want to give the impression that I'm not willing to do my >> homework. >> >> I'm trying to find documentation on Xhtml, the site on hackage refers to >> http://www.cse.ogi.edu/~andy/html/intro.htm for an introduction to the >> library, the link is dead. >> >> I managed to locate Andy Gill's current homepage >> (http://www.cse.ogi.edu/~andy/html/intro.htm) but there is no mention of >> his html combinatory library. >> > > sry, I meant this site here: http://www.ittc.ku.edu/~andygill/index.php > >> Does anyone else know where an introduction to this library can be >> retrieved from? >> >> G?nther Hi, By Xhtml, do you mean the xhtml package on hackage [1] ? Maybe to get you started: $ ghci Prelude> :m + Text.XHtml.Strict Prelude Text.XHtml.Strict> putStrLn . prettyHtmlFragment $ p (primHtml "hello") ! [theclass "foo"]

hello

The idea is to create values of type Html, e.g. primHtml, combine them to make bigger document, e.g. with p or (+++), possibly with some attributes, e.g. with (!), then eventually render the final Html value, e.g. with prettyHtmlFragment. Try it in ghci! HTH, cheers Thu [1] http://hackage.haskell.org/package/xhtml From gue.schmidt at web.de Wed Jan 13 10:05:53 2010 From: gue.schmidt at web.de (=?UTF-8?B?R8O8bnRoZXIgU2NobWlkdA==?=) Date: Wed Jan 13 09:38:53 2010 Subject: [Haskell-cafe] Re: what is *hack*? In-Reply-To: <29bf512f1001130648p6b2eda40y14033470116d4203@mail.gmail.com> References: <4B4DCE59.2030402@web.de> <4B4DCFA2.6050405@web.de> <29bf512f1001130648p6b2eda40y14033470116d4203@mail.gmail.com> Message-ID: <4B4DE151.1030805@web.de> Hi Michael, on first impression this seems like a good idea then. G?nther Am 13.01.10 15:48, schrieb Michael Snoyman: > G?nther, > > Hack is a layer between a web application and a web server. It allows > you to write a web application once and have it communicate with the > server in different ways simply by swapping the handler. For example, I > have applications that I test on my local system using > hack-handler-simpleserver and then deploy onto an Apache server using > either hack-handler-cgi or hack-handler-fastcgi. > > Michael > From stephen.tetley at gmail.com Wed Jan 13 10:29:08 2010 From: stephen.tetley at gmail.com (Stephen Tetley) Date: Wed Jan 13 10:01:44 2010 Subject: [Haskell-cafe] Xhtml? In-Reply-To: <4B4DD959.9050309@web.de> References: <4B4DD959.9050309@web.de> Message-ID: <5fdc56d71001130729l75341e8odf973e776000951f@mail.gmail.com> 2010/1/13 G?nther Schmidt : .... > Does anyone else know where an introduction to this library can be retrieved > from? Hi G?nther One for the Wayback machine (the HTML library was well documented, unfortunately the docs have been lost...) http://web.archive.org/web/20021206140745/http://www.cse.ogi.edu/~andy/html/intro.htm Best wishes Stephen From monnier at iro.umontreal.ca Wed Jan 13 11:01:15 2010 From: monnier at iro.umontreal.ca (Stefan Monnier) Date: Wed Jan 13 10:34:29 2010 Subject: [Haskell-cafe] Re: ssh ports for monk and nun? References: <79d7c4981001121243j708b6127r5cd5312f0cb97246@mail.gmail.com> <79d7c4981001121257i2a8a230elad85ba04b45b2ec6@mail.gmail.com> Message-ID: >> Trying to get ssh working via putty from behind my company firewall. My recommendation is to get access to an outside machine where you run an OpenVPN server on port 80 or 443. This will solve it "once and for all". But first, please complain loudly and repeatedly about the firewall being closed to port 22. Stefan From robgreayer at gmail.com Wed Jan 13 12:05:33 2010 From: robgreayer at gmail.com (Robert Greayer) Date: Wed Jan 13 11:38:08 2010 Subject: [Haskell-cafe] How to fulfill the "code-reuse" destiny of OOP? In-Reply-To: <1202CA08-B5E7-4519-8975-6FD53C662C23@me.com> References: <3bd412d40910291854w67677d4esc0d47763c6a6fd8a@mail.gmail.com> <4AEB38BE.5010100@btinternet.com> <3bd412d40910310503p3b45d004ia69f873114579f2a@mail.gmail.com> <8b70a98a0910310521s646593a3i2558aca5d4088a27@mail.gmail.com> <87aaz7ovlt.fsf@gregorycollins.net> <1202CA08-B5E7-4519-8975-6FD53C662C23@me.com> Message-ID: <4ec472cb1001130905s4cba8b19t1cf6f9acd36b5c8b@mail.gmail.com> On Wed, Jan 13, 2010 at 4:56 AM, Martin Coxall wrote: > > On 13 Jan 2010, at 09:51, Peter Verswyvelen wrote: > > On Sun, Nov 1, 2009 at 2:57 AM, Gregory Collins > wrote: >> >> Doing OO-style programming in Haskell is difficult and unnatural, it's >> true (although technically speaking it is possible). That said, nobody's >> yet to present a convincing argument to me why Java gets a free pass for >> lacking closures and typeclasses. > > I might be wrong, but doesn't Java's concepts of inner classes and > interfaces together with adapter classes can be used to replace closures and > typeclasses in a way? > > Inner classes are not a semantic replacement for closures, even if you > discount horrific syntax. Inner classes do not close over their lexical > environment. > Martin Anonymous classes in Java close over their lexical environment (can refer to variables in that lexical environment, with values bound at the time of instance construction) with the caveat that only local variables/parameters marked as 'final' may be referred to. Aside from the horrible syntax, this is the key distinction between them, and, say, Ruby closures. Referring to mutable variables from inside a closure has its drawbacks, making the horrible syntax the biggest stumbling block to using them IMHO (other than runtime overhead, which I believe is also an issue). From qdunkan at gmail.com Wed Jan 13 12:54:52 2010 From: qdunkan at gmail.com (Evan Laforge) Date: Wed Jan 13 12:27:27 2010 Subject: [Haskell-cafe] wildcards for type variables? In-Reply-To: <43BCD272-1EB5-42AE-952F-66DF5268FAAD@informatik.uni-kiel.de> References: <2518b95d1001121529l60701d44y13ecf6614c82d1a6@mail.gmail.com> <4c88418c1001130254g58e11e37g1a4ec6cd1bad63e2@mail.gmail.com> <417DCDA9-6971-4F0A-AA5A-45C10DC5FCC3@ece.cmu.edu> <694519c51001130516i7cbb2535yc497efc3839db53c@mail.gmail.com> <43BCD272-1EB5-42AE-952F-66DF5268FAAD@informatik.uni-kiel.de> Message-ID: <2518b95d1001130954v470e510mbf6df19e99cd78e5@mail.gmail.com> >> Isn't that what we have here? a function of type (a -> A -> B) cannot >> use the first argument in any meaningful way. > > I think, he wants to document that the type variable 'a' is not used in the > *type*. Yeah, that's the idea, sorry if I wasn't clear. In the case of const, I might write const :: a -> _b -> a To document that 'b' intentionally appears only once, but this is only my convention and I've never seen anyone else use it. In the case of 'const' it's pretty obvious and unnecessary, but in a longer signature it might help a bit, especially if you are using phantom types and some functions intentionally ignore type arguments. I haven't used them before, but in the presence of scoped type variables, wouldn't have a reader have to go look for internal definitions to reassure himself that the type is in fact ignored entirely? It's not a big issue, but it seemed like a nice symmetry with pattern matching syntax. From cristiano.paris at gmail.com Wed Jan 13 13:43:06 2010 From: cristiano.paris at gmail.com (Cristiano Paris) Date: Wed Jan 13 13:16:03 2010 Subject: [Haskell-cafe] Name overloading Message-ID: Hi, these days I'm thinking about name scoping in Haskell and a question built up silently but steadily in my mind. Many times I see code like this: data Foo = { fooBar :: Int, fooSay :: String, fooClose :: String } which reminds me of "Ye Olde Times" of C where you prepend the structure name (or an abbreviation) to the structure's fields so as to avoid clashes with other (possibly included) structures (here Haskell qualified imports don't help as they just let you cut down the size of the prefix which is still present though and is module-scoped anyway). One of the most appreciated (at least by me) features of OOP languages like C++, Java, Python and co. is the possibility to name instance methods the same in different classes and have the compiler resolve to the correct implementation (at least indirectly through a virtual table when inheritance is in place) simply looking at the type of the variable which "->" is applied to. The most fulgid example of this is the "open" method, which is likely to be present in lots of classes. Now, in Haskell we have type inference, which is "The Good Thing" as it allows to "validate" your program at compile time. Hence, the idea coming up to my mind is that type inference actually forbids a type-directed resolution of names as in C++ or Java. Is this correct? Think about this piece of code: data DB = { open :: DBHandle } data FS = { open :: File } foo x = open x or, worse: foo x = open (open x) if the result of the first "open" application should typecheck with the second. Notice that, in my understanding, adding a signature doesn't help as the type checker must guarantee that "foo" code complies with its signature, which is actually impossible if open is left undetermined in its type. Thank you for any comment. Cristiano From bulat.ziganshin at gmail.com Wed Jan 13 14:01:33 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Wed Jan 13 13:34:15 2010 Subject: [Haskell-cafe] Name overloading In-Reply-To: References: Message-ID: <1337748239.20100113220133@gmail.com> Hello Cristiano, Wednesday, January 13, 2010, 9:43:06 PM, you wrote: > coming up to my mind is that type inference actually forbids a > type-directed resolution of names as in C++ or Java. you are right. we either have ad-hoc polymorphism like in C++ where type of id selected based on type of arguments, like in int open(char *s) int open(int i) or two-way type inference where each id has just one type. otherwise, having both overloaded ids and two-way inference, we will got polynomial raise of complexity of type inferencing. ie. imagine some f = a . b . c . d where a,b,c,d have multiple possible types there is backdorr to this mechanism - you can define foo inside of class. moreover, you can use this to overload struct fields: class HasFoo a b where foo :: a -> b data X = {fooX :: Int} data Y = {fooY :: Char} instance HasFoo X Int where foo=fooX instance HasFoo Y Char where foo=fooY although error messages may be not ideal ;) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From jmillikin at gmail.com Wed Jan 13 14:08:08 2010 From: jmillikin at gmail.com (John Millikin) Date: Wed Jan 13 13:41:02 2010 Subject: [Haskell-cafe] Name overloading In-Reply-To: References: Message-ID: <3283f7fe1001131108r715655fdl7272fe0a644975e9@mail.gmail.com> The usual suggestion I see for this sort of thing is to create a typeclass for the operations you care about[1][2]. For example: ------------------------------------------------------------------------------------------- class HasOpen a where open :: a -> Handle data DB data FS openDB :: DB -> Handle openFS :: FS -> Handle instance DB HasOpen where open = openDB instance FS HasOpen where open = openFS ------------------------------------------------------------------------------------------- Of course, this doesn't allow you to have functions share the same name if they have different signatures, as in your (open :: FS -> File) example. To be honest, I think the C / Haskell approach of unambiguously-identified functions is clearly superior to the C++ / C# / Java "class as namespace" idiom, which has caused me no end of grief. Dynamic languages such as Python and Ruby, of course, can return anything from anywhere. This is nice in some cases, but having used both extensively I think (static typing+inference) is a better solution than dynamic typing. > Now, in Haskell we have type inference, which is "The Good Thing" as > it allows to "validate" your program at compile time. Hence, the idea > coming up to my mind is that type inference actually forbids a > type-directed resolution of names as in C++ or Java. > > Is this correct? Type inference and static typing are separate; inference makes static typing usable, but static typing makes compile-type correctness verification easier. And it's not inference making your goal impossible, but the fact that Haskell (like C) does not support arbitrary overloading. [1] http://www.mail-archive.com/haskell-cafe@haskell.org/msg64844.html [2] http://stackoverflow.com/questions/1897306/haskell-record-syntax-and-type-classes From bulat.ziganshin at gmail.com Wed Jan 13 14:14:01 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Wed Jan 13 13:46:44 2010 Subject: [Haskell-cafe] Name overloading In-Reply-To: <3283f7fe1001131108r715655fdl7272fe0a644975e9@mail.gmail.com> References: <3283f7fe1001131108r715655fdl7272fe0a644975e9@mail.gmail.com> Message-ID: <194934910.20100113221401@gmail.com> Hello John, Wednesday, January 13, 2010, 10:08:08 PM, you wrote: > Of course, this doesn't allow you to have functions share the same > name if they have different signatures class Open a where open :: a instance Open (Int -> String) where ... instance Open (String -> Int) where ... -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From ekmett at gmail.com Wed Jan 13 14:18:21 2010 From: ekmett at gmail.com (Edward Kmett) Date: Wed Jan 13 13:50:54 2010 Subject: [Haskell-cafe] Name overloading In-Reply-To: <3283f7fe1001131108r715655fdl7272fe0a644975e9@mail.gmail.com> References: <3283f7fe1001131108r715655fdl7272fe0a644975e9@mail.gmail.com> Message-ID: <7fb8f82f1001131118p1b37e5aem74e7a909ef4fc7b7@mail.gmail.com> Well, you can get part of the way there, by using a class associated type class HasOpen a where type Open a :: * open :: a -> Open a This lets you use type inference in one direction, without requiring that every result be a member of a data family. On the other hand, type inference just became directional, like in C#. you can't use the type of Open a to infer the type a because you've lost injectivity. You'd need a data type family to guarantee injectivity and determine a from the context of Open a, and that yields an ugly mess. Since each container would have to yield a distinct value type and interoperability goes out the window. On the other hand, the mixture of fixed type slots and type family slots gets you a pretty good compromise. You typically know the type of the structs whose members you are asking for. -Edward Kmett On Wed, Jan 13, 2010 at 2:08 PM, John Millikin wrote: > The usual suggestion I see for this sort of thing is to create a > typeclass for the operations you care about[1][2]. For example: > > > ------------------------------------------------------------------------------------------- > class HasOpen a where > open :: a -> Handle > > data DB > data FS > > openDB :: DB -> Handle > openFS :: FS -> Handle > > instance DB HasOpen where open = openDB > instance FS HasOpen where open = openFS > > ------------------------------------------------------------------------------------------- > > Of course, this doesn't allow you to have functions share the same > name if they have different signatures, as in your (open :: FS -> > File) example. To be honest, I think the C / Haskell approach of > unambiguously-identified functions is clearly superior to the C++ / C# > / Java "class as namespace" idiom, which has caused me no end of > grief. > > Dynamic languages such as Python and Ruby, of course, can return > anything from anywhere. This is nice in some cases, but having used > both extensively I think (static typing+inference) is a better > solution than dynamic typing. > > > Now, in Haskell we have type inference, which is "The Good Thing" as > > it allows to "validate" your program at compile time. Hence, the idea > > coming up to my mind is that type inference actually forbids a > > type-directed resolution of names as in C++ or Java. > > > > Is this correct? > > Type inference and static typing are separate; inference makes static > typing usable, but static typing makes compile-type correctness > verification easier. And it's not inference making your goal > impossible, but the fact that Haskell (like C) does not support > arbitrary overloading. > > [1] http://www.mail-archive.com/haskell-cafe@haskell.org/msg64844.html > [2] > http://stackoverflow.com/questions/1897306/haskell-record-syntax-and-type-classes > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/31ebb41a/attachment.html From ekmett at gmail.com Wed Jan 13 14:22:15 2010 From: ekmett at gmail.com (Edward Kmett) Date: Wed Jan 13 13:54:48 2010 Subject: [Haskell-cafe] Name overloading In-Reply-To: <194934910.20100113221401@gmail.com> References: <3283f7fe1001131108r715655fdl7272fe0a644975e9@mail.gmail.com> <194934910.20100113221401@gmail.com> Message-ID: <7fb8f82f1001131122wf9ec98ved0b11eb898e7f23@mail.gmail.com> > > On Wed, Jan 13, 2010 at 2:14 PM, Bulat Ziganshin < > bulat.ziganshin@gmail.com> wrote: > > class Open a where > open :: a > > instance Open (Int -> String) where ... > instance Open (String -> Int) where ... > The problem with this approach is that you'll need to supply type annotations with basically every use of open, which is even more verbose than prepending the type name. -Edward Kmett -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/ab9dc672/attachment.html From andrewcoppin at btinternet.com Wed Jan 13 14:25:19 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Wed Jan 13 13:57:44 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> <4B4CF878.3070407@btinternet.com> Message-ID: <4B4E1E1F.9060501@btinternet.com> Colin Paul Adams wrote: > Andrew> It's weird that us Haskell people complain about there > Andrew> being only 26 letters in the alphabet > > Which alphabet? > You have plenty of choice in Unicode. > Er... I was under the impression that Haskell source code uses the ASCII character set, not Unicode. (And even if that's not the case, I've yet to find a way to type in the Unicode characters which are hypothetically possible.) From andrewcoppin at btinternet.com Wed Jan 13 14:28:08 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Wed Jan 13 14:00:30 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <1263372640-sup-6089@nixos> References: <4B4CE8CE.9060202@btinternet.com> <1263372640-sup-6089@nixos> Message-ID: <4B4E1EC8.5060308@btinternet.com> Marc Weber wrote: >> As you can see, this conclusively proves... something. >> > > What about brainfuck? 8 different signs are used. > -> http://de.wikipedia.org/wiki/Brainfuck#cite_note-0 > > The first link points to a page saying there is an interpreter 98 bytes > in size.. > > What does this prove? :-) > Exhibit A: The Iota calculus. It has one value (the Iota function), and one operator (function application). It is Turing-complete. I have literally *no idea* how big an interpretter would be... From qdunkan at gmail.com Wed Jan 13 14:28:33 2010 From: qdunkan at gmail.com (Evan Laforge) Date: Wed Jan 13 14:01:08 2010 Subject: [Haskell-cafe] Name overloading In-Reply-To: References: Message-ID: <2518b95d1001131128m7cbfcc69xa2872eefc22f259e@mail.gmail.com> > Now, in Haskell we have type inference, which is "The Good Thing" as > it allows to "validate" your program at compile time. Hence, the idea > coming up to my mind is that type inference actually forbids a > type-directed resolution of names as in C++ or Java. > > Is this correct? There is a proposed extension which is not implemented but was discussed on the list a while back, maybe you'd find this interesting: http://hackage.haskell.org/trac/haskell-prime/wiki/TypeDirectedNameResolution Search back in the archives for TDNR and you should turn up some threads. From allbery at ece.cmu.edu Wed Jan 13 14:28:26 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Wed Jan 13 14:01:16 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4E1E1F.9060501@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> <4B4CF878.3070407@btinternet.com> <4B4E1E1F.9060501@btinternet.com> Message-ID: On Jan 13, 2010, at 14:25 , Andrew Coppin wrote: > Colin Paul Adams wrote: >> Andrew> It's weird that us Haskell people complain about there >> Andrew> being only 26 letters in the alphabet >> >> Which alphabet? >> You have plenty of choice in Unicode. > > Er... I was under the impression that Haskell source code uses the > ASCII character set, not Unicode. The Report would beg to differ with you; see section 2.1. "Haskell uses the Unicode [11] character set. However, source programs are currently biased toward the ASCII character set used in earlier versions of Haskell ." ("Currently" at the time being 1998. Unicode is more prevalent these days.) > (And even if that's not the case, I've yet to find a way to type in > the Unicode characters which are hypothetically possible.) That's a problem with your editor/development environment. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/8182f080/PGP.bin From andrewcoppin at btinternet.com Wed Jan 13 14:29:23 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Wed Jan 13 14:01:47 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <9EE98D56-25E9-4B7E-9CF9-2FE1C12DA9CD@ece.cmu.edu> References: <4B4CE8CE.9060202@btinternet.com> <9EE98D56-25E9-4B7E-9CF9-2FE1C12DA9CD@ece.cmu.edu> Message-ID: <4B4E1F13.5020902@btinternet.com> Brandon S. Allbery KF8NH wrote: > On Jan 12, 2010, at 17:12 , Niklas Broberg wrote: >>> Haskell '98 apparently features 25 reserved words. (Not counting >>> "forall" >>> and "mdo" and so on, which AFAIK are not in Haskell '98.) >> >> 21 actually. case, class, data, default, deriving, do, else, if, >> import, in, infix, infixl, infixr, instance, let, module, newtype, of, >> then, type, where. There's also three special words that can still be >> used as identifiers, so aren't reserved: as, qualified, hiding. > > > Are we counting the FFI annex ("foreign")? > Strictly, wasn't that added *after* the Haskell 98 report was written? I.e., if you wanted to be ultra-technical about it, it's not part of the original Haskell '98? At any rate, no I didn't count the FFI. (Since I almost never use it.) From allbery at ece.cmu.edu Wed Jan 13 14:30:52 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Wed Jan 13 14:03:27 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4E1F13.5020902@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> <9EE98D56-25E9-4B7E-9CF9-2FE1C12DA9CD@ece.cmu.edu> <4B4E1F13.5020902@btinternet.com> Message-ID: <0D8BFC30-8315-4111-876A-92F838193E2C@ece.cmu.edu> On Jan 13, 2010, at 14:29 , Andrew Coppin wrote: > Brandon S. Allbery KF8NH wrote: >> On Jan 12, 2010, at 17:12 , Niklas Broberg wrote: >>>> Haskell '98 apparently features 25 reserved words. (Not counting >>>> "forall" >>>> and "mdo" and so on, which AFAIK are not in Haskell '98.) >>> >>> 21 actually. case, class, data, default, deriving, do, else, if, >>> import, in, infix, infixl, infixr, instance, let, module, newtype, >>> of, >>> then, type, where. There's also three special words that can still >>> be >>> used as identifiers, so aren't reserved: as, qualified, hiding. >> >> Are we counting the FFI annex ("foreign")? > > Strictly, wasn't that added *after* the Haskell 98 report was > written? I.e., if you wanted to be ultra-technical about it, it's > not part of the original Haskell '98? That would be the import of "annex", yes. It was not part of the original standard, but is considered part of the working Haskell '98 standard. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/da2cf2d5/PGP.bin From andrewcoppin at btinternet.com Wed Jan 13 14:31:16 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Wed Jan 13 14:03:40 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <1263339354.4862.122.camel@dell.linuxdev.us.dell.com> References: <4B4CE8CE.9060202@btinternet.com> <1263339354.4862.122.camel@dell.linuxdev.us.dell.com> Message-ID: <4B4E1F84.8020608@btinternet.com> sylvain wrote: > Le mardi 12 janvier 2010 ? 21:25 +0000, Andrew Coppin a ?crit : > > Hi Andrew, > > >> As you can see, this conclusively proves... something. >> > > What, exactly? > Not a lot. As you so elegantly point out, the number of keywords in a language is a fairly crude measurement of how complex the language is or is not. On the other hand, like lines of code, it's something that's easy to measure. ;-) Other such ways include taking the size of a gzip of a typical block of source code, like the Shootout does. This doesn't really prove anything though, because any benchmark can be implemented in more than one way. You could also try using how many pages it takes to explain the syntax of the language - but that also depends on how you explain it. Simplicity is really in the eye of the beholder, after all... From dmehrtash at gmail.com Wed Jan 13 14:31:24 2010 From: dmehrtash at gmail.com (Daryoush Mehrtash) Date: Wed Jan 13 14:03:59 2010 Subject: [Haskell-cafe] What is the difference between Strachey diff from Scott Semantic Domain? Message-ID: On Stack overflow page Conal Elliot says: > Beware that denotational semantics has two parts, from its two founders > Christopher Strachey and Dana Scott: the easier & more useful Strachey part > and the harder and less useful (for design) Scott part. > http://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming > Any more information on how the Scott version is different from Starchey? On Tue, Jan 12, 2010 at 3:24 PM, Raoul Duke wrote: > http://lambda-the-ultimate.org/node/1665#comment-55086 > Daryoush -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/74554054/attachment-0001.html From andrewcoppin at btinternet.com Wed Jan 13 14:41:31 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Wed Jan 13 14:13:56 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <0D8BFC30-8315-4111-876A-92F838193E2C@ece.cmu.edu> References: <4B4CE8CE.9060202@btinternet.com> <9EE98D56-25E9-4B7E-9CF9-2FE1C12DA9CD@ece.cmu.edu> <4B4E1F13.5020902@btinternet.com> <0D8BFC30-8315-4111-876A-92F838193E2C@ece.cmu.edu> Message-ID: <4B4E21EB.7090907@btinternet.com> Brandon S. Allbery KF8NH wrote: > On Jan 13, 2010, at 14:29 , Andrew Coppin wrote: >> Brandon S. Allbery KF8NH wrote: >>> Are we counting the FFI annex ("foreign")? >> >> Strictly, wasn't that added *after* the Haskell 98 report was >> written? I.e., if you wanted to be ultra-technical about it, it's not >> part of the original Haskell '98? > > > That would be the import of "annex", yes. It was not part of the > original standard, but is considered part of the working Haskell '98 > standard. Of course, you could always use Haskell 2010. It exists now, apparently... From andrewcoppin at btinternet.com Wed Jan 13 14:42:36 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Wed Jan 13 14:15:02 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> <4B4CF878.3070407@btinternet.com> <4B4E1E1F.9060501@btinternet.com> Message-ID: <4B4E222C.9020503@btinternet.com> Brandon S. Allbery KF8NH wrote: > On Jan 13, 2010, at 14:25 , Andrew Coppin wrote: >> Colin Paul Adams wrote: >>> Andrew> It's weird that us Haskell people complain about there >>> Andrew> being only 26 letters in the alphabet >>> >>> Which alphabet? >>> You have plenty of choice in Unicode. >> >> Er... I was under the impression that Haskell source code uses the >> ASCII character set, not Unicode. > > The Report would beg to differ with you; see section 2.1. "Haskell > uses the Unicode [11] character set. However, source programs are > currently biased toward the ASCII character set used in earlier > versions of Haskell ." ("Currently" at the time being 1998. Unicode > is more prevalent these days.) So... how would GHC tell which of the hundreds of millions of possible character encodings is in use? >> (And even if that's not the case, I've yet to find a way to type in >> the Unicode characters which are hypothetically possible.) > > That's a problem with your editor/development environment. Or rather, the problem with every computer system known to man? From miguelimo38 at yandex.ru Wed Jan 13 14:44:32 2010 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Wed Jan 13 14:17:08 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4E1E1F.9060501@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> <4B4CF878.3070407@btinternet.com> <4B4E1E1F.9060501@btinternet.com> Message-ID: On 13 Jan 2010, at 22:25, Andrew Coppin wrote: > Colin Paul Adams wrote: >> Andrew> It's weird that us Haskell people complain about there >> Andrew> being only 26 letters in the alphabet >> >> Which alphabet? >> You have plenty of choice in Unicode. >> > > Er... I was under the impression that Haskell source code uses the > ASCII character set, not Unicode. > > (And even if that's not the case, I've yet to find a way to type in > the Unicode characters which are hypothetically possible.) module Main where import Prelude hiding (putStrLn) import System.IO.UTF8 main = let ? = "Andrew Coppin ????? ???????? ??????" ? = ???_??_??? where ???_??_??? = undefined in putStrLn ? From sebastian.sylvan at gmail.com Wed Jan 13 14:48:07 2010 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Wed Jan 13 14:20:42 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <27137827.post@talk.nabble.com> References: <4B4CE8CE.9060202@btinternet.com> <27137827.post@talk.nabble.com> Message-ID: <3d96ac181001131148i58dbb5a0y359a79a7c7af0b3d@mail.gmail.com> On Wed, Jan 13, 2010 at 12:55 AM, Eduard Sergeev wrote: > > > Andrew Coppin wrote: > > > > OK people, it's random statistics time! > > OK, my version of meaningless statistics: > > C++ (ISO/IEC 14882:1998(E)): 325 pages (712 including standard libraries) > C# (ECMA-334): 505 pages (language only) > Java: 450 pages (language only?) > Scala (2.7): 125 pages (157 including standard library) > Eiffel (ECMA-367): 160 pages (language only) > ANSI SQL-92: 685 pages (language only) > Haskell-98: 77 pages (247 including Prelude) > Erlang (4.7.3) 162 pages (251 including builtin functions) > Scheme (R5RS): 17 pages (45 including standard procedures) > Oberon: 16 pages, including table of contents and Appendix (containing EBNF grammar). -- Sebastian Sylvan -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/c19fdd5f/attachment.html From allbery at ece.cmu.edu Wed Jan 13 14:49:02 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Wed Jan 13 14:21:48 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4E222C.9020503@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> <4B4CF878.3070407@btinternet.com> <4B4E1E1F.9060501@btinternet.com> <4B4E222C.9020503@btinternet.com> Message-ID: <43F66B7C-4B3E-4EF8-AF63-264E43EA7C6C@ece.cmu.edu> On Jan 13, 2010, at 14:42 , Andrew Coppin wrote: > Brandon S. Allbery KF8NH wrote: >> On Jan 13, 2010, at 14:25 , Andrew Coppin wrote: >>> Colin Paul Adams wrote: >>>> Andrew> It's weird that us Haskell people complain about there >>>> Andrew> being only 26 letters in the alphabet >>>> >>>> Which alphabet? >>>> You have plenty of choice in Unicode. >>> >>> Er... I was under the impression that Haskell source code uses the >>> ASCII character set, not Unicode. >> >> The Report would beg to differ with you; see section 2.1. "Haskell >> uses the Unicode [11] character set. However, source programs are >> currently biased toward the ASCII character set used in earlier >> versions of Haskell ." ("Currently" at the time being 1998. >> Unicode is more prevalent these days.) > > So... how would GHC tell which of the hundreds of millions of > possible character encodings is in use? That's left to the compiler implementation. I'm not spotting an official statement in the GHC manual, but in practice GHC uses UTF-8. (It might support Windows standard UTF-16 as well; if do, it probably requires the first character of the source file to be a UTF-16 byte order mark.) >>> (And even if that's not the case, I've yet to find a way to type >>> in the Unicode characters which are hypothetically possible.) >> >> That's a problem with your editor/development environment. > > Or rather, the problem with every computer system known to man? s/man/you/ The existence of -XUnicodeSyntax ( http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#unicode-syntax ) suggests that at least some other GHC users don't have your problem. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/f9154104/PGP.bin From sebf at informatik.uni-kiel.de Wed Jan 13 15:31:39 2010 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Wed Jan 13 15:04:11 2010 Subject: [Haskell-cafe] wildcards for type variables? In-Reply-To: <2518b95d1001130954v470e510mbf6df19e99cd78e5@mail.gmail.com> References: <2518b95d1001121529l60701d44y13ecf6614c82d1a6@mail.gmail.com> <4c88418c1001130254g58e11e37g1a4ec6cd1bad63e2@mail.gmail.com> <417DCDA9-6971-4F0A-AA5A-45C10DC5FCC3@ece.cmu.edu> <694519c51001130516i7cbb2535yc497efc3839db53c@mail.gmail.com> <43BCD272-1EB5-42AE-952F-66DF5268FAAD@informatik.uni-kiel.de> <2518b95d1001130954v470e510mbf6df19e99cd78e5@mail.gmail.com> Message-ID: <25DD26F9-93F2-4405-80E3-133AEBBE4649@informatik.uni-kiel.de> On Jan 13, 2010, at 6:54 PM, Evan Laforge wrote: > It's not a big issue, but it seemed like a nice symmetry with pattern > matching syntax. And I don't think it's a weird idea. The "Haskell dialect" Curry [1] supports this syntax. Maybe the hurdle for Haskell is the competition with more complex, conflicting proposals like [2]. Sebastian [1] http://curry-language.org [2] http://hackage.haskell.org/trac/haskell-prime/wiki/PartialTypeSigs -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From tittoassini at gmail.com Wed Jan 13 15:33:18 2010 From: tittoassini at gmail.com (Pasqualino "Titto" Assini) Date: Wed Jan 13 15:05:54 2010 Subject: [Haskell-cafe] Re: what is *hack*? In-Reply-To: <4B4DE151.1030805@web.de> References: <4B4DCE59.2030402@web.de> <4B4DCFA2.6050405@web.de> <29bf512f1001130648p6b2eda40y14033470116d4203@mail.gmail.com> <4B4DE151.1030805@web.de> Message-ID: <2d34474e1001131233t7533eda0hf8aad103b9478906@mail.gmail.com> Hi Michael, what is your experience with hack? Do you have any problem moving your apps from one server/env to another? Regards, titto 2010/1/13 G?nther Schmidt : > Hi Michael, > > on first impression this seems like a good idea then. > > G?nther > > > > Am 13.01.10 15:48, schrieb Michael Snoyman: >> >> G?nther, >> >> Hack is a layer between a web application and a web server. It allows >> you to write a web application once and have it communicate with the >> server in different ways simply by swapping the handler. For example, I >> have applications that I test on my local system using >> hack-handler-simpleserver and then deploy onto an Apache server using >> either hack-handler-cgi or hack-handler-fastcgi. >> >> Michael >> > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- Pasqualino "Titto" Assini, Ph.D. http://quicquid.org/ From korpios at korpios.com Wed Jan 13 15:46:17 2010 From: korpios at korpios.com (Tom Tobin) Date: Wed Jan 13 15:18:51 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> <4B4CF878.3070407@btinternet.com> <4B4E1E1F.9060501@btinternet.com> Message-ID: On Wed, Jan 13, 2010 at 1:28 PM, Brandon S. Allbery KF8NH wrote: > On Jan 13, 2010, at 14:25 , Andrew Coppin wrote: >> (And even if that's not the case, I've yet to find a way to type in the >> Unicode characters which are hypothetically possible.) > > That's a problem with your editor/development environment. It's not just one's editor (I use emacs, and it's actually not that hard to type a decent subset of interesting Unicode characters in emacs with the tex input mode), but readability. The ASCII characters are universal and easily recognized (assuming you have a decent monochrome font); having to notice potentially significant differences involving diacritics alone (not to mention all the various mathematical symbols) in identifiers would drive me mad. It's the same reason we try to limit lines of code to ~80 characters ??our editors are *capable* of more, sure, but are we? From agocorona at gmail.com Wed Jan 13 15:47:18 2010 From: agocorona at gmail.com (Alberto G. Corona ) Date: Wed Jan 13 15:19:55 2010 Subject: [Haskell-cafe] Re: what is *hack*? In-Reply-To: <2d34474e1001131233t7533eda0hf8aad103b9478906@mail.gmail.com> References: <4B4DCE59.2030402@web.de> <4B4DCFA2.6050405@web.de> <29bf512f1001130648p6b2eda40y14033470116d4203@mail.gmail.com> <4B4DE151.1030805@web.de> <2d34474e1001131233t7533eda0hf8aad103b9478906@mail.gmail.com> Message-ID: rack (and hack) permits also to concatenate applications (request handlers) one in top of the other. with interesting combinations (filters, encriptation layers, applications as such). It seems that this is the reason for its name. At first sight it seems too little code to make something useful, but it?s fine. 2010/1/13 Pasqualino "Titto" Assini > Hi Michael, > > what is your experience with hack? Do you have any problem moving your > apps from one server/env to another? > > Regards, > > titto > > 2010/1/13 G?nther Schmidt : > > Hi Michael, > > > > on first impression this seems like a good idea then. > > > > G?nther > > > > > > > > Am 13.01.10 15:48, schrieb Michael Snoyman: > >> > >> G?nther, > >> > >> Hack is a layer between a web application and a web server. It allows > >> you to write a web application once and have it communicate with the > >> server in different ways simply by swapping the handler. For example, I > >> have applications that I test on my local system using > >> hack-handler-simpleserver and then deploy onto an Apache server using > >> either hack-handler-cgi or hack-handler-fastcgi. > >> > >> Michael > >> > > > > > > _______________________________________________ > > Haskell-Cafe mailing list > > Haskell-Cafe@haskell.org > > http://www.haskell.org/mailman/listinfo/haskell-cafe > > > > > > -- > Pasqualino "Titto" Assini, Ph.D. > http://quicquid.org/ > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/a18f22c1/attachment.html From michael at snoyman.com Wed Jan 13 15:56:55 2010 From: michael at snoyman.com (Michael Snoyman) Date: Wed Jan 13 15:29:30 2010 Subject: [Haskell-cafe] Re: what is *hack*? In-Reply-To: <2d34474e1001131233t7533eda0hf8aad103b9478906@mail.gmail.com> References: <4B4DCE59.2030402@web.de> <4B4DCFA2.6050405@web.de> <29bf512f1001130648p6b2eda40y14033470116d4203@mail.gmail.com> <4B4DE151.1030805@web.de> <2d34474e1001131233t7533eda0hf8aad103b9478906@mail.gmail.com> Message-ID: <29bf512f1001131256g13cfdd86k48e244d865e20a7f@mail.gmail.com> Titto, I've had no problems with hack. The only things to keep in mind are outside the scope of hack such as: * Persistence. Clearly you need to optimize your application different for CGI run (load up only what you need right now) versus long-running processes like FastCGI (load data only once). * URL schemes. A lot of people assume that your web app with be served from the root of the domain. When using my simpleserver testing, that *is* the case. However, I deploy apps in subdirectories of my domain ( http://www.snoyman.com/photos/, http://www.snoyman.com/wordify/, etc), so I need to keep this in mind. My only two quips about hack itself is: * Versioning scheme. I wish (and have requested) that Hack would follow the Package Versioning Policy so that I could easily check for breaking changes. As is, I simply have to declare the exact version number of Hack I want to work with to guarantee my apps aren't broken in the future. * More serious issue is that it returns the response as a lazy bytestring. It's not really fair to call this a quip, since I fully supported this approach; nonetheless, using an enumerator for this would probably be more efficient for certain use cases. I just a few hours ago sent off an e-mail about bringing into fruition the Web Application Interface for Haskell, which I would envision as Hack with these two quips addressed. Theoretically, it would also allow easy collaboration with Hack. Michael On Wed, Jan 13, 2010 at 10:33 PM, Pasqualino "Titto" Assini < tittoassini@gmail.com> wrote: > Hi Michael, > > what is your experience with hack? Do you have any problem moving your > apps from one server/env to another? > > Regards, > > titto > > 2010/1/13 G?nther Schmidt : > > Hi Michael, > > > > on first impression this seems like a good idea then. > > > > G?nther > > > > > > > > Am 13.01.10 15:48, schrieb Michael Snoyman: > >> > >> G?nther, > >> > >> Hack is a layer between a web application and a web server. It allows > >> you to write a web application once and have it communicate with the > >> server in different ways simply by swapping the handler. For example, I > >> have applications that I test on my local system using > >> hack-handler-simpleserver and then deploy onto an Apache server using > >> either hack-handler-cgi or hack-handler-fastcgi. > >> > >> Michael > >> > > > > > > _______________________________________________ > > Haskell-Cafe mailing list > > Haskell-Cafe@haskell.org > > http://www.haskell.org/mailman/listinfo/haskell-cafe > > > > > > -- > Pasqualino "Titto" Assini, Ph.D. > http://quicquid.org/ > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/3ceaa02a/attachment.html From lemming at henning-thielemann.de Wed Jan 13 16:25:32 2010 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Wed Jan 13 15:58:07 2010 Subject: [Haskell-cafe] ghc -e In-Reply-To: References: <4B452987.2030305@gmail.com> Message-ID: On Wed, 6 Jan 2010, Gwern Branwen wrote: > On Wed, Jan 6, 2010 at 7:23 PM, Tony Morris wrote: >> ghc -e "import Control.Monad; forM [[1,2,3]] reverse" > > As of 6.10.2, the bug whereby the GHC API lets you use functions from > anywhere just by naming them (Java-style) has not been fixed: > > $ ghc -e "Control.Monad.forM [[1,2,3]] reverse" > package flags have changed, resetting and loading new packages... Why is this a bug? This is the intended behaviour in GHCi and you can include and exclude packages with -package and -hide-package options, respectively. From schlepptop at henning-thielemann.de Wed Jan 13 16:42:18 2010 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Wed Jan 13 16:15:18 2010 Subject: [Haskell-cafe] Re: looking for origin of quote on preprocessors and language design In-Reply-To: <1262870296.6326.116.camel@picard> References: <4B45D443.8020709@imn.htwk-leipzig.de> <1262870296.6326.116.camel@picard> Message-ID: <4B4E3E3A.9020609@henning-thielemann.de> Maciej Piechotka schrieb: > > Not quite. While I agree that "the *frequent* need for a preprocessor > shows omissions in (the design of) a language." it is not necessary the > case. Preprocessor may be useful if: > > - there is a new beatyful feature in newer version of compiler but you > still want to have backward compatibility. > - there are compiler or platform dependant elements. For example if you > write a driver in Haskell you may want to share code as much as possible > but you need to know 1) the size of registers and 2) the platform you're > writing as Windows have quite different API then Linux or BSD. > - You need to enable/disable features at build-time. It is not frequent > at closed-source system but it is frequent on OpenSource systems. For > example I might need to have minimal program for embedded system but > with full feature set it likly conquer the desktops > Many of these problems are solved by preprocessor intervention in C/C++, but there is often no need to do so. You could also write system dependent modules, where the right module for your system is included by the build system. I hope the build system does not count as a preprocessor. In Haskell it is however still no fun to support multiple versions of the base libraries, not to speak of different compilers - and their set of libraries. Unfortunately, the original question is still not answered. From gue.schmidt at web.de Wed Jan 13 16:51:48 2010 From: gue.schmidt at web.de (=?UTF-8?B?R8O8bnRoZXIgU2NobWlkdA==?=) Date: Wed Jan 13 16:24:44 2010 Subject: [Haskell-cafe] Re: status of wash? In-Reply-To: <1263320952-sup-2060@nixos> References: <4B4CB768.2080704@web.de> <1263320952-sup-2060@nixos> Message-ID: <4B4E4074.8040705@web.de> Hi, well I followed klondykes advise and followed through with the examples on the http://www.haskell.org/haskellwiki/Practical_web_programming_in_Haskell site. The authors did point out at the very beginning that the approach shown was not very sophisticated and I'd agree with that :) . Of what I *read* about WASH that is more like what I had in mind, state of the art sort of thing. How come it's discontinued or not maintained? It pretty much looks like Seaside just in Haskell. As I said this is by judging from what I *read*, I haven't actually used it yet. Is this technique continued in some other project maybe? G?nther From uzytkownik2 at gmail.com Wed Jan 13 16:54:59 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Wed Jan 13 16:27:36 2010 Subject: [Haskell-cafe] Re: looking for origin of quote on preprocessors and language design In-Reply-To: <4B4E3E3A.9020609@henning-thielemann.de> References: <4B45D443.8020709@imn.htwk-leipzig.de> <1262870296.6326.116.camel@picard> <4B4E3E3A.9020609@henning-thielemann.de> Message-ID: <1263419699.9546.4.camel@picard> On Wed, 2010-01-13 at 22:42 +0100, Henning Thielemann wrote: > Maciej Piechotka schrieb: > > > > Not quite. While I agree that "the *frequent* need for a preprocessor > > shows omissions in (the design of) a language." it is not necessary the > > case. Preprocessor may be useful if: > > > > - there is a new beatyful feature in newer version of compiler but you > > still want to have backward compatibility. > > - there are compiler or platform dependant elements. For example if you > > write a driver in Haskell you may want to share code as much as possible > > but you need to know 1) the size of registers and 2) the platform you're > > writing as Windows have quite different API then Linux or BSD. > > - You need to enable/disable features at build-time. It is not frequent > > at closed-source system but it is frequent on OpenSource systems. For > > example I might need to have minimal program for embedded system but > > with full feature set it likly conquer the desktops > > > Many of these problems are solved by preprocessor intervention in C/C++, > but there is often no need to do so. You could also write system > dependent modules, where the right module for your system is included by > the build system. I hope the build system does not count as a > preprocessor. In Haskell it is however still no fun to support multiple > versions of the base libraries, not to speak of different compilers - > and their set of libraries. > > Unfortunately, the original question is still not answered. > Hmm. May I ask how to do for example something depending on POSIX or WinAPI? I am sorry but I cannot see how any of the above problems could be solved. Regards -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/e6e917f7/attachment.bin From jmillikin at gmail.com Wed Jan 13 17:43:04 2010 From: jmillikin at gmail.com (John Millikin) Date: Wed Jan 13 17:15:57 2010 Subject: [Haskell-cafe] looking for origin of quote on preprocessors and language design In-Reply-To: <4B45D443.8020709@imn.htwk-leipzig.de> References: <4B45D443.8020709@imn.htwk-leipzig.de> Message-ID: <3283f7fe1001131443v1f71f70el4b2e244119d86871@mail.gmail.com> Haskell doesn't *need* preprocessors, but they sure make a lot of things easier. There are three I use regularly (c2hs, cpphs, noweb), and each serves a purpose which isn't directly supported by plain Haskell: c2hs -- Supports generating foreign function imports and wrappers based on C header files. This is simpler and less prone to cross-platform type errors than writing the declarations in Haskell, which generally requires a cpp-style #if..#else..#endif preprocessor anyway. cpphs -- The C preprocessor, adapted to Haskell syntax. I'd like to replace my uses of it with Template Haskell, but TH's limitation that its splices can't be defined in the same file make it (for my purposes) essentially useless. cpphs is text-based, which means you can glue together pretty much anything and let the compiler verify that it type-checks. noweb -- True literate programming (as opposed to .lhs verbose commenting), which allows sections of the source code to be re-arranged arbitrarily. I suppose it's possible in theory for a language to support this without a preprocessing step, but (to my knowledge) not even LISP derivatives do/can. On Thu, Jan 7, 2010 at 04:32, Johannes Waldmann wrote: > Dear all, > > It's not exactly Haskell-specific, but ... > I am trying to track down the origin of the proverb > > "the existence (or: need for) a preprocessor > shows omissions in (the design of) a language." > > > I like to think that in Haskell, we don't need > preprocessors since we can manipulate programs > programmatically, because they are data. > > In other words, a preprocessor realizes higher order > functions, and you only need this if your base language > is first-order. > > Yes, that's vastly simplified, and it does not cover > all cases, what about generic programming > (but this can be done via Data.Data) > and alex/happy (but we have parsec) etc etc. > > Best regards, J.W. > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From pseudo.meta at me.com Wed Jan 13 18:53:59 2010 From: pseudo.meta at me.com (Martin Coxall) Date: Wed Jan 13 18:37:31 2010 Subject: [Haskell-cafe] How to fulfill the "code-reuse" destiny of OOP? In-Reply-To: <4ec472cb1001130905s4cba8b19t1cf6f9acd36b5c8b@mail.gmail.com> References: <3bd412d40910291854w67677d4esc0d47763c6a6fd8a@mail.gmail.com> <4AEB38BE.5010100@btinternet.com> <3bd412d40910310503p3b45d004ia69f873114579f2a@mail.gmail.com> <8b70a98a0910310521s646593a3i2558aca5d4088a27@mail.gmail.com> <87aaz7ovlt.fsf@gregorycollins.net> <1202CA08-B5E7-4519-8975-6FD53C662C23@me.com> <4ec472cb1001130905s4cba8b19t1cf6f9acd36b5c8b@mail.gmail.com> Message-ID: <5A87FCEE-EF28-4F82-88A6-B54DAA682F52@me.com> >> > > Anonymous classes in Java close over their lexical environment (can > refer to variables in that lexical environment, with values bound at > the time of instance construction) with the caveat that only local > variables/parameters marked as 'final' may be referred to. Aside from > the horrible syntax, this is the key distinction between them, and, > say, Ruby closures. Referring to mutable variables from inside a > closure has its drawbacks, making the horrible syntax the biggest > stumbling block to using them IMHO (other than runtime overhead, which > I believe is also an issue). Yes, this. Which makes them basically unusable where you might want proper closures. From nfjinjing at gmail.com Wed Jan 13 19:28:31 2010 From: nfjinjing at gmail.com (Jinjing Wang) Date: Wed Jan 13 19:01:03 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> Message-ID: <81ea7d401001131628p1fa9a512if06ddff64ed106e4@mail.gmail.com> The hyena backend is essentially just a translator between hack and wai, i failed to finished it since I can't understand iteratee (seriously) and eventually got distracted ... What hyena tries to solve can't be realized in hack, so there's not too much reason for a backend anyway. Hyena is especially tuned for streaming and that's exactly what hack can't do (in practice). http://github.com/nfjinjing/hack-handler-hyena -- jinjing From ryani.spam at gmail.com Wed Jan 13 20:11:11 2010 From: ryani.spam at gmail.com (Ryan Ingram) Date: Wed Jan 13 19:43:43 2010 Subject: [Haskell-cafe] space leaks and optimizations In-Reply-To: <4B485910.7070701@iqi.caltech.edu> References: <4B471126.4010807@iqi.caltech.edu> <3e1162e61001080717i25e54a1bl16c983d0e8ebc68d@mail.gmail.com> <4B485910.7070701@iqi.caltech.edu> Message-ID: <2f9b2d31001131711j43167935r9860a2c2606e96e8@mail.gmail.com> On Sat, Jan 9, 2010 at 2:23 AM, Alexei Kitaev wrote: > Reading the discussion related to your blog, I > realized that strict State is different in that it does not actually > force the state. But forcing can be achieved by wrapping all actions > with the following function: > > sState :: (s -> (a,s)) -> State s a > sState f = State $ \s -> case f s of > ? ? ? ? ? ? ? ? ? ? ? ? ? ? (a,s') -> s' `seq` (a,s') > > I hope that somebody will answer my other questions about the > operational semantics and optimizations. Hi Alexei, you have a ton of great points but I wanted to discuss an issue with this one. It's unusual that this is what you want either; since it only reduces the state to WHNF. For example, if your state is a string, this only evaluates enough to know whether or not the string is empty at each step, and you can still get into trouble with code like this: put ("xxx" ++ some_bad_computation) which leave bottoms inside of your state which won't show up until later. Several attempts to solve this problem exist, but the most commonly used one is the "rnf" strategy from Control.Parallel.Strategies, which uses a typeclass to allow each type to specify how to evaluate itself completely. -- ryan From dnmehay at gmail.com Wed Jan 13 23:07:43 2010 From: dnmehay at gmail.com (DNM) Date: Wed Jan 13 22:40:15 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <945952185.20100113143335@gmail.com> References: <27139612.post@talk.nabble.com> <945952185.20100113143335@gmail.com> Message-ID: <27156139.post@talk.nabble.com> Bulat, Some very good suggestions. I will try to appease Ceiling Cat and reduce my (perhaps gratuitous) use of unsafePerformIO. I'm going to have to use it somewhere, since I want referentially transparent code (and I try to avoid the IO monad when possible, anyway). > 2. if your function returns Ptr a - then hold in haskell types this Ptr a. > no need to convert it back and forth to ForeignPtr Yes, I thought of doing this, but then thought it was better to use a so-called "managed" foreign pointer via newForeignPtr. I thought this was the best way to have a foreign pointer that the Haskell garbage collector would eat up when it was no longer in use. I could be wrong. I convert from a ForeignPtr to a Ptr, because the FFI code wasn't compiling at all (nevermind the missing C/C++ reference problem), as apparently a ForeignPtr isn't the sort of thing that an imported foreign function can take as an argument (or so said GHC). I just assumed that the back-and-forth between Ptr and ForeignPtr would be compiled away by GHC. I could be wrong, though. If performance starts to suffer, I'll manage the Ptr memory in my code directly. > 4. i don't looked in your code but if C functions defines > *modifiable* datastructure - you should use it at Haskell side via > imperatiove functions, i.e. those with return type IO a. using > unsafePerformIO in this case will lead to Haskell compiler will > consider this datatype as permanent and reorder operations on the will Good point. I would do this if I planned to train or update the language model from within Haskell, but, as it stands, I just want to train it once (at the command line, using the built-in mechanisms of SRILM) and then read in the ARPA-formatted language model file for use in Haskell. > 3. why c_dlm is FunPtr in your definition? it should be > > foreign import ccall "srilm.h deleteLM" > c_dlm :: Ptr Ngram -> IO () No reason. Just because I don't know what I'm doing yet. Thanks for the correction. Thanks for the help, Bulat. Much appreciated. Best, Dennis -- View this message in context: http://old.nabble.com/FFI%2C-C-C%2B%2B-and-undefined-references-tp27139612p27156139.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From dnmehay at gmail.com Wed Jan 13 23:25:54 2010 From: dnmehay at gmail.com (DNM) Date: Wed Jan 13 22:58:25 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <61E9624C-CB47-469C-BC29-2FA4A670D845@cs.york.ac.uk> References: <27139612.post@talk.nabble.com> <61E9624C-CB47-469C-BC29-2FA4A670D845@cs.york.ac.uk> Message-ID: <27156254.post@talk.nabble.com> Malcolm, I saw this suggestion somewhere else. Unfortunately, it didn't help either. I still get the "undefined reference" errors. I did eventually get ghc to compile Main.hs by putting the -c and -cpp flags after "--make Main.hs". Then it produces a Main.o file which (even with +x permissions on my Linux box) will not run. I just get the message "cannot run binary file", or some such message. No explanation given. Any ideas? Best, Dennis Malcolm Wallace wrote: > >> But when I try to compile it (after having successfully compiled the >> C code >> with g++), I get: >> >> $ ghc --make Main.hs > > You are not telling ghc to link against the C/C++ code, e.g. > ghc --make Main.hs srilm.o > > Regards, > Malcolm > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- View this message in context: http://old.nabble.com/FFI%2C-C-C%2B%2B-and-undefined-references-tp27139612p27156254.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From dnmehay at gmail.com Wed Jan 13 23:28:58 2010 From: dnmehay at gmail.com (DNM) Date: Wed Jan 13 23:01:30 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <350E8375-EBE0-4893-A956-72AD45666AAB@ece.cmu.edu> References: <27139612.post@talk.nabble.com> <350E8375-EBE0-4893-A956-72AD45666AAB@ece.cmu.edu> Message-ID: <27156267.post@talk.nabble.com> Sorry. In my haste to paste in the .c file, I left out all the include statements. I do have #include "srilm.h" there (which to my non- C/C++ mind seems stupid -- why the hell would you need to import the header file for the code that it's a header *for*?) Still no dice. Thanks for your time, though. Sorry to waste it. --D.N. -- View this message in context: http://old.nabble.com/FFI%2C-C-C%2B%2B-and-undefined-references-tp27139612p27156267.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From allbery at ece.cmu.edu Wed Jan 13 23:40:45 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Wed Jan 13 23:13:30 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <27156267.post@talk.nabble.com> References: <27139612.post@talk.nabble.com> <350E8375-EBE0-4893-A956-72AD45666AAB@ece.cmu.edu> <27156267.post@talk.nabble.com> Message-ID: <42435E1D-33CC-4E30-813E-5B2107B7B8E1@ece.cmu.edu> On Jan 13, 2010, at 23:28 , DNM wrote: > Sorry. In my haste to paste in the .c file, I left out all the > include > statements. I do have #include "srilm.h" there (which to my non- > C/C++ mind seems stupid -- why the hell would you need to import > the header file for the code that it's a header *for*?) Really, the only reason in this case is that there is no equivalent for `extern "C"' that you can apply to a function definition, only to a declaration. The rationale is that everything that works with the function, including its definition, needs to see that declaration, so rather than repeat it in the definition you #include the declaration. In GHC, this is the kind of thing that lands in the .hi file; the tradeoff is you need to have up to date .hi files for everything that needs to see that information, which can lead to dependency loops. GHC has a ".hs-boot" hack to work around this. No free lunch.... -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100113/c62cf682/PGP.bin From colin at colina.demon.co.uk Thu Jan 14 01:45:56 2010 From: colin at colina.demon.co.uk (Colin Paul Adams) Date: Thu Jan 14 01:18:29 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: (Tom Tobin's message of "Wed\, 13 Jan 2010 14\:46\:17 -0600") References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> <4B4CF878.3070407@btinternet.com> <4B4E1E1F.9060501@btinternet.com> Message-ID: >>>>> "Tom" == Tom Tobin writes: Tom> readability. The ASCII characters are universal and easily Tom> recognized No they are not. My wife is Chinese. When she was learning pinyin as a child, she asked her father for help with some homework. He replied that he didn't understand them. -- Colin Adams Preston Lancashire From kitaev at iqi.caltech.edu Thu Jan 14 02:03:09 2010 From: kitaev at iqi.caltech.edu (Alexei Kitaev) Date: Thu Jan 14 01:35:42 2010 Subject: [Haskell-cafe] Strategies Message-ID: <4B4EC1AD.5090605@iqi.caltech.edu> Dear Ryan, Thanks a lot for your support and for pointing out a problem with my approach to forcing the state. I was aware of this issue but I didn't know there was a standard solution. It is indeed very natural to let each type specify how to evaluate itself. I will try this technique on the nearest occasion. Incidentally, the link to Control.Parallel.Strategies from the latest GHC User Guide is broken... --Alexei Ryan Ingram wrote: > On Sat, Jan 9, 2010 at 2:23 AM, Alexei Kitaev wrote: >> Reading the discussion related to your blog, I >> realized that strict State is different in that it does not actually >> force the state. But forcing can be achieved by wrapping all actions >> with the following function: >> >> sState :: (s -> (a,s)) -> State s a >> sState f = State $ \s -> case f s of >> (a,s') -> s' `seq` (a,s') >> >> I hope that somebody will answer my other questions about the >> operational semantics and optimizations. > > Hi Alexei, you have a ton of great points but I wanted to discuss an > issue with this one. > > It's unusual that this is what you want either; since it only reduces > the state to WHNF. For example, if your state is a string, this only > evaluates enough to know whether or not the string is empty at each > step, and you can still get into trouble with code like this: > > put ("xxx" ++ some_bad_computation) > > which leave bottoms inside of your state which won't show up until later. > > Several attempts to solve this problem exist, but the most commonly > used one is the "rnf" strategy from Control.Parallel.Strategies, which > uses a typeclass to allow each type to specify how to evaluate itself > completely. > > -- ryan From will_n48 at yahoo.com Thu Jan 14 02:25:48 2010 From: will_n48 at yahoo.com (Will Ness) Date: Thu Jan 14 01:58:43 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001121400.25492.daniel.is.fischer@web.de> <201001131233.23024.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > Am Mittwoch 13 Januar 2010 10:43:42 schrieb Heinrich Apfelmus: > > I wonder whether it's really the liveness of ?pair ?in > > > > ? mergeSP (a,b) pair > > ? ? ?= let sm = spMerge b (fst pair) > > ? ? ? ?in (a ++ fst sm, merge (snd sm) (snd pair)) > > > > that is responsible for the space leak, for chances are that Sparud's > > technique applies and ?pair ?is properly disposed of. Rather, it could > > be that we need the stronger property that forcing the second component > > will evaluate the first to NF. > > I think that is responsible. At least that's how I understand the core: > > mergeSP (a,b) ~(c,d) = (a ++ bc, merge b' d) > where > (bc, b') = spMerge b c > spMerge ... That is equivalent to first (a++) . second (`merge`d) $ spMerge b c and Daniel's fix is equivalent to first (a++) $ spMerge b c d Now, when compiler sees the first variant, it probably treats spMerge as opaque. I.e. although in reality spMerge only contributes to the first "channel" while it is progressively instantiated, and (`merge`d) will only be called upon when spMerge's final clause is reached, that is (most likely) not known to the compiler at this stage. When looking at just the first expression itself, it has to assume that spMerge may contribute to both channels (parts of a pair) while working, and so can't know _when_ /d/ will get called upon to contribute to the data, as it is consumed finally at access. So /d/ is gotten hold of prematurely, _before_ going into spMerge. The second variant passes the responsibility for actually accessing its inputs to spMerge itself, and _it_ is clear about needing /d/ only in the very end. Just a theory. :) Does that make sense? From bulat.ziganshin at gmail.com Thu Jan 14 02:56:08 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Thu Jan 14 02:28:55 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <27156139.post@talk.nabble.com> References: <27139612.post@talk.nabble.com> <945952185.20100113143335@gmail.com> <27156139.post@talk.nabble.com> Message-ID: <522025072.20100114105608@gmail.com> Hello DNM, Thursday, January 14, 2010, 7:07:43 AM, you wrote: > Yes, I thought of doing this, but then thought it was better to use a > so-called "managed" foreign pointer via newForeignPtr. i recommend to use Ptr and switch to ForeignPtr only when you will study how to use it. overall, unsafe* functions are really unsafe, and using them without learning will lead to mysterious problems. it's like painting with eyes closed > Good point. I would do this if I planned to train or update the language > model > from within Haskell, but, as it stands, I just want to train it once (at the > command line, > using the built-in mechanisms of SRILM) and then read in the ARPA-formatted > language > model file for use in Haskell. you may add problems by using unsafePerformIO. i recommend you to learn first how to manage FFI without it, make program work, and only then try to use it. eat elephant in small pieces! look into http://haskell.org/haskellwiki/IO_inside -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From bulat.ziganshin at gmail.com Thu Jan 14 02:57:54 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Thu Jan 14 02:30:47 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <42435E1D-33CC-4E30-813E-5B2107B7B8E1@ece.cmu.edu> References: <27139612.post@talk.nabble.com> <350E8375-EBE0-4893-A956-72AD45666AAB@ece.cmu.edu> <27156267.post@talk.nabble.com> <42435E1D-33CC-4E30-813E-5B2107B7B8E1@ece.cmu.edu> Message-ID: <897668250.20100114105754@gmail.com> Hello Brandon, Thursday, January 14, 2010, 7:40:45 AM, you wrote: > Really, the only reason in this case is that there is no equivalent > for `extern "C"' that you can apply to a function definition, only to > a declaration it works with GCC: extern "C" int c_szOpenArchive (TABI_ELEMENT* params) { .... } -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From cristiano.paris at gmail.com Thu Jan 14 04:10:51 2010 From: cristiano.paris at gmail.com (Cristiano Paris) Date: Thu Jan 14 03:43:44 2010 Subject: [Haskell-cafe] Name overloading In-Reply-To: <2518b95d1001131128m7cbfcc69xa2872eefc22f259e@mail.gmail.com> References: <2518b95d1001131128m7cbfcc69xa2872eefc22f259e@mail.gmail.com> Message-ID: I wish to thank all of you for your comments. In fact, the solutions you proposed mostly coincided with mine (including the one using type families) but, in my opinion, they are more cumbersome than the prefixed names solution. Going back to my example: f x = open $ open x where: data Foo = { open :: Bar } data Bar = { open :: String } there are basically two possibilities to assign types to the "open" functions, either the first is "open :: Foo -> Bar" and the second is "open :: Bar -> String" or the converse. It's clear that the type checker might explore these two possibilities until one of them typechecks. Hence, the possible outcomes of this search would be: 1 - No possible assignment works so the typechecking phase fail. 2 - One possibility matches, then it's undertaken. 3 - Two or more possibilities match so an ambiguity is found which can be solved only by the programmer specifying the type of the open function explicitly, which is just like using the prefix based solution. Would you trust a type checker behaving like this? My answer is no, as the type checker would be making assumptions about my intentions when I wrote the expression "open $ open x". I would rather prefer the compiler to signal this as an error, forcing me to be more explicit about my real intentions that I could actually find to be wrong (i.e. a bug would be accepted silently). Concerning TDNR, I read about it just a while ago but, as far as I can remember, it's just a syntactic dissertation on the subject while the type checking matter is not touched. Thank you again. C. On Wed, Jan 13, 2010 at 8:28 PM, Evan Laforge wrote: >> Now, in Haskell we have type inference, which is "The Good Thing" as >> it allows to "validate" your program at compile time. Hence, the idea >> coming up to my mind is that type inference actually forbids a >> type-directed resolution of names as in C++ or Java. >> >> Is this correct? > > There is a proposed extension which is not implemented but was > discussed on the list a while back, maybe you'd find this interesting: > > http://hackage.haskell.org/trac/haskell-prime/wiki/TypeDirectedNameResolution > > Search back in the archives for TDNR and you should turn up some threads. Cristiano From qdunkan at gmail.com Thu Jan 14 04:38:52 2010 From: qdunkan at gmail.com (Evan Laforge) Date: Thu Jan 14 04:11:25 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> <4B4CF878.3070407@btinternet.com> <4B4E1E1F.9060501@btinternet.com> Message-ID: <2518b95d1001140138ia2dafffw57f213dcff55b460@mail.gmail.com> Wow, that's kind of cute: {-# LANGUAGE UnicodeSyntax #-} (?) = (*) (?) = (/) ?? ? ? ?=???????? ?? = 123 Oddly, if I change the order of these definitions I get syntax errors. Very mysterious. Nice how it knows that ? is a symbol, but I'm not sure how I'm supposed to name a type. It certainly spells the end of of camelCase arguments though, and can take single-character variable names to dizzying new heights :) I suppose number literals can't be overridden though. Not to mention ? and ??. > It's not just one's editor (I use emacs, and it's actually not that > hard to type a decent subset of interesting Unicode characters in > emacs with the tex input mode), but readability. The ASCII characters > are universal and easily recognized (assuming you have a decent > monochrome font); having to notice potentially significant differences > involving diacritics alone (not to mention all the various > mathematical symbols) in identifiers would drive me mad. It's the > same reason we try to limit lines of code to ~80 characters -- our > editors are *capable* of more, sure, but are we? Unicode identifiers are fun but this is a good point. The line has to be somewhere, so it might as well be in the historical position unless there are widely agreed on benefits to moving it. On Wed, Jan 13, 2010 at 10:45 PM, Colin Paul Adams wrote: > My wife is Chinese. When she was learning pinyin as a child, she > asked her father for help with some homework. He replied that he didn't > understand them. But that's all kind of beside the point because you already need to learn quite a bit of specialized knowledge to be writing in haskell in the first place. It's real hard to get to that stage without already recognizing ascii. If the problem was just pinyin and not latin letters in general, then most Taiwanese wouldn't understand it either. From nicolas.pouillard at gmail.com Thu Jan 14 04:53:48 2010 From: nicolas.pouillard at gmail.com (Nicolas Pouillard) Date: Thu Jan 14 04:26:23 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: <81ea7d401001131628p1fa9a512if06ddff64ed106e4@mail.gmail.com> References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> <81ea7d401001131628p1fa9a512if06ddff64ed106e4@mail.gmail.com> Message-ID: <1263462665-sup-8709@ks> Excerpts from Jinjing Wang's message of Thu Jan 14 01:28:31 +0100 2010: | The hyena backend is essentially just a translator between hack and | wai, i failed to finished it since I can't understand iteratee | (seriously) and eventually got distracted ... If I have well understood you miss a function to convert an enumerator to a list. What about this code? > import qualified Data.ByteString.Lazy.Char8 as S > import Control.Concurrent (forkIO) > import Control.Concurrent.Chan (newChan,writeChan,getChanContents) > > type Enumerator = forall a. (a -> S.ByteString -> IO (Either a a)) -> a -> IO a > > enumToList :: Enumerator -> IO [S.ByteString] > enumToList e = do ch <- newChan > _ <- forkIO $ e (writer ch) () > getChanContents ch > where writer ch () chunk = do writeChan ch chunk > return (Right ()) Best regards, -- Nicolas Pouillard http://nicolaspouillard.fr From tittoassini at gmail.com Thu Jan 14 05:06:42 2010 From: tittoassini at gmail.com (Pasqualino "Titto" Assini) Date: Thu Jan 14 04:39:14 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: <29bf512f1001131337j4ddfc409g6968cae62783b5b4@mail.gmail.com> References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> <2d34474e1001131312w514ee46bwcd76bcb10ada928c@mail.gmail.com> <29bf512f1001131337j4ddfc409g6968cae62783b5b4@mail.gmail.com> Message-ID: <2d34474e1001140206h67488317ye5f22999f5c2ca39@mail.gmail.com> Hi Michael, no, the message was not meant to be off-list, that was just me pressing the wrong button :-) Regarding happstack, I do not believe that there is a contrast with your effort, the core of happstack is in its persistency mechanism not in its http interface so I think it would be great to engage the happstack community in this effort. We have so many half-baked and dispersed attempts in the web area that any attempt at consolidation can only be welcome. Personally I have been using happstack for a few years though now I am running it behind a nginx server because of its known deficiencies (no HTTPS etc). titto P.S. I will be away for a few days and unable to answer my email 2010/1/13 Michael Snoyman : > Not sure if you replied off-list on purpose or not, but I'll continue this > off list for the moment. I think we have a bit of a problem in the Haskell > web community: you've got the Happstack camp and then the rest of us. "The > rest of us" need to rally around *something*, and it seems that Hack didn't > get people's attention for some reason. > > I'm happy to write WAI, but I'd like more to make it a community effort. You > have any thoughts on this? My first stab at the idea is to create a github > repo, write the code, and then try to get people to comment on it. However, > I also want to give it at least a day so I can get people's feedback on this > e-mail. > > What have you been using for Haskell web development until now? It seems > like each non-Happstack person has a totally different approach, and I'd > like to try and consolidate this together somehow. > > Michael > > On Wed, Jan 13, 2010 at 11:12 PM, Pasqualino "Titto" Assini > wrote: >> >> A unified web app interface would be a God-sent, please please go ahead. >> >> Regarding point 1, I find hack interface nice and clean and would like >> to see something similar. >> >> Regarding point 2 I vote for correctness/performance vs convenience. >> >> ? ? titto >> >> 2010/1/13 Michael Snoyman : >> > Hi, >> > >> > I recently read (again) the wiki page on a web application interface[1] >> > for >> > Haskell. It seems like this basically works out to Hack[2], but using an >> > enumerator instead of lazy bytestring in the response type. Is anyone >> > working on implementing this? If not, I would like to create the >> > package, >> > though I wouldn't mind some community input on some design decisions: >> > >> > * Hack has been fairly well-tested in the past year and I think it >> > provides >> > the features that people want. Therefore, I would want to model the >> > Environment variable for WAI from Hack. I *could* just import Hack in >> > WAI >> > and use the exact same Environment data type. Thoughts? >> > >> > * If using a different data type for Environment, should I replace the >> > String parts with ByteStrings? On the one hand, ByteStrings are the >> > "correct" data type since the HTTP protocol does not specify a character >> > encoding; on the other hand, Strings are easier to deal with. >> > >> > * It's simple to write a function to convert between a lazy bytestring >> > and >> > an enumerator, meaning it would be very easy to write conversion >> > functions >> > between Hack and WAI applications. This would make it simpler for people >> > to >> > use either backend. >> > >> > If someone else is already working on WAI, please let me know, I don't >> > want >> > to have duplicate implementations. The idea here is to consolidate, not >> > split the community. I have a few Hack handlers (simpleserver, cgi, >> > fastcgi) >> > that I would happily convert to WAI handlers as well. >> > >> > Michael >> > >> > [1] http://www.haskell.org/haskellwiki/WebApplicationInterface >> > [2] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hack >> > >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > Haskell-Cafe@haskell.org >> > http://www.haskell.org/mailman/listinfo/haskell-cafe >> > >> > >> >> >> >> -- >> Pasqualino "Titto" Assini, Ph.D. >> http://quicquid.org/ > > -- Pasqualino "Titto" Assini, Ph.D. http://quicquid.org/ From vandijk.roel at gmail.com Thu Jan 14 05:38:57 2010 From: vandijk.roel at gmail.com (Roel van Dijk) Date: Thu Jan 14 05:11:28 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <2518b95d1001140138ia2dafffw57f213dcff55b460@mail.gmail.com> References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> <4B4CF878.3070407@btinternet.com> <4B4E1E1F.9060501@btinternet.com> <2518b95d1001140138ia2dafffw57f213dcff55b460@mail.gmail.com> Message-ID: 2010/1/14 Evan Laforge : > Wow, that's kind of cute: > > {-# LANGUAGE UnicodeSyntax #-} > (?) = (*) > (?) = (/) > ?? ? ? ? = ? ? ? ? ? ? ?? > ?? = 123 That code snippet is also perfectly legal Haskell without the UnicodeSyntax language extension. You use UnicodeSyntax if you want to write code like this: {-# LANGUAGE UnicodeSyntax, ScopedTypeVariables #-} swap ? ? ? ?. (?, ?) ? (?, ?) swap = uncurry $ flip (,) > Oddly, if I change the order of these definitions I get syntax > errors. Very mysterious. Nice how it knows that ? is a symbol, > but I'm not sure how I'm supposed to name a type. I was a bit surprised that you could use ? as an operator since it is a punctuation character. Maybe there are some corner cases with fullwidth characters or with composition of characters. > Unicode identifiers are fun but this is a good point. The line has > to be somewhere, so it might as well be in the historical position > unless there are widely agreed on benefits to moving it. I have already crossed that line: http://hackage.haskell.org/package/base-unicode-symbols http://hackage.haskell.org/package/containers-unicode-symbols But I am aware that there is a point beyond which unicode symbols only make your code harder to understand. So I try to be conservative in my use of them. Still, there are a lot of useful and acceptable symbols which are not part of the historic ASCII set: ?, ?, ?, ?, ?, ? to name a few. From agocorona at gmail.com Thu Jan 14 05:50:25 2010 From: agocorona at gmail.com (Alberto G. Corona ) Date: Thu Jan 14 05:22:56 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: <81ea7d401001131628p1fa9a512if06ddff64ed106e4@mail.gmail.com> References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> <81ea7d401001131628p1fa9a512if06ddff64ed106e4@mail.gmail.com> Message-ID: 2010/1/14 Jinjing Wang > > > Hyena is especially tuned for streaming and that's exactly what hack > can't do (in practice). > Isn't possible to stream an (almost) infinite bytestring trough hack?. I ever trough that the laziness of haskell is a great advantage in Web applications. This is very important because the size of the block transferred vary widely. In my applications I don?t care whether I have to stream a hello world page or a video. The first block of my application goes trough the internet as soon as my procedure start without concern about if the processing is composed of a complicated chain of steps or not. And with no especial coding; Neither my web server interface nor my user responsiveness requirements force me to code iterations everywhere in my code. I know the chuncked mode in web server but I think that just this mode of web streaming is the right mode for serving lazy haskell applications. My question is why whatever performance advantage the iteratee may have, can not be coded under the clean interface of a lazy bytestring or whatever lazy stream. > > http://github.com/nfjinjing/hack-handler-hyena > > > -- > jinjing > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100114/2e647465/attachment.html From michael at snoyman.com Thu Jan 14 05:58:27 2010 From: michael at snoyman.com (Michael Snoyman) Date: Thu Jan 14 05:31:02 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> <81ea7d401001131628p1fa9a512if06ddff64ed106e4@mail.gmail.com> Message-ID: <29bf512f1001140258k54cf7d99s2c7c733dc3757b8f@mail.gmail.com> On Thu, Jan 14, 2010 at 12:50 PM, Alberto G. Corona wrote: > > > 2010/1/14 Jinjing Wang > > >> >> Hyena is especially tuned for streaming and that's exactly what hack >> can't do (in practice). >> > > Isn't possible to stream an (almost) infinite bytestring trough hack?. I > ever trough that the laziness of haskell is a great advantage in Web > applications. This is very important because the size of the block > transferred vary widely. In my applications I don?t care whether I have to > stream a hello world page or a video. The first block of my application > goes trough the internet as soon as my procedure start without concern > about if the processing is composed of a complicated chain of steps or not. > And with no especial coding; Neither my web server interface nor my user > responsiveness requirements force me to code iterations everywhere in my > code. I know the chuncked mode in web server but I think that just this > mode of web streaming is the right mode for serving lazy haskell > applications. > > My question is why whatever performance advantage the iteratee may have, > can not be coded under the clean interface of a lazy bytestring or whatever > lazy stream. > Well, for one thing, you'd need to use lazy IO to achieve your goal, which has some safety issues. As things get more and more complex, the requirements of lazy IO will continue to grow. This also has implications for number of open file handles and deterministic space usage. Given the fact that a lazy bytestring and easily be converted to an enumerator, I think it makes sense to start a new package using this approach. As a side point, would anyone be interested in having a central location for web-specific Haskell development discussions? I know we have the mailing list, but it's never used. I'm thinking more of a place to post articles and links to packages. In particular, I think it would be great to have a site with multiple sections (model, view, controller, authentication, authorization, etc) and articles, forums and packages specific for each. Also a great place to post what the community is missing. Michael >> http://github.com/nfjinjing/hack-handler-hyena >> >> >> -- >> jinjing >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100114/c4eeda1b/attachment.html From daniel.is.fischer at web.de Thu Jan 14 06:02:37 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Thu Jan 14 05:36:51 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001131233.23024.daniel.is.fischer@web.de> Message-ID: <201001141202.37294.daniel.is.fischer@web.de> Am Donnerstag 14 Januar 2010 08:25:48 schrieb Will Ness: > Daniel Fischer web.de> writes: > > Am Mittwoch 13 Januar 2010 10:43:42 schrieb Heinrich Apfelmus: > > > I wonder whether it's really the liveness of ?pair ?in > > > > > > ? mergeSP (a,b) pair > > > ? ? ?= let sm = spMerge b (fst pair) > > > ? ? ? ?in (a ++ fst sm, merge (snd sm) (snd pair)) > > > > > > that is responsible for the space leak, for chances are that > > > Sparud's technique applies and ?pair ?is properly disposed of. > > > Rather, it could be that we need the stronger property that forcing > > > the second component will evaluate the first to NF. > > > > I think that is responsible. At least that's how I understand the > > core: > > > > mergeSP (a,b) ~(c,d) = (a ++ bc, merge b' d) > > where > > (bc, b') = spMerge b c > > spMerge ... > > That is equivalent to > > first (a++) . second (`merge`d) $ spMerge b c > > and Daniel's fix is equivalent to > > first (a++) $ spMerge b c d > > > Now, when compiler sees the first variant, it probably treats spMerge as > opaque. I.e. although in reality spMerge only contributes to the > first "channel" while it is progressively instantiated, and (`merge`d) > will only be called upon when spMerge's final clause is reached, that is > (most likely) not known to the compiler at this stage. When looking at > just the first expression itself, it has to assume that spMerge may > contribute to both channels (parts of a pair) while working, and so > can't know _when_ /d/ will get called upon to contribute to the data, as > it is consumed finally at access. > > So /d/ is gotten hold of prematurely, _before_ going into spMerge. No, the problem is that d itself is gotten hold of too late, it is accessed only indirectly via the pair, so we keep an unnecessary reference to c via d. > > The second variant passes the responsibility for actually accessing its > inputs to spMerge itself, and _it_ is clear about needing /d/ only in > the very end. The second variant is clear about not needing the _pair_ anymore once spMerge is entered. Thus d doesn't reference c anymore. > > Just a theory. :) > > Does that make sense? > From malcolm.wallace at cs.york.ac.uk Thu Jan 14 06:14:29 2010 From: malcolm.wallace at cs.york.ac.uk (Malcolm Wallace) Date: Thu Jan 14 05:47:01 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <27156254.post@talk.nabble.com> References: <27139612.post@talk.nabble.com> <61E9624C-CB47-469C-BC29-2FA4A670D845@cs.york.ac.uk> <27156254.post@talk.nabble.com> Message-ID: > I still get the "undefined reference" errors. It is likely there is some combination of other mistakes as well then. Other responses have made suggestions of fixes you require in the C++ code for instance. You will need those as well. > I did eventually get ghc to compile > Main.hs by putting the -c and -cpp flags after "--make Main.hs". > > Then it produces a Main.o file which (even with +x permissions on my > Linux > box) will not run. I just get the message "cannot run binary file", > or some > such message. The file Main.o is just an object file, not a complete executable. It still needs to be linked against some other (Haskell or C/C++) object files and libraries, and the Haskell runtime system, to form an executable that can be run. ghc is capable of doing all the linking, e.g. ghc -o myProg Main.o slirm.o -package base -package foo However, if you are unsure of which Haskell packages are needed, it is wise to let ghc work out the dependencies for you, e.g. with ghc --make Main.hs slirm.o It cannot work out the C/C++ dependencies though, so every time you get "undefined reference" linking errors, you must discover which C code provides those symbols, and add its object file to the commandline by hand. Regards, Malcolm From daniel.is.fischer at web.de Thu Jan 14 06:16:15 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Thu Jan 14 05:50:27 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> <2518b95d1001140138ia2dafffw57f213dcff55b460@mail.gmail.com> Message-ID: <201001141216.16075.daniel.is.fischer@web.de> Am Donnerstag 14 Januar 2010 11:38:57 schrieb Roel van Dijk: > > I was a bit surprised that you could use ? as an operator since it is > a punctuation character. Maybe there are some corner cases with > fullwidth characters or with composition of characters. > Thus speaketh the report (http://haskell.org/onlinereport/lexemes.html): symbol -> ascSymbol | uniSymbol ascSymbol -> ! | # | $ | % | & | * | + | . | / | < | = | > | ? | @ | \ | ^ | | | - | ~ uniSymbol -> any Unicode symbol or punctuation Punctuation characters are legitimate for operators. From agocorona at gmail.com Thu Jan 14 06:20:18 2010 From: agocorona at gmail.com (Alberto G. Corona ) Date: Thu Jan 14 05:52:49 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: <29bf512f1001140258k54cf7d99s2c7c733dc3757b8f@mail.gmail.com> References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> <81ea7d401001131628p1fa9a512if06ddff64ed106e4@mail.gmail.com> <29bf512f1001140258k54cf7d99s2c7c733dc3757b8f@mail.gmail.com> Message-ID: 2010/1/14 Michael Snoyman > > > Well, for one thing, you'd need to use lazy IO to achieve your goal, which > has some safety issues. As things get more and more complex, the > requirements of lazy IO will continue to grow. This also has implications > for number of open file handles and deterministic space usage. Given the > fact that a lazy bytestring and easily be converted to an enumerator, I > think it makes sense to start a new package using this approach. > > These must be issues of base library developers, not application developpers. TIme ago a guy said me that using an standard library like malloc for memory allocation where not the optimum. And he was right. Fortunately things went in the "non-optimum" direction. You can make the application faster by using your own plumbing code instead of standard libraries provided that you have enough time and knowledge. Because I don?t have neither of the two :-) (nor have the people that read my code and maintain the application), I really like the laziness of haskell and the lazy bytestring interface. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100114/64875dcc/attachment.html From michael at snoyman.com Thu Jan 14 06:34:57 2010 From: michael at snoyman.com (Michael Snoyman) Date: Thu Jan 14 06:07:28 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> <81ea7d401001131628p1fa9a512if06ddff64ed106e4@mail.gmail.com> <29bf512f1001140258k54cf7d99s2c7c733dc3757b8f@mail.gmail.com> Message-ID: <29bf512f1001140334j6c61211dt22ed66ab88463884@mail.gmail.com> On Thu, Jan 14, 2010 at 1:20 PM, Alberto G. Corona wrote: > > > 2010/1/14 Michael Snoyman > > >> >> Well, for one thing, you'd need to use lazy IO to achieve your goal, which >> has some safety issues. As things get more and more complex, the >> requirements of lazy IO will continue to grow. This also has implications >> for number of open file handles and deterministic space usage. Given the >> fact that a lazy bytestring and easily be converted to an enumerator, I >> think it makes sense to start a new package using this approach. >> >> These must be issues of base library developers, not application > developpers. TIme ago a guy said me that using an standard library like > malloc for memory allocation where not the optimum. And he was right. > Fortunately things went in the "non-optimum" direction. You can make the > application faster by using your own plumbing code instead of standard > libraries provided that you have enough time and knowledge. Because I don?t > have neither of the two :-) (nor have the people that read my code and > maintain the application), I really like the laziness of haskell and the > lazy bytestring interface. > > Lazy bytestring interface is one thing; lazy IO is another. If you have pure code generating a lazy bytestring, Hack will work fine for you. Try this one however: take a 10MB YAML file, reformat it using something in the IO monad (for example, look up values from a database) and produce HTML output. Hack will *not* allow you to run in constant space without significant usageof unsafe functions. Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100114/f6b6dc2b/attachment.html From vandijk.roel at gmail.com Thu Jan 14 06:41:02 2010 From: vandijk.roel at gmail.com (Roel van Dijk) Date: Thu Jan 14 06:13:37 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <201001141216.16075.daniel.is.fischer@web.de> References: <4B4CE8CE.9060202@btinternet.com> <2518b95d1001140138ia2dafffw57f213dcff55b460@mail.gmail.com> <201001141216.16075.daniel.is.fischer@web.de> Message-ID: > Thus speaketh the report (http://haskell.org/onlinereport/lexemes.html): > > symbol ? -> ? ? ?ascSymbol | uniSymbol > ascSymbol ? ? ? -> ? ? ?! | # | $ | % | & | * | + | . | / | < | = | > | ? | @ > ? ? ? ?| ? ? ? \ | ^ | | | - | ~ > uniSymbol ? ? ? ?-> ? ? ?any Unicode symbol or punctuation > > Punctuation characters are legitimate for operators. Aha, didn't know that (or forgot it). Also kind of obvious when you consider that '.' and ':' are punctuation characters. I think it is time for an Obfuscated Haskell Contest :-) From colin at colina.demon.co.uk Thu Jan 14 06:47:29 2010 From: colin at colina.demon.co.uk (Colin Paul Adams) Date: Thu Jan 14 06:20:01 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: (Roel van Dijk's message of "Thu\, 14 Jan 2010 12\:41\:02 +0100") References: <4B4CE8CE.9060202@btinternet.com> <2518b95d1001140138ia2dafffw57f213dcff55b460@mail.gmail.com> <201001141216.16075.daniel.is.fischer@web.de> Message-ID: >>>>> "Roel" == Roel van Dijk writes: Roel> I think it is time for an Obfuscated Haskell Contest :-) Are you allowed to use obsolete scripts for your identifiers? :-) -- Colin Adams Preston Lancashire From vandijk.roel at gmail.com Thu Jan 14 07:07:30 2010 From: vandijk.roel at gmail.com (Roel van Dijk) Date: Thu Jan 14 06:40:01 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> <2518b95d1001140138ia2dafffw57f213dcff55b460@mail.gmail.com> <201001141216.16075.daniel.is.fischer@web.de> Message-ID: On Thu, Jan 14, 2010 at 12:47 PM, Colin Paul Adams wrote: >>>>>> "Roel" == Roel van Dijk writes: > > ? ?Roel> I think it is time for an Obfuscated Haskell Contest :-) > > Are you allowed to use obsolete scripts for your identifiers? :-) Sure, I'll consider bonus points if you write your program entirely in cuneiform. From ketil at malde.org Thu Jan 14 07:11:29 2010 From: ketil at malde.org (Ketil Malde) Date: Thu Jan 14 06:44:02 2010 Subject: [Haskell-cafe] Typed Configuration Files In-Reply-To: (Magnus Therning's message of "Fri, 8 Jan 2010 15:25:31 +0000") References: <0102AD94-4A7C-47F0-A412-748FF4850448@informatik.uni-kiel.de> Message-ID: <87y6k0yjgu.fsf@malde.org> Magnus Therning writes: > Seriously, cmdargs is *brilliant*. It's also magic (to me). On this list, I'm uncertain whether "brilliant" is a warning or a recommendation, but "magic" is clearly irresistible, so I had a go at using cmdargs. And I agree, it is really nice in quickly and succintly getting command parsing up and working, and in that it most Works As Expected (tm). Some snags I ran into, which may (or may not) serve to improve documentation, and which may (or may not) result in some gentle guidande as to preferred solutions rising to the surface: - The examples use 'def' a lot, and I mistakenly thought 'empty' would supply default values. Not so, replace 'def' with the default value and off you go. 'def' seems to be the "minimum" value for that particular type. - As I wanted a single file argument, I tried to use 'args' in combination with a parameter of type FilePath. Apparently 'args' wants [FilePath] and appends command line arguments to the default value. I used 'error "no file bla bla"' as the default value, and appending to this didn't do much good, as you can imagine. So: use [FilePath] and check the length manually. - CmdArgs helpfully provides default --help, --version as well as --quite and --verbose. For the two former, there's also a nice default implementation, but presumably the latter two are for use in the program proper. Unfortunately, I don't know how to get at their values. -k -- If I haven't seen further, it is by standing in the footprints of giants From michael at snoyman.com Thu Jan 14 07:14:12 2010 From: michael at snoyman.com (Michael Snoyman) Date: Thu Jan 14 06:46:44 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> <81ea7d401001131628p1fa9a512if06ddff64ed106e4@mail.gmail.com> <29bf512f1001140258k54cf7d99s2c7c733dc3757b8f@mail.gmail.com> <29bf512f1001140334j6c61211dt22ed66ab88463884@mail.gmail.com> Message-ID: <29bf512f1001140414h4a691722v5422113fc4bf72f2@mail.gmail.com> On Thu, Jan 14, 2010 at 1:58 PM, Alberto G. Corona wrote: > > > 2010/1/14 Michael Snoyman > >> >> >> On Thu, Jan 14, 2010 at 1:20 PM, Alberto G. Corona wrote: >> >>> >>> >>> 2010/1/14 Michael Snoyman >>> >>> >>>> >>>> Well, for one thing, you'd need to use lazy IO to achieve your goal, >>>> which has some safety issues. As things get more and more complex, the >>>> requirements of lazy IO will continue to grow. This also has implications >>>> for number of open file handles and deterministic space usage. Given the >>>> fact that a lazy bytestring and easily be converted to an enumerator, I >>>> think it makes sense to start a new package using this approach. >>>> >>>> These must be issues of base library developers, not application >>> developpers. TIme ago a guy said me that using an standard library like >>> malloc for memory allocation where not the optimum. And he was right. >>> Fortunately things went in the "non-optimum" direction. You can make the >>> application faster by using your own plumbing code instead of standard >>> libraries provided that you have enough time and knowledge. Because I don?t >>> have neither of the two :-) (nor have the people that read my code and >>> maintain the application), I really like the laziness of haskell and the >>> lazy bytestring interface. >>> >>> Lazy bytestring interface is one thing; lazy IO is another. If you have >> pure code generating a lazy bytestring, Hack will work fine for you. Try >> this one however: take a 10MB YAML file, reformat it using something in the >> IO monad (for example, look up values from a database) and produce HTML >> output. Hack will *not* allow you to run in constant space without >> significant usageof unsafe functions. >> >> Michael >> > > So there are memory leaks somewhere in the lazy bytestring IO libraries > (not in hack neither is an inherent problem in the lazy bytestring design, > the lazy IO concept or laziness as such). > > I did''t take a look, but surely a lazy bytestring IO read is composed of > an iteration of strict block reads that present a lazy bytestring interface. > It must be essentially the same than a iteratee IO, but with a higher level > interface (at least higher from my point of view). > > I like haskell for Internet applications because streaming is the essence > of communications and function call is the building block of programming. > Haskell deals with both with zero impedance because its laziness. Don't > break this!! > > > No, that's not the way it works. Lazy IO requires the use of unsafeInterleaveIO, which is, well, unsafe. Pure functions in Haskell can safely be lazy, not so with IO. If you don't believe me, you can read more about it here: http://okmij.org/ftp/Streams.html#iteratee Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100114/a364cb31/attachment.html From jaspervdj at gmail.com Thu Jan 14 07:21:52 2010 From: jaspervdj at gmail.com (Jasper Van der Jeugt) Date: Thu Jan 14 06:54:43 2010 Subject: [Haskell-cafe] ANN: hakyll-1.0 Message-ID: Hello, I have just released hakyll[1] 1.0. It is now available on hackage[2]. This is considered a first stable release (hence 1.0), and pretty it is functional. Hakyll is a Haskell library for generating static sites. It is written in a very configurable way and uses an xmonad-like DSL for configuration. Important changes: - Switched from the template library to a custom template system, because we needed some more flexibility, but not quite as much as something like HStringTemplate would give. - Switched from inconsistent String/ByteString usage to String only for the external API. - Added a $root system so it is easy to work with relative/absolute URL's. - Many bugfixes. - More documentation and a reference are online now. All feedback and questions are welcome. Kind regards, Jasper Van der Jeugt [1]: http://jaspervdj.be/hakyll [2]: http://hackage.haskell.org/package/hakyll From martijn at van.steenbergen.nl Thu Jan 14 07:40:50 2010 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Thu Jan 14 07:13:26 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> Message-ID: <4B4F10D2.4080902@van.steenbergen.nl> Niklas Broberg wrote: >> Haskell '98 apparently features 25 reserved words. (Not counting "forall" >> and "mdo" and so on, which AFAIK are not in Haskell '98.) > > 21 actually. case, class, data, default, deriving, do, else, if, > import, in, infix, infixl, infixr, instance, let, module, newtype, of, > then, type, where. There's also three special words that can still be > used as identifiers, so aren't reserved: as, qualified, hiding. Since you can define operators in Haskell, would it make sense to include '=', '--', ':', ',' etc. as "reserved names" since those can't be used as operator names? > Illegal binding of built-in syntax: : > Illegal binding of built-in syntax: (,) > parse error (possibly incorrect indentation) Martijn. From ozgurakgun at gmail.com Thu Jan 14 08:19:50 2010 From: ozgurakgun at gmail.com (Ozgur Akgun) Date: Thu Jan 14 07:52:22 2010 Subject: [Haskell-cafe] wildcards for type variables? In-Reply-To: <25DD26F9-93F2-4405-80E3-133AEBBE4649@informatik.uni-kiel.de> References: <2518b95d1001121529l60701d44y13ecf6614c82d1a6@mail.gmail.com> <4c88418c1001130254g58e11e37g1a4ec6cd1bad63e2@mail.gmail.com> <417DCDA9-6971-4F0A-AA5A-45C10DC5FCC3@ece.cmu.edu> <694519c51001130516i7cbb2535yc497efc3839db53c@mail.gmail.com> <43BCD272-1EB5-42AE-952F-66DF5268FAAD@informatik.uni-kiel.de> <2518b95d1001130954v470e510mbf6df19e99cd78e5@mail.gmail.com> <25DD26F9-93F2-4405-80E3-133AEBBE4649@informatik.uni-kiel.de> Message-ID: <7be1feae1001140519l58312420s8a91e93e9de3d7db@mail.gmail.com> Can someone give an example of a "reasonable" function that never uses one of its parameters, and justify the existence of that parameter in this case, please? Because for this example, f :: _unused -> A -> B f _ a = b I think what I'd do is to write the function f without that first parameter, and call the funcrtion accordingly. Best, 2010/1/13 Sebastian Fischer > > On Jan 13, 2010, at 6:54 PM, Evan Laforge wrote: > > It's not a big issue, but it seemed like a nice symmetry with pattern >> matching syntax. >> > > And I don't think it's a weird idea. The "Haskell dialect" Curry [1] > supports this syntax. Maybe the hurdle for Haskell is the competition with > more complex, conflicting proposals like [2]. > > Sebastian > > [1] http://curry-language.org > [2] http://hackage.haskell.org/trac/haskell-prime/wiki/PartialTypeSigs > > > -- > Underestimating the novelty of the future is a time-honored tradition. > (D.G.) > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- Ozgur Akgun -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100114/ccedd966/attachment.html From ivan.miljenovic at gmail.com Thu Jan 14 08:24:55 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Thu Jan 14 07:57:29 2010 Subject: [Haskell-cafe] wildcards for type variables? In-Reply-To: <7be1feae1001140519l58312420s8a91e93e9de3d7db@mail.gmail.com> (Ozgur Akgun's message of "Thu, 14 Jan 2010 13:19:50 +0000") References: <2518b95d1001121529l60701d44y13ecf6614c82d1a6@mail.gmail.com> <4c88418c1001130254g58e11e37g1a4ec6cd1bad63e2@mail.gmail.com> <417DCDA9-6971-4F0A-AA5A-45C10DC5FCC3@ece.cmu.edu> <694519c51001130516i7cbb2535yc497efc3839db53c@mail.gmail.com> <43BCD272-1EB5-42AE-952F-66DF5268FAAD@informatik.uni-kiel.de> <2518b95d1001130954v470e510mbf6df19e99cd78e5@mail.gmail.com> <25DD26F9-93F2-4405-80E3-133AEBBE4649@informatik.uni-kiel.de> <7be1feae1001140519l58312420s8a91e93e9de3d7db@mail.gmail.com> Message-ID: <878wc0ddjs.fsf@gmail.com> Ozgur Akgun writes: > Can someone give an example of a "reasonable" function that never uses one > of its parameters, and justify the existence of that parameter in this case, > please? I would like to bring your attention to the "const" function: ,---- | const :: a -> b -> a | const a _ = a `---- For justification, I often use this function when I need to provide a function that takes two arguments by the function I want to use only needs one; as such either const of (flip const) can let me absorb and ignore the unneeded argument. Satisfied? ;-) -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From ketil at malde.org Thu Jan 14 08:31:08 2010 From: ketil at malde.org (Ketil Malde) Date: Thu Jan 14 08:03:40 2010 Subject: [Haskell-cafe] wildcards for type variables? In-Reply-To: <7be1feae1001140519l58312420s8a91e93e9de3d7db@mail.gmail.com> (Ozgur Akgun's message of "Thu, 14 Jan 2010 13:19:50 +0000") References: <2518b95d1001121529l60701d44y13ecf6614c82d1a6@mail.gmail.com> <4c88418c1001130254g58e11e37g1a4ec6cd1bad63e2@mail.gmail.com> <417DCDA9-6971-4F0A-AA5A-45C10DC5FCC3@ece.cmu.edu> <694519c51001130516i7cbb2535yc497efc3839db53c@mail.gmail.com> <43BCD272-1EB5-42AE-952F-66DF5268FAAD@informatik.uni-kiel.de> <2518b95d1001130954v470e510mbf6df19e99cd78e5@mail.gmail.com> <25DD26F9-93F2-4405-80E3-133AEBBE4649@informatik.uni-kiel.de> <7be1feae1001140519l58312420s8a91e93e9de3d7db@mail.gmail.com> Message-ID: <87hbqoyfs3.fsf@malde.org> Ozgur Akgun writes: > Can someone give an example of a "reasonable" function that never uses one > of its parameters, and justify the existence of that parameter in this case, > please? E.g, 'const' is useful when you need something to feed to a higher order function: -- an element <=3 starts a new group *Main> groupBy (const (>3)) [1,2,3,4,1,5,6] [[1],[2],[3,4],[1,5,6]] Not the best example, perhaps, but the existence of const allows you to easily reuse existing framework. There's also 'par', although it's raison d'?tre is to have an effect on the second parameter, so it is arguably "using" it. -k -- If I haven't seen further, it is by standing in the footprints of giants From danr at student.chalmers.se Thu Jan 14 08:49:16 2010 From: danr at student.chalmers.se (=?ISO-8859-1?Q?Dan_Ros=E9n?=) Date: Thu Jan 14 08:22:09 2010 Subject: [Haskell-cafe] deleteBy type too restrictive Message-ID: <3defcb4e1001140549w3fc71633qaf0fcc9caef509ab@mail.gmail.com> Hello, I realized today that the type for deleteBy in Data.List is too restrictive. The code is: deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a] deleteBy _ _ [] = [] deleteBy eq x (y:ys) = if x `eq` y then ys else y : deleteBy eq x ys though the type deleteBy :: (b -> a -> Bool) -> b -> [a] -> [a] will do good as well. Is there a particular reason that the type has this restriction? Otherwise, where can I post a suggestion to have it untightened? Best regards, Dan Ros?n references: http://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Data-List.html#v:deleteBy http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/src/Data-List.html#deleteBy -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100114/f71dc470/attachment.html From adam_khan_rfc at hotmail.com Thu Jan 14 08:52:07 2010 From: adam_khan_rfc at hotmail.com (Ian675) Date: Thu Jan 14 08:24:37 2010 Subject: [Haskell-cafe] General Advice Needed .. Message-ID: <27161410.post@talk.nabble.com> Hi, First of all, sorry if its in the wrong section.. But I'm just having trouble getting to grips with Haskell. I have my functional programming exam tommorow and I'm struggling to understand any of this. We worked through the book The Craft Of Functional Programming and Im trying to work my way through it but still no luck.. I find it really hard to put down code onto paper. I can understand the code in the book I can do the simple simple functions like cube.. cube :: Int -> Int cube n = n*n*n But after that im lost :( Is there any general advice? Just keep reading the book till it drills into my big head? You can make sarcastic n00b jokes if you like.. I'm just a very frustrated student right now! -- View this message in context: http://old.nabble.com/General-Advice-Needed-..-tp27161410p27161410.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From niklas.broberg at gmail.com Thu Jan 14 08:54:00 2010 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Thu Jan 14 08:26:31 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4F10D2.4080902@van.steenbergen.nl> References: <4B4CE8CE.9060202@btinternet.com> <4B4F10D2.4080902@van.steenbergen.nl> Message-ID: > Since you can define operators in Haskell, would it make sense to include > '=', '--', ':', ',' etc. as "reserved names" since those can't be used as > operator names? They are indeed reserved operators in the report. 11 of those: .. : :: = \ | <- -> @ ~ => To be fair, _ is also a reserved identifier, so 22 and not 21 as I said previously. So a total of 33 reserved "names". /Niklas From korpios at korpios.com Thu Jan 14 09:16:40 2010 From: korpios at korpios.com (Tom Tobin) Date: Thu Jan 14 08:49:13 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> <4B4CF878.3070407@btinternet.com> <4B4E1E1F.9060501@btinternet.com> Message-ID: On Thu, Jan 14, 2010 at 12:45 AM, Colin Paul Adams wrote: >>>>>> "Tom" == Tom Tobin writes: > > ? ?Tom> readability. ?The ASCII characters are universal and easily > ? ?Tom> recognized > > No they are not. > My wife is Chinese. When she was learning pinyin as a child, she asked > her father for help with some homework. He replied that he didn't > understand them. I should have said "The ASCII characters are universal and easily recognized *for programmers*." Of course someone who hasn't come in contact with the Latin alphabet, let alone programming, isn't going to recognize ASCII ? but I think we'd have an amazingly hard time finding a programmer who wasn't familiar with it, regardless of their native language. From pseudo.meta at me.com Thu Jan 14 09:25:57 2010 From: pseudo.meta at me.com (Martin Coxall) Date: Thu Jan 14 08:58:40 2010 Subject: [Haskell-cafe] General Advice Needed .. In-Reply-To: <27161410.post@talk.nabble.com> References: <27161410.post@talk.nabble.com> Message-ID: > > But after that im lost :( > > Is there any general advice? Just keep reading the book till it drills into > my big head? Is it that you're having difficulty knowing how you'd solve certain classes of problems using Haskell? You're stuck in an imperative rut? The O'Reilly book "Real World Haskell" is very good for this, because as the name implies, it uses Haskell to solve actual engineering problems, rather than approach it from the theoretical angle. Martin From matthias.goergens at googlemail.com Thu Jan 14 09:29:18 2010 From: matthias.goergens at googlemail.com (=?ISO-8859-1?Q?Matthias_G=F6rgens?=) Date: Thu Jan 14 09:02:08 2010 Subject: [Haskell-cafe] General Advice Needed .. In-Reply-To: <27161410.post@talk.nabble.com> References: <27161410.post@talk.nabble.com> Message-ID: Hi, it may be a bit too late for you, but in general working through Smullyan's "To Mock a Mockingbird" (http://en.wikipedia.org/wiki/To_Mock_a_Mockingbird) may help in coming to grips with some of the theory (and intuition) behind functional programming. The "Real World Haskell" book is also a good choice, completely orthogonal to Smullyan's book, and much more practical. Matthias. From adam_khan_rfc at hotmail.com Thu Jan 14 09:38:26 2010 From: adam_khan_rfc at hotmail.com (Ian675) Date: Thu Jan 14 09:11:02 2010 Subject: [Haskell-cafe] General Advice Needed .. In-Reply-To: References: <27161410.post@talk.nabble.com> Message-ID: <27162216.post@talk.nabble.com> Pretty much yeah.. Im going through the book and things like : Define a function rangeProduct which when given natural numbers m and n, returns the product m*(m+1)*....*(n-1)*n I got the solution from my lecture notes but I still dont understand it.. rangeProduct :: Int -> Int -> Int rangeProduct m n | m > n = 0 | m == n = m | otherwise = m * rangeProduct (m+1) n Totally lost! Haha.. But thanks for the book suggestion, My exam is tommorow so I'm hoping theres an online version of this book that I can read through! And maybe by some divine miracle I'll understand it :-) Martin Coxall-2 wrote: > >> >> But after that im lost :( >> >> Is there any general advice? Just keep reading the book till it drills >> into >> my big head? > > Is it that you're having difficulty knowing how you'd solve certain > classes of problems using Haskell? You're stuck in an imperative rut? > > The O'Reilly book "Real World Haskell" is very good for this, because as > the name implies, it uses Haskell to solve actual engineering problems, > rather than approach it from the theoretical angle. > > Martin > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- View this message in context: http://old.nabble.com/General-Advice-Needed-..-tp27161410p27162216.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From adam_khan_rfc at hotmail.com Thu Jan 14 09:40:04 2010 From: adam_khan_rfc at hotmail.com (Ian675) Date: Thu Jan 14 09:12:34 2010 Subject: [Haskell-cafe] General Advice Needed .. In-Reply-To: References: <27161410.post@talk.nabble.com> Message-ID: <27162253.post@talk.nabble.com> It may be a bit late but I'll try anything Thankyou, I'll have a read :-) Matthias G?rgens-2 wrote: > > Hi, > > it may be a bit too late for you, but in general working through > Smullyan's "To Mock a Mockingbird" > (http://en.wikipedia.org/wiki/To_Mock_a_Mockingbird) may help in > coming to grips with some of the theory (and intuition) behind > functional programming. > > The "Real World Haskell" book is also a good choice, completely > orthogonal to Smullyan's book, and much more practical. > > Matthias. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- View this message in context: http://old.nabble.com/General-Advice-Needed-..-tp27161410p27162253.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From korpios at korpios.com Thu Jan 14 09:41:00 2010 From: korpios at korpios.com (Tom Tobin) Date: Thu Jan 14 09:13:32 2010 Subject: [Haskell-cafe] General Advice Needed .. In-Reply-To: <27161410.post@talk.nabble.com> References: <27161410.post@talk.nabble.com> Message-ID: On Thu, Jan 14, 2010 at 7:52 AM, Ian675 wrote: > Is there any general advice? Just keep reading the book till it drills into > my big head? Also don't be afraid to ask specific questions on the Beginners mailing list; while Cafe is a good general resource, Beginners is specifically there for those still learning the language (like me). :-) From matthias.goergens at googlemail.com Thu Jan 14 09:42:06 2010 From: matthias.goergens at googlemail.com (=?ISO-8859-1?Q?Matthias_G=F6rgens?=) Date: Thu Jan 14 09:14:56 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> Message-ID: > All Lisps have "special forms" which are evaluated uniquely and differently from function application and are therefore reserved words by another name. For example, Clojure has def, if, do, let, var, quote, fn, loop, recur, throw, try, monitor-enter, monitor-exit, dot, new and set!. Yes, but the special forms are not distinguishable from user defined macros --- and some Lisp-implemantations special forms are another implementations macros. E.g. you can choose to make `if' a macro that expands to `cond' or vice versa. I do not know whether you are allowed to shadow the name of special-forms. > If you count reserved tokens, I guess Lisp reserves parentheses and whitespace? Not if you are using Common Lisp. There you can install reader-macros that act on characters in the input-stream. (Most macros act on stuff in the already parsed syntrax tree.) Forth is also a remarkably flexible language in this regard. Matthias. From pseudo.meta at me.com Thu Jan 14 09:46:37 2010 From: pseudo.meta at me.com (Martin Coxall) Date: Thu Jan 14 09:21:42 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> Message-ID: On 14 Jan 2010, at 14:42, Matthias G?rgens wrote: >> All Lisps have "special forms" which are evaluated uniquely and differently from function application and are therefore reserved words by another name. For example, Clojure has def, if, do, let, var, quote, fn, loop, recur, throw, try, monitor-enter, monitor-exit, dot, new and set!. > > Yes, but the special forms are not distinguishable from user defined > macros --- and some Lisp-implemantations special forms are another > implementations macros. E.g. you can choose to make `if' a macro that > expands to `cond' or vice versa. I do not know whether you are > allowed to shadow the name of special-forms. > Clojure's a lot more 'syntaxy' than most Lisps. It has literals for large classes of entities that get represented as lists in most other Lisps. Which I guess is clearly a pragmatic design decision: be as syntax-heavy as is reasonably practicable without sacrificing homoiconicity and ending up like Dylan. Martin From ketil at malde.org Thu Jan 14 09:51:34 2010 From: ketil at malde.org (Ketil Malde) Date: Thu Jan 14 09:24:05 2010 Subject: [Haskell-cafe] Typed Configuration Files In-Reply-To: <87y6k0yjgu.fsf@malde.org> (Ketil Malde's message of "Thu, 14 Jan 2010 13:11:29 +0100") References: <0102AD94-4A7C-47F0-A412-748FF4850448@informatik.uni-kiel.de> <87y6k0yjgu.fsf@malde.org> Message-ID: <874omoyc21.fsf@malde.org> Ketil Malde writes: > - CmdArgs helpfully provides default --help, --version as well as > --quite and --verbose. For the two former, there's also a nice > default implementation, but presumably the latter two are for use in > the program proper. Unfortunately, I don't know how to get at their > values. I couldn't find it in an example, but apparently it is done through global functions 'isLoud', 'isNormal', and 'isQuiet'. -k -- If I haven't seen further, it is by standing in the footprints of giants From schlepptop at henning-thielemann.de Thu Jan 14 09:53:51 2010 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Thu Jan 14 09:25:48 2010 Subject: [Haskell-cafe] Re: looking for origin of quote on preprocessors and language design In-Reply-To: <1263419699.9546.4.camel@picard> References: <4B45D443.8020709@imn.htwk-leipzig.de> <1262870296.6326.116.camel@picard> <4B4E3E3A.9020609@henning-thielemann.de> <1263419699.9546.4.camel@picard> Message-ID: <4B4F2FFF.8090607@henning-thielemann.de> Maciej Piechotka schrieb: > > Hmm. May I ask how to do for example something depending on POSIX or > WinAPI? I am sorry but I cannot see how any of the above problems could > be solved. Sure, I choose different Hs-Source-Dirs for the different platforms. Multiple Hs-Source-Dirs are merged. Example: http://hackage.haskell.org/packages/archive/sox/0.1/sox.cabal From steve at fenestra.com Thu Jan 14 09:53:33 2010 From: steve at fenestra.com (Steve Schafer) Date: Thu Jan 14 09:26:03 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> Message-ID: <4jbuk55e7puamcbbm1bpjm5r5dlncvqfvt@4ax.com> On Thu, 14 Jan 2010 14:42:06 +0000, you wrote: >> All Lisps have "special forms" which are evaluated uniquely and differently from function application and are therefore reserved words by another name. For example, Clojure has def, if, do, let, var, quote, fn, loop, recur, throw, try, monitor-enter, monitor-exit, dot, new and set!. > >Yes, but the special forms are not distinguishable from user defined >macros --- and some Lisp-implemantations special forms are another >implementations macros. E.g. you can choose to make `if' a macro that >expands to `cond' or vice versa. I do not know whether you are >allowed to shadow the name of special-forms. You can in Scheme; syntactic-keyword bindings can shadow variable bindings, and vice versa: The following is given as an example in R5RS: (let-syntax ((when (syntax-rules () ((when test stmt1 stmt2 ...) (if test (begin stmt1 stmt2 ...)))))) (let ((if #t)) (when if (set! if 'now)) if)) Evaluating the above returns "now." Steve Schafer Fenestra Technologies Corp. http://www.fenestra.com/ From hjgtuyl at chello.nl Thu Jan 14 10:20:55 2010 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Thu Jan 14 09:53:25 2010 Subject: [Haskell-cafe] Quick, somebody do something! Message-ID: Haskell has dropped out of the top 50 at Tiobe [1]; how could this hapen? Let's start selling mobile phones that can only be programmed in Haskell :-) [1] http://www.tiobe.com/content/paperinfo/tpci/index.html -- Met vriendelijke groet, Henk-Jan van Tuyl -- http://Van.Tuyl.eu/ http://members.chello.nl/hjgtuyl/tourdemonad.html -- From deniz.a.m.dogan at gmail.com Thu Jan 14 10:38:12 2010 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Thu Jan 14 10:11:03 2010 Subject: [Haskell-cafe] Quick, somebody do something! In-Reply-To: References: Message-ID: <7b501d5c1001140738r7a358735v828520dc5c83e8be@mail.gmail.com> 2010/1/14 Henk-Jan van Tuyl : > > Haskell has dropped out of the top 50 at Tiobe [1]; how could this hapen? > Let's start selling mobile phones that can only be programmed in Haskell :-) > > > [1] http://www.tiobe.com/content/paperinfo/tpci/index.html > > > -- > Met vriendelijke groet, > Henk-Jan van Tuyl > > So then we lived up to Peyton-Jones' Haskell slogan: avoid success at all costs. -- Deniz Dogan From jeremy at n-heptane.com Thu Jan 14 10:42:05 2010 From: jeremy at n-heptane.com (Jeremy Shaw) Date: Thu Jan 14 10:14:43 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> Message-ID: Hello, Happstack is currently bundled with it's own lazy I/O based HTTP backend. Ideally, we would like to split that out, and allow happstack to be used with that backend, hyena, or other options. A primary using for using hyena would be for the benefits of predictability and constant space usage that iterators bring. People do actually running into the issues that come with lazy I/O, such as running out of file descriptors, etc. So, I feel like I would want to stick with using iterators the whole way when using hyena, and not convert back to a lazy ByteString? Happstack now includes support for sendfile(). This is done by adding another constructor to the Response type: (line 94): http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/HTTP/Types.hs Then here on line 197, we match on that case and use sendfile to send the data: http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/HTTP/Handler.hs This makes it difficult for use to be compatible with WAI. We can write a wrapper that converts the sendfile case to use lazy bytestrings instead, but then we lose the advantages of using sendfile. I wonder if the 'Response' portion of WAI should support all three currently used methods: - lazy I/O - Enumerator - sendFile I haven't really thought about how that would work.. hyena currently includes a Network.WAI which uses ByteString: http://hackage.haskell.org/packages/archive/hyena/0.1/doc/html/Network-Wai.html gotta run, sorry about any typos! - jeremy On Jan 13, 2010, at 8:46 AM, Michael Snoyman wrote: > Hi, > > I recently read (again) the wiki page on a web application > interface[1] for Haskell. It seems like this basically works out to > Hack[2], but using an enumerator instead of lazy bytestring in the > response type. Is anyone working on implementing this? If not, I > would like to create the package, though I wouldn't mind some > community input on some design decisions: > > * Hack has been fairly well-tested in the past year and I think it > provides the features that people want. Therefore, I would want to > model the Environment variable for WAI from Hack. I *could* just > import Hack in WAI and use the exact same Environment data type. > Thoughts? > > * If using a different data type for Environment, should I replace > the String parts with ByteStrings? On the one hand, ByteStrings are > the "correct" data type since the HTTP protocol does not specify a > character encoding; on the other hand, Strings are easier to deal > with. > > * It's simple to write a function to convert between a lazy > bytestring and an enumerator, meaning it would be very easy to write > conversion functions between Hack and WAI applications. This would > make it simpler for people to use either backend. > > If someone else is already working on WAI, please let me know, I > don't want to have duplicate implementations. The idea here is to > consolidate, not split the community. I have a few Hack handlers > (simpleserver, cgi, fastcgi) that I would happily convert to WAI > handlers as well. > > Michael > > [1] http://www.haskell.org/haskellwiki/WebApplicationInterface > [2] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hack > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From dnmehay at gmail.com Thu Jan 14 10:47:24 2010 From: dnmehay at gmail.com (DNM) Date: Thu Jan 14 10:19:54 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <27139612.post@talk.nabble.com> References: <27139612.post@talk.nabble.com> Message-ID: <27163389.post@talk.nabble.com> OK. Before anyone expends any e-ink replying to my reply below -- the one where I demonstrate that I don't understand what -c, -cpp mean to 'ghc' (not that you can blame me, since there isn't any documentation in the 'ghc' man page) -- I see why the Main.o file doesn't run. It's an object file, not an executable (not being from the C/C++ world, being a distinction I did not have at the forefront of my mind). Anyhow, still no dice. Even when cleaning up my Haskell code, I can't get this to compile. --D.N. DNM wrote: > > Note: I'm relatively new to Haskell, and my knowledge of C and C++ is > basically pretty > minimal -- I can read, modify and compile C/C++ programs (usually). > > I'm trying to interface with some C++ code by writing a little bit of C > code that uses that C++ code, > and I'm getting "undefined reference" errors when I try to 'ghc --make' a > client application to test > it. > > Actually, I'm modifying Nitin Madnani's (freely available) Python SRILM > toolkit wrapper code. (SRILM, > by the bye, is a C++-based toolkit for training and using statistical > n-gram language models. I was > surprised that no-one has tried to do this yet -- or at least not that > they have shared with the rest of us.) > Anyhow, I've verified that my modification of Madnani's C code works by > compiling it and running it > through a SWIG interface in Madnani's Python code, so I'm pretty confident > the C client of SRILM > is solid. The culprit is either my Haskell FFI code or the client of > that code. > > Without cooking up a microcosm of my problem with little Foo's and Bar's, > I'll just give my > actual C, header file and Haskell code (or at least the relevant bits), > and then the error. > > ------------- srilm.h ---------------- > #ifdef __cplusplus > extern "C" { > #else > typedef struct Ngram Ngram; /* dummy type to stand in for class */ > #endif > > Ngram* bldLM(int order, const char* filename); > void deleteLM(Ngram* ngram); > float getSeqProb(Ngram* ngram, const char* ngramstr, unsigned order, > unsigned length); > > #ifdef __cplusplus > } > #endif > ----------------------------------------- > > ------------- srilm.c ---------------- > // Initialize and read in the ngram model > Ngram* bldLM(int order, const char* filename) { ... } > ... > // Delete the ngram model > void deleteLM(Ngram* ngram) { > delete srilm_vocab; > delete ngram; > } > ... > // Get the ngram probability of the given string, given n-gram order > 'order' and string length > // 'length'. > float getSeqProb(Ngram* ngram, const char* ngramstr, unsigned order, > unsigned length) { ...} > ----------------------------- > > Next, the Haskell FFI specs and code that marshals data between Haskell > and C. > > ---------------- LM.hs ---------------------- > {-# INCLUDE "srilm.h" #-} > {-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-} > ... module decl's, imports, etc. > {- | A dummy placeholder for SRILM n-gram model thingies. -} > data Ngram > > data NGModel = NGModel {ng :: !(ForeignPtr Ngram)} > > foreign import ccall "srilm.h bldLM" > c_blm :: CInt -> CString -> Ptr Ngram > > foreign import ccall "srilm.h deleteLM" > c_dlm :: FunPtr ((Ptr Ngram) -> IO ()) > > foreign import ccall "srilm.h getSeqProb" > c_ngramProb :: Ptr Ngram -> CString -> CUInt -> CUInt -> CFloat > > {- > | Given an n-gram model, an Int representing the n-gram order > and a list of strings (word sequence), compute the > n-gram probability of the sequence. > -} > scoreSequence :: NGModel -> Int -> [String] -> Float > scoreSequence ngram order seq = > unsafePerformIO $ do > stringSeq <- newCString (unwords seq) > let sc = c_ngramProb (unsafeForeignPtrToPtr $ ng ngram) stringSeq > (fromIntegral order) (fromIntegral $ length seq) > return (realToFrac sc) > ... > buildLM :: Int -> String -> NGModel > buildLM order fname = > NGModel $ > unsafePerformIO $ do > cFName <- newCString fname > let ng = c_blm (fromIntegral order) cFName > return $ unsafePerformIO $ newForeignPtr c_dlm ng > -------------------------------------------- > > Now, I've defined a simple app that tries to use this: > > ------------------- Main.hs ------------------------- > module Main where > import SRILM.LM(scoreSequence, buildLM) > > main :: IO () > main = do > let lm = buildLM 5 "eng.kn.5g.lm" > putStrLn $ show $ scoreSequence lm 5 ["the", "prime", "minister", > "gave", "a", "speech", "."] > ----------------------------------------------------------- > > But when I try to compile it (after having successfully compiled the C > code with g++), I get: > > $ ghc --make Main.hs > Linking Main ... > LM.o: In function `r18k_info': > (.text+0x122): undefined reference to `bldLM' > LM.o: In function `r18m_info': > (.text+0x14e): undefined reference to `deleteLM' > LM.o: In function `r18o_info': > (.text+0x28b): undefined reference to `getSeqProb' > collect2: ld returned 1 exit status > > Any ideas? > > Note that I'm not confident that everything on the Haskell side is > correct, but it seems > that ghc can't find my C client of SRILM. As I said, I've compiled this > code > using g++, and it works when I interface with it through Python. > > Sorry for the long-windedness, but I figured I'd err on the side of TMI so > that I don't > have to keep posting more and more code snippets and error messages. Any > help > is greatly appreciated. (And I'd be happy to share my interface to SRILM > to anyone > who's interested, once I get it working -- and I get permission from Nitin > Madnani to > distribute a modified version of his code.) > > Thanks, > Dennis > -- View this message in context: http://old.nabble.com/FFI%2C-C-C%2B%2B-and-undefined-references-tp27139612p27163389.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From hjgtuyl at chello.nl Thu Jan 14 11:01:56 2010 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Thu Jan 14 10:34:28 2010 Subject: [Haskell-cafe] General Advice Needed .. In-Reply-To: <27162216.post@talk.nabble.com> References: <27161410.post@talk.nabble.com> <27162216.post@talk.nabble.com> Message-ID: On Thu, 14 Jan 2010 15:38:26 +0100, Ian675 wrote: > > Pretty much yeah.. Im going through the book and things like : > > Define a function rangeProduct which when given natural numbers m and n, > returns the product m*(m+1)*....*(n-1)*n > > I got the solution from my lecture notes but I still dont understand it.. > > rangeProduct :: Int -> Int -> Int > rangeProduct m n > | m > n = 0 > | m == n = m > | otherwise = m * rangeProduct (m+1) n > I'll try to give a clear explanation of this function: > rangeProduct :: Int -> Int -> Int > rangeProduct m n A function is defined with parameters m and n, both Int; the result of the function is also an Int > | m > n = 0 If m > n, the result is 0; the rest of the function definition will be skipped > | m == n = m If m is not larger then n, evalution continues here; if m == n, the result of the function is m > | otherwise = m * rangeProduct (m+1) n If previous predicates were False, this branch is evaluated ("otherwise" is always True); the function calls itself with (m+1) as first parameter The boolean expressions in this function are called "guards"; the right hand side after the first guard that evaluates to True, will give the result of the function. Regards, Henk-Jan van Tuyl -- http://Van.Tuyl.eu/ http://members.chello.nl/hjgtuyl/tourdemonad.html -- From stephen.tetley at gmail.com Thu Jan 14 11:28:48 2010 From: stephen.tetley at gmail.com (Stephen Tetley) Date: Thu Jan 14 11:01:20 2010 Subject: [Haskell-cafe] General Advice Needed .. In-Reply-To: <27162216.post@talk.nabble.com> References: <27161410.post@talk.nabble.com> <27162216.post@talk.nabble.com> Message-ID: <5fdc56d71001140828r63228a17s1c9869a547b3c41@mail.gmail.com> Hello Does you find this version easier to understand? rangeProduct :: Int -> Int -> Int rangeProduct m n = if m > n then 0 else if m == n then m else m * rangeProduct (m+1) n I would suspect the main point of the example is to make you think recursively - note how rangeProduct is called from within its own definition (on the last line of code). Before it, there are two stopping conditions that will halt recursion "if m > n " or "if m == n" - stopping conditions are crucial for recursive thinking and programming - without them you will recur endlessly and never produce an answer. If you exam is 'on paper' - that's to say code you can have some syntax errors because it isn't actually run - you want to be demonstrating that you can think recursively. Good luck Stephen From michael at snoyman.com Thu Jan 14 11:32:26 2010 From: michael at snoyman.com (Michael Snoyman) Date: Thu Jan 14 11:05:02 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> Message-ID: <29bf512f1001140832h346cdb6cs1b3dbf985b1abe16@mail.gmail.com> On Thu, Jan 14, 2010 at 5:42 PM, Jeremy Shaw wrote: > Hello, > > Happstack is currently bundled with it's own lazy I/O based HTTP backend. > Ideally, we would like to split that out, and allow happstack to be used > with that backend, hyena, or other options. > > A primary using for using hyena would be for the benefits of predictability > and constant space usage that iterators bring. People do actually running > into the issues that come with lazy I/O, such as running out of file > descriptors, etc. So, I feel like I would want to stick with using > iterators the whole way when using hyena, and not convert back to a lazy > ByteString? > > Happstack now includes support for sendfile(). This is done by adding > another constructor to the Response type: > > (line 94): > > http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/HTTP/Types.hs > > Then here on line 197, we match on that case and use sendfile to send the > data: > > > http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/HTTP/Handler.hs > > This makes it difficult for use to be compatible with WAI. We can write a > wrapper that converts the sendfile case to use lazy bytestrings instead, but > then we lose the advantages of using sendfile. > > I wonder if the 'Response' portion of WAI should support all three > currently used methods: > - lazy I/O > - Enumerator > - sendFile > > I haven't really thought about how that would work.. > > hyena currently includes a Network.WAI which uses ByteString: > > > http://hackage.haskell.org/packages/archive/hyena/0.1/doc/html/Network-Wai.html > > gotta run, sorry about any typos! > - jeremy > > Firstly, thanks for the Heyna Network.Wai link, I wasn't aware of it. Definitely something to take into consideration here. As for your proposal of three methods, I'm not sure if it's necesary. I understand that we would want sendfile for speedy serving of files straight from the filesystem, but it's fairly straight-forward to convert a lazy bytestring into an enumerator, and I don't think we get a performance penalty for doing so (if there's a benchmark otherwise, I'd be happy to see it). So if this were a changeset to Network.Wai in Hyena, I would see redefining Application as: type Application = Environment -> IO (Int, ByteString, Headers, Either FilePath Enumerator) Implementations that wish to go for efficiency could use sendfile directly. We could even include a helper function for making this easy. We could also provide a lazy bytestring -> enumerator function while we're at it (although those features might be more appropriate for a wai-helpers package, I'm not certain). I think it would be great if we could get Happstack involved in the WAI project. Michael > > > On Jan 13, 2010, at 8:46 AM, Michael Snoyman wrote: > > Hi, >> >> I recently read (again) the wiki page on a web application interface[1] >> for Haskell. It seems like this basically works out to Hack[2], but using an >> enumerator instead of lazy bytestring in the response type. Is anyone >> working on implementing this? If not, I would like to create the package, >> though I wouldn't mind some community input on some design decisions: >> >> * Hack has been fairly well-tested in the past year and I think it >> provides the features that people want. Therefore, I would want to model the >> Environment variable for WAI from Hack. I *could* just import Hack in WAI >> and use the exact same Environment data type. Thoughts? >> >> * If using a different data type for Environment, should I replace the >> String parts with ByteStrings? On the one hand, ByteStrings are the >> "correct" data type since the HTTP protocol does not specify a character >> encoding; on the other hand, Strings are easier to deal with. >> >> * It's simple to write a function to convert between a lazy bytestring and >> an enumerator, meaning it would be very easy to write conversion functions >> between Hack and WAI applications. This would make it simpler for people to >> use either backend. >> >> If someone else is already working on WAI, please let me know, I don't >> want to have duplicate implementations. The idea here is to consolidate, not >> split the community. I have a few Hack handlers (simpleserver, cgi, fastcgi) >> that I would happily convert to WAI handlers as well. >> >> Michael >> >> [1] http://www.haskell.org/haskellwiki/WebApplicationInterface >> [2] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hack >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100114/dc97327a/attachment.html From qdunkan at gmail.com Thu Jan 14 11:52:36 2010 From: qdunkan at gmail.com (Evan Laforge) Date: Thu Jan 14 11:25:08 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> <201001122326.31495.daniel.is.fischer@web.de> <4B4CF878.3070407@btinternet.com> <4B4E1E1F.9060501@btinternet.com> <2518b95d1001140138ia2dafffw57f213dcff55b460@mail.gmail.com> Message-ID: <2518b95d1001140852q47b83bc1pd353d16306760019@mail.gmail.com> >> Unicode identifiers are fun but this is a good point. ?The line has >> to be somewhere, so it might as well be in the historical position >> unless there are widely agreed on benefits to moving it. > > I have already crossed that line: Ha, well haskell programmers wouldn't be haskell programmers if they weren't already a bunch of line crossers :) From adam_khan_rfc at hotmail.com Thu Jan 14 11:53:00 2010 From: adam_khan_rfc at hotmail.com (Ian675) Date: Thu Jan 14 11:25:31 2010 Subject: [Haskell-cafe] General Advice Needed .. In-Reply-To: References: <27161410.post@talk.nabble.com> <27162216.post@talk.nabble.com> Message-ID: <27164433.post@talk.nabble.com> thankyou.. that made more sense to me :) What im doing now is.. Im still working through the "Craft of Functional Programming" book but I've found a site that has solutions to some of the excercise questions. So i'm noting them down and trying to make sense of them Is that a good approach? Henk-Jan van Tuyl wrote: > > On Thu, 14 Jan 2010 15:38:26 +0100, Ian675 > wrote: > >> >> Pretty much yeah.. Im going through the book and things like : >> >> Define a function rangeProduct which when given natural numbers m and n, >> returns the product m*(m+1)*....*(n-1)*n >> >> I got the solution from my lecture notes but I still dont understand it.. >> >> rangeProduct :: Int -> Int -> Int >> rangeProduct m n >> | m > n = 0 >> | m == n = m >> | otherwise = m * rangeProduct (m+1) n >> > > I'll try to give a clear explanation of this function: > >> rangeProduct :: Int -> Int -> Int >> rangeProduct m n > A function is defined with parameters m and n, both Int; the result of the > function is also an Int > >> | m > n = 0 > If m > n, the result is 0; the rest of the function definition will be > skipped > >> | m == n = m > If m is not larger then n, evalution continues here; if m == n, the result > of the function is m > > >> | otherwise = m * rangeProduct (m+1) n > If previous predicates were False, this branch is evaluated ("otherwise" > is always True); the function calls itself with (m+1) as first parameter > > The boolean expressions in this function are called "guards"; the right > hand side after the first guard that evaluates to True, will give the > result of the function. > > Regards, > Henk-Jan van Tuyl > > > -- > http://Van.Tuyl.eu/ > http://members.chello.nl/hjgtuyl/tourdemonad.html > -- > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- View this message in context: http://old.nabble.com/General-Advice-Needed-..-tp27161410p27164433.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From ck_kashyap at yahoo.com Thu Jan 14 12:09:30 2010 From: ck_kashyap at yahoo.com (CK Kashyap) Date: Thu Jan 14 11:42:01 2010 Subject: [Haskell-cafe] Haskell implementation of ideas from StandardML as a Metaprogramming language Message-ID: <897996.94253.qm@web112513.mail.gq1.yahoo.com> Hi All, I was just going over the paper titled - "Standard ML as a meta programming language" by Samuel Kamin - It has a few ideas of generating C++ code from ML. The first one being generating C++ top down parser. I wanted to try out the sample in Haskell - I was wondering if anyone's already done that - I could just look at that implementation for reference. Regards, Kashyap From jason.dusek at gmail.com Thu Jan 14 12:14:55 2010 From: jason.dusek at gmail.com (Jason Dusek) Date: Thu Jan 14 11:47:25 2010 Subject: [Haskell-cafe] Re: looking for origin of quote on preprocessors and language design In-Reply-To: <1262870296.6326.116.camel@picard> References: <4B45D443.8020709@imn.htwk-leipzig.de> <1262870296.6326.116.camel@picard> Message-ID: <42784f261001140914y6febedbbxd26dcd51beafd18b@mail.gmail.com> 2010/01/07 Maciej Piechotka : > On Thu, 2010-01-07 at 13:32 +0100, Johannes Waldmann wrote: > > Dear all, > > > > It's not exactly Haskell-specific, but ... > > I am trying to track down the origin of the proverb > > > > "the existence (or: need for) a preprocessor > > shows omissions in (the design of) a language." > > > > I like to think that in Haskell, we don't need > > preprocessors since we can manipulate programs > > programmatically, because they are data. > > > > In other words, a preprocessor realizes higher order > > functions, and you only need this if your base language > > is first-order. > > > > Yes, that's vastly simplified, and it does not cover > > all cases, what about generic programming > > (but this can be done via Data.Data) > > and alex/happy (but we have parsec) etc etc. > > Not quite. While I agree that "the *frequent* need for a preprocessor > shows omissions in (the design of) a language." it is not necessary the > case. Preprocessor may be useful if: > > - there is a new beatyful feature in newer version of compiler but you > still want to have backward compatibility. > - there are compiler or platform dependant elements. For example if you > write a driver in Haskell you may want to share code as much as possible > but you need to know 1) the size of registers and 2) the platform you're > writing as Windows have quite different API then Linux or BSD. > - You need to enable/disable features at build-time. It is not frequent > at closed-source system but it is frequent on OpenSource systems. For > example I might need to have minimal program for embedded system but > with full feature set it likly conquer the desktops > > in such cases it is easier/more efficient to just write > #if (defined WINDOWS && BITS >= 64) || defined ALSA > ... > #elseif GHC_VERSION >= 061004 > > #endif I think that pre-processing is an inevitable result of poor support for DSLs. When looking into embedded programming for the AVR family recently, I was surprised at the degree to which programmers rely on C macros; they're the only way they can get the expressiveness they want at a price they can accept. Haskell has strong support for embedded DSLs and the abstraction penalty is low so it's not hard to get away with just writing Haskell for things. Just the same, there are some aspects of Haskell syntax that make it horribly awkward for some applications. I would like to write all my shell scripts in Haskell -- especially those scripts that drive SSH connections or multiple external processes -- but the line noise penalty is pretty high right now. Using quasi-quotation -- a kind of pre-processor -- with a more shell-like set of shortcuts might be just the right thing. It's nice to reflect on the fact that Haskell offers a lot of flexibility for program transformation but is relatively safe from the incomprehensibility that results from the use of monkey patching in Ruby or macros in general. -- Jason Dusek From matthias.goergens at googlemail.com Thu Jan 14 12:27:46 2010 From: matthias.goergens at googlemail.com (=?ISO-8859-1?Q?Matthias_G=F6rgens?=) Date: Thu Jan 14 12:00:35 2010 Subject: [Haskell-cafe] Typed Configuration Files In-Reply-To: <0102AD94-4A7C-47F0-A412-748FF4850448@informatik.uni-kiel.de> References: <0102AD94-4A7C-47F0-A412-748FF4850448@informatik.uni-kiel.de> Message-ID: Hi Sebastian, You might also want to look at how xmonad handles it's configuration. Basically the configuration file is the main-file that produces the executable and takes in the rest of xmonad as a library. This works out quite well, but you need a compiler to update the configuration. Matthias. From ndmitchell at gmail.com Thu Jan 14 12:39:21 2010 From: ndmitchell at gmail.com (Neil Mitchell) Date: Thu Jan 14 12:11:52 2010 Subject: [Haskell-cafe] Typed Configuration Files In-Reply-To: <87y6k0yjgu.fsf@malde.org> References: <0102AD94-4A7C-47F0-A412-748FF4850448@informatik.uni-kiel.de> <87y6k0yjgu.fsf@malde.org> Message-ID: <404396ef1001140939m6e8dbf5wf90cc0e8596362ac@mail.gmail.com> Hi The CmdArgs manual might help: http://community.haskell.org/~ndm/darcs/cmdargs/cmdargs.htm >> Seriously, cmdargs is *brilliant*. ?It's also magic (to me). > > On this list, I'm uncertain whether "brilliant" is a warning or a > recommendation, but "magic" is clearly irresistible, so I had a go at > using cmdargs. I'd describe cmdargs as referentially impure, but really concise. > And I agree, it is really nice in quickly and succintly getting command > parsing up and working, and in that it most Works As Expected (tm). > Some snags I ran into, which may (or may not) serve to improve > documentation, and which may (or may not) result in some gentle guidande > as to preferred solutions rising to the surface: > > - The examples use 'def' a lot, and I mistakenly thought 'empty' would > ?supply default values. Not so, replace 'def' with the default value > ?and off you go. ?'def' seems to be the "minimum" value for that > ?particular type. 'def' is the default value, empty has a particular semantic meaning and serves to change the options. I should document this more carefully. Perhaps empty should be renamed 'optional', since that's what it does. > - As I wanted a single file argument, I tried to use 'args' in > ?combination with a parameter of type FilePath. ?Apparently 'args' > ?wants [FilePath] and appends command line arguments to the default > ?value. ?I used 'error "no file bla bla"' as the default value, and > ?appending to this didn't do much good, as you can imagine. ?So: use > ?[FilePath] and check the length manually. argPos 0 should do the trick. > - CmdArgs helpfully provides default --help, --version as well as > ?--quite and --verbose. ?For the two former, there's also a nice > ?default implementation, but presumably the latter two are for use in > ?the program proper. ?Unfortunately, I don't know how to get at their > ?values. As you found later, isLoud etc do the job. CmdArgs is very much a 0.1 release. The documentation isn't polished, it does simple arguments nicely, but has flaws when you try and go more advanced. I want to spend some more time on it at some point. Thanks, Neil From gcross at phys.washington.edu Thu Jan 14 12:44:58 2010 From: gcross at phys.washington.edu (Gregory Crosswhite) Date: Thu Jan 14 12:17:55 2010 Subject: [Haskell-cafe] General Advice Needed .. In-Reply-To: <27164433.post@talk.nabble.com> References: <27161410.post@talk.nabble.com> <27162216.post@talk.nabble.com> <27164433.post@talk.nabble.com> Message-ID: Yes. An approach that I have always used that has worked well for me is to keep a list of "tricks" while I am studying. Whenever I get stuck on a practice problem but eventually figure it out (either by simply thinking harder, looking it up, or asking someone for help), I try to identify the missing link that had prevented me from seeing how to do it immediately, and then write it down on my "tricks" list so that I know that I need to keep that trick in mind while I am taking the test. Cheers, Greg On Jan 14, 2010, at 8:53 AM, Ian675 wrote: > > thankyou.. that made more sense to me :) > > What im doing now is.. > Im still working through the "Craft of Functional Programming" book but I've > found a site that has solutions to some of the excercise questions. So i'm > noting them down and trying to make sense of them > > Is that a good approach? > > > Henk-Jan van Tuyl wrote: >> >> On Thu, 14 Jan 2010 15:38:26 +0100, Ian675 >> wrote: >> >>> >>> Pretty much yeah.. Im going through the book and things like : >>> >>> Define a function rangeProduct which when given natural numbers m and n, >>> returns the product m*(m+1)*....*(n-1)*n >>> >>> I got the solution from my lecture notes but I still dont understand it.. >>> >>> rangeProduct :: Int -> Int -> Int >>> rangeProduct m n >>> | m > n = 0 >>> | m == n = m >>> | otherwise = m * rangeProduct (m+1) n >>> >> >> I'll try to give a clear explanation of this function: >> >>> rangeProduct :: Int -> Int -> Int >>> rangeProduct m n >> A function is defined with parameters m and n, both Int; the result of the >> function is also an Int >> >>> | m > n = 0 >> If m > n, the result is 0; the rest of the function definition will be >> skipped >> >>> | m == n = m >> If m is not larger then n, evalution continues here; if m == n, the result >> of the function is m >> >> >>> | otherwise = m * rangeProduct (m+1) n >> If previous predicates were False, this branch is evaluated ("otherwise" >> is always True); the function calls itself with (m+1) as first parameter >> >> The boolean expressions in this function are called "guards"; the right >> hand side after the first guard that evaluates to True, will give the >> result of the function. >> >> Regards, >> Henk-Jan van Tuyl >> >> >> -- >> http://Van.Tuyl.eu/ >> http://members.chello.nl/hjgtuyl/tourdemonad.html >> -- >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> >> > > -- > View this message in context: http://old.nabble.com/General-Advice-Needed-..-tp27161410p27164433.html > 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 From lemming at henning-thielemann.de Thu Jan 14 12:51:55 2010 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Thu Jan 14 12:24:27 2010 Subject: [Haskell-cafe] sizeOf on a type In-Reply-To: References: <1261166970.12712.1350817859@webmail.messagingengine.com> Message-ID: On Fri, 25 Dec 2009, Lennart Augustsson wrote: > sizeOfPtr :: Ptr a -> Int > sizeOfPtr = sizeOf . (undefined :: Ptr a -> a) > > No need for scoped type variables. But it does assume sizeOf does not > use its argument. That's even better. I'll add that to the Wiki. ?http://www.haskell.org/haskellwiki/Scoped_type_variables#Avoiding_Scoped_Type_Variables From qdunkan at gmail.com Thu Jan 14 13:08:56 2010 From: qdunkan at gmail.com (Evan Laforge) Date: Thu Jan 14 12:41:26 2010 Subject: [Haskell-cafe] wildcards for type variables? In-Reply-To: <7be1feae1001140519l58312420s8a91e93e9de3d7db@mail.gmail.com> References: <2518b95d1001121529l60701d44y13ecf6614c82d1a6@mail.gmail.com> <4c88418c1001130254g58e11e37g1a4ec6cd1bad63e2@mail.gmail.com> <417DCDA9-6971-4F0A-AA5A-45C10DC5FCC3@ece.cmu.edu> <694519c51001130516i7cbb2535yc497efc3839db53c@mail.gmail.com> <43BCD272-1EB5-42AE-952F-66DF5268FAAD@informatik.uni-kiel.de> <2518b95d1001130954v470e510mbf6df19e99cd78e5@mail.gmail.com> <25DD26F9-93F2-4405-80E3-133AEBBE4649@informatik.uni-kiel.de> <7be1feae1001140519l58312420s8a91e93e9de3d7db@mail.gmail.com> Message-ID: <2518b95d1001141008n55f9c6f0laf57d7a44d6c6bd2@mail.gmail.com> On Thu, Jan 14, 2010 at 5:19 AM, Ozgur Akgun wrote: > Can someone give an example of a "reasonable" function that never uses one > of its parameters, and justify the existence of that parameter in this case, > please? As I mentioned, this is not only about parameters, but about type variables. From my own code: data Signal y = data ControlY -- phantom type type Control = Signal ControlY -- other phantom types follow takes_specific_signal :: Control -> ... takes_generic_signal :: Signal _y -> ... > Because for this example, > f :: _unused -> A -> B > f _ a = b > I think what I'd do is to write the function f without that first parameter, > and call the funcrtion accordingly. It's common (for me at least) to write 'modify' functions that look like "modify_x :: (X -> X) -> SomeMonad ()". You don't need to write the 'set' variant if you have const. That said, 'const' is already in the Prelude. But ignored args also turn up when you need a common signature, this also occurs a number of times in my own code: this_way :: X -> Y -> Z that_way :: X -> _y -> Z -- doesn't need Ys testing_way :: _x -> _y -> Z ... modify_rec $ const $ rec { rec_doit = if do_this_way then this_way else that_way } From stephen.tetley at gmail.com Thu Jan 14 14:38:20 2010 From: stephen.tetley at gmail.com (Stephen Tetley) Date: Thu Jan 14 14:10:52 2010 Subject: [Haskell-cafe] Haskell implementation of ideas from StandardML as a Metaprogramming language In-Reply-To: <897996.94253.qm@web112513.mail.gq1.yahoo.com> References: <897996.94253.qm@web112513.mail.gq1.yahoo.com> Message-ID: <5fdc56d71001141138k5669edaag65a63d2248af7751@mail.gmail.com> Hello Kashyap I can do MSL and Region, maybe I did the parser combinators but I can't find them at the moment. I tried to keep the code close to the original SML, so as Haskell code its not pretty. Not having quasiquote was a problem. Best wishes Stephen -------------------------------------------------------------------------------- -- MSL module MSL where type Expr = String type Predicate = Expr type Statement = String type Fieldname = String data Bitsource = Source Expr Expr deriving Show newbitsource a i = Source a i initbs (Source _ i) = i ++ " = 0;" getByte (Source a i) = a ++ "[" ++ i ++ "/8]" getNthByte :: Bitsource -> Int -> Expr getNthByte (Source a i) n | n == 0 = a ++ "[" ++ i ++ "/8]" | otherwise = a ++ "[" ++ i ++ "/8+" ++ show n ++ "]" advanceByte (Source a i) = i ++ " = " ++ i ++ "-(" ++ i ++ "%8)+8;" advanceNBytes (Source a i) n | n == 0 = "" | otherwise = i ++ " = " ++ i ++ "-(" ++ i ++ "%8)+(8*" ++ show n++");" data Recordfield = Field Expr [Fieldname] deriving Show recordptr :: Expr -> Recordfield recordptr e = Field e [] subfield :: Recordfield -> Fieldname -> Recordfield subfield (Field e fl) f = Field e (f:fl) deref :: Recordfield -> Expr deref (Field e fl) = "(*" ++e++ ")" ++ concat ( map cojoin (reverse fl) ) where cojoin :: Fieldname -> String cojoin s = "." ++ s type Message = Bitsource -> Recordfield -> Statement -> Statement infield :: Fieldname -> Message -> Message infield f m src tgt = m src (subfield tgt f) c_if :: Expr -> Statement -> Statement -> Statement c_if e s1 s2 = if e=="1" || e=="(1)" then s1 else "if("++e++"){" ++ s1 ++ "}" ++ if s2 /= "" then "else {" ++ s2 ++ "}" else "" seqmsg :: [Message] -> Message seqmsg (m:ml) src tgt s = (m src tgt "error_action();") ++ (seqmsg ml src tgt s) seqmsg [] _ _ _ = "" asc2Int :: Int -> (Int,Int) -> Message asc2Int w (lo,hi) src tgt s = c_if ("inrange(" ++ (getByte src) ++ ", " ++ (ms w) ++ ", " ++ (ms lo) ++ ", " ++ (ms hi)) "" s where ms n = show n alt :: [Message] -> Message alt (m:ml) src tgt s = m src tgt (alt ml src tgt s) delim :: Expr -> Message delim e src tgt s = "if (" ++ getByte src ++ " == " ++ e ++")" ++ advanceByte src rangex :: Int -> Int -> [Int] rangex i j | i > j = [] | otherwise = (i:(rangex (i+1) j)) c_and [] = "" c_and [pred] = "(" ++ pred ++ ")" c_and (pred1:pred2:preds) = "(" ++ pred1 ++ " && " ++ c_and (pred2:preds) ++ ")" asc :: String -> String -> Message asc chars value src tgt s = c_if "" (deref tgt ++ " == " ++ value ++ ";" ) s skip :: Int -> Message skip n src tgt s = (deref tgt) ++ "= 1;" ++ (advanceNBytes src n) -------------------------------------------------------------------------------- bs = newbitsource "A" "bit" f = recordptr "target" main = delim "6" bs f "abort();" to_confidence = alt [ asc "HH" "High" , asc "MM" "Medium" , asc "LL" "Low" , asc "NN" "None" ] -------------------------------------------------------------------------------- -- Region -- This one doesn't work properly - -- CPoints are difficult to manipulate as strings, hence the `hasVar` -- problems, it gives some idea of the method though. module Region where import Data.Char ( isAlpha ) import Data.List ( foldl' ) -- Prolog type CExpr = String type CPred = String type CFloat = Float infixr 6 ++& (++&) :: Show a => String -> a -> String s ++& a = s ++ show a sqrdist _ = "" add :: CPoint -> CPoint -> CPoint add a b = a ++ "+" ++ b sub :: CPoint -> CPoint -> CPoint sub a b = a ++ "-" ++ b hasVar :: CExpr -> Bool hasVar = any isAlpha cfst :: CPoint -> CExpr cfst a | hasVar a = a ++ ".x" | otherwise = "1.1" csnd :: CPoint -> CExpr csnd a | hasVar a = a ++".y" | otherwise = "2.2" pt :: (CFloat,CFloat) -> CPoint pt = show intersect :: [Region] -> Region intersect (r:rs) = foldl' (/\) r rs intersect [] = error $ "intersect on empty list" -- presentation type CPoint = CExpr type Region = CPoint -> CPred circle :: CFloat -> Region circle n = \p -> "(" ++ sqrdist p ++ "<" ++& n ++ "*" ++& n ++ ")" halfplane :: CPoint -> CPoint -> Region halfplane a b = \p -> "(" ++ zcross (a `sub` p) (b `sub` a) ++ " > 0.0)" where zcross e1 e2 = "(" ++ cfst e1 ++ "*" ++ csnd e2 ++ "-" ++ csnd e2 ++ "*" ++ cfst e1 ++ ")" (/\) :: Region -> Region -> Region r1 /\ r2 = \p -> "(" ++ r1 p ++ " && " ++ r2 p ++ ")" (\/) :: Region -> Region -> Region r1 \/ r2 = \p -> "(" ++ r1 p ++ " || " ++ r2 p ++ ")" at :: Region -> CPoint -> Region r `at` p0 = \p -> r (p `sub` p0) convexPoly :: [CPoint] -> Region convexPoly (p:ps) = intersect (zipWith halfplane ([p] ++ ps) (ps ++ [p])) tightZone :: CPoint -> CPred tightZone = (convexPoly [pt (0.0,5.0), pt (118.0,32.0), pt (118.0,62.0), pt (0.0,25.0) ]) \/ (convexPoly [pt (118.0,32.0), pt (259.0,5.0), pt (259.0, 25.0), pt (118.0,62.0)]) main = tightZone e1 where e1::CExpr e1 = "p" From andrewcoppin at btinternet.com Thu Jan 14 14:38:48 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Thu Jan 14 14:11:11 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4F10D2.4080902@van.steenbergen.nl> References: <4B4CE8CE.9060202@btinternet.com> <4B4F10D2.4080902@van.steenbergen.nl> Message-ID: <4B4F72C8.1040903@btinternet.com> Martijn van Steenbergen wrote: > Niklas Broberg wrote: >> 21 actually. case, class, data, default, deriving, do, else, if, >> import, in, infix, infixl, infixr, instance, let, module, newtype, of, >> then, type, where. There's also three special words that can still be >> used as identifiers, so aren't reserved: as, qualified, hiding. > > Since you can define operators in Haskell, would it make sense to > include '=', '--', ':', ',' etc. as "reserved names" since those can't > be used as operator names? Makes sense to me... It's merely more difficult to catelogue this information for a half-dozen different languages. Looking up the reserved word list is usually only a Google search away. Somebody suggested to me that the best metric for "how difficult" a language is to learn is "the number of orthogonal concepts you need to learn". Of course, measuring THAT is going to be no picknick! From dnmehay at gmail.com Thu Jan 14 14:42:42 2010 From: dnmehay at gmail.com (DNM) Date: Thu Jan 14 14:15:14 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: References: <27139612.post@talk.nabble.com> <61E9624C-CB47-469C-BC29-2FA4A670D845@cs.york.ac.uk> <27156254.post@talk.nabble.com> Message-ID: <27167019.post@talk.nabble.com> Which is weird, because 'srilm.o'/'srilm.h' are the files that define the mysterious "undefined references". I'll keep plugging away and report back when (or whether) I make some progress. In the meanwhile, if anyone has a clue, I'm all ears. Best, D.N. Malcolm Wallace wrote: > > However, if you are unsure of which Haskell packages are needed, it is > wise to let ghc work out the dependencies for you, e.g. with > ghc --make Main.hs slirm.o > > It cannot work out the C/C++ dependencies though, so every time you > get "undefined reference" linking errors, you must discover which C > code provides those symbols, and add its object file to the > commandline by hand. > -- View this message in context: http://old.nabble.com/FFI%2C-C-C%2B%2B-and-undefined-references-tp27139612p27167019.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From jur at cs.uu.nl Thu Jan 14 15:06:22 2010 From: jur at cs.uu.nl (jur) Date: Thu Jan 14 14:38:53 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4F72C8.1040903@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> <4B4F10D2.4080902@van.steenbergen.nl> <4B4F72C8.1040903@btinternet.com> Message-ID: On Jan 14, 2010, at 8:38 PM, Andrew Coppin wrote: > Martijn van Steenbergen wrote: >> Niklas Broberg wrote: >>> 21 actually. case, class, data, default, deriving, do, else, if, >>> import, in, infix, infixl, infixr, instance, let, module, newtype, >>> of, >>> then, type, where. There's also three special words that can still >>> be >>> used as identifiers, so aren't reserved: as, qualified, hiding. >> >> Since you can define operators in Haskell, would it make sense to >> include '=', '--', ':', ',' etc. as "reserved names" since those >> can't be used as operator names? > > Makes sense to me... > > It's merely more difficult to catelogue this information for a half- > dozen different languages. Looking up the reserved word list is > usually only a Google search away. > > Somebody suggested to me that the best metric for "how difficult" a > language is to learn is "the number of orthogonal concepts you need > to learn". Of course, measuring THAT is going to be no picknick! I do not think so. More orthogonal concepts may make it more work to learn the language, but I think orthogonality helps to learn a language that has many concepts. For me, a major problem when learning a language is ad-hocness. The Java Language Specification part on Generics (parametric polymorphism) comes to mind. It is full of ad-hoc restrictions, and operational details. Haskell's polymorphism behaves much more predictably because it is much less ad-hoc. Although I do not have any Python programming experience, I got the impression that Python is very un-ad-hoc. Everything behaves in exactly the same way at all possible levels in the language. You need to master only one idea and it applies everywhere. Even if the way it behaves is strange. Jurriaan From daniel.is.fischer at web.de Thu Jan 14 15:08:24 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Thu Jan 14 14:42:56 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <27167019.post@talk.nabble.com> References: <27139612.post@talk.nabble.com> <27167019.post@talk.nabble.com> Message-ID: <201001142108.26312.daniel.is.fischer@web.de> Am Donnerstag 14 Januar 2010 20:42:42 schrieb DNM: > Which is weird, because 'srilm.o'/'srilm.h' are the files that define > the mysterious "undefined references". I'll keep plugging away and > report back when (or whether) I make some progress. In the meanwhile, > if anyone has a clue, I'm all ears. > > Best, > D.N. Just an idea. Are you on windows? If so, then your foreign calls would probably have to be foreign import stdcall "srilm.h whatever" ... instead of foreign import ccall "..." > > Malcolm Wallace wrote: > > However, if you are unsure of which Haskell packages are needed, it is > > wise to let ghc work out the dependencies for you, e.g. with > > ghc --make Main.hs slirm.o > > > > It cannot work out the C/C++ dependencies though, so every time you > > get "undefined reference" linking errors, you must discover which C > > code provides those symbols, and add its object file to the > > commandline by hand. From tanimoto at arizona.edu Thu Jan 14 15:23:52 2010 From: tanimoto at arizona.edu (Paulo Tanimoto) Date: Thu Jan 14 14:56:42 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <201001142108.26312.daniel.is.fischer@web.de> References: <27139612.post@talk.nabble.com> <27167019.post@talk.nabble.com> <201001142108.26312.daniel.is.fischer@web.de> Message-ID: On Thu, Jan 14, 2010 at 2:08 PM, Daniel Fischer wrote: > > Just an idea. Are you on windows? > If so, then your foreign calls would probably have to be > > foreign import stdcall "srilm.h whatever" ... > > instead of > > foreign import ccall "..." > Yes, I came here to say that too. I was getting those errors on Windows. Paulo From stephen.tetley at gmail.com Thu Jan 14 15:24:47 2010 From: stephen.tetley at gmail.com (Stephen Tetley) Date: Thu Jan 14 14:57:19 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <201001142108.26312.daniel.is.fischer@web.de> References: <27139612.post@talk.nabble.com> <27167019.post@talk.nabble.com> <201001142108.26312.daniel.is.fischer@web.de> Message-ID: <5fdc56d71001141224u201375abi6080c29e63669819@mail.gmail.com> Hello Daniel On Windows, isn't stdcall vs ccall still dependent on the actual library and what compiled it - commonly MSVC (stdcall) or gcc (ccall) of course? I could very easily be wrong... Best wishes Stephen 2010/1/14 Daniel Fischer : > Am Donnerstag 14 Januar 2010 20:42:42 schrieb DNM: > > Just an idea. Are you on windows? > If so, then your foreign calls would probably have to be > > foreign import stdcall "srilm.h whatever" ... > > instead of > > foreign import ccall "..." > From bulat.ziganshin at gmail.com Thu Jan 14 15:33:07 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Thu Jan 14 15:08:47 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <201001142108.26312.daniel.is.fischer@web.de> References: <27139612.post@talk.nabble.com> <27167019.post@talk.nabble.com> <201001142108.26312.daniel.is.fischer@web.de> Message-ID: <1556549637.20100114233307@gmail.com> Hello Daniel, Thursday, January 14, 2010, 11:08:24 PM, you wrote: i think you are wrong. stdcall used for std windows dlls, but gcc by default generates ccall things. and cl anyway useless here > Just an idea. Are you on windows? > If so, then your foreign calls would probably have to be > foreign import stdcall "srilm.h whatever" ... > instead of > foreign import ccall "..." >> >> Malcolm Wallace wrote: >> > However, if you are unsure of which Haskell packages are needed, it is >> > wise to let ghc work out the dependencies for you, e.g. with >> > ghc --make Main.hs slirm.o >> > >> > It cannot work out the C/C++ dependencies though, so every time you >> > get "undefined reference" linking errors, you must discover which C >> > code provides those symbols, and add its object file to the >> > commandline by hand. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From dnmehay at gmail.com Thu Jan 14 15:39:57 2010 From: dnmehay at gmail.com (DNM) Date: Thu Jan 14 15:12:26 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <201001142108.26312.daniel.is.fischer@web.de> References: <27139612.post@talk.nabble.com> <61E9624C-CB47-469C-BC29-2FA4A670D845@cs.york.ac.uk> <27156254.post@talk.nabble.com> <27167019.post@talk.nabble.com> <201001142108.26312.daniel.is.fischer@web.de> Message-ID: <27167751.post@talk.nabble.com> Nope. Ubuntu Linux (Intrepid Ibex). I wish it were that simple. --D.N. Daniel Fischer-4 wrote: > > Am Donnerstag 14 Januar 2010 20:42:42 schrieb DNM: >> Which is weird, because 'srilm.o'/'srilm.h' are the files that define >> the mysterious "undefined references". I'll keep plugging away and >> report back when (or whether) I make some progress. In the meanwhile, >> if anyone has a clue, I'm all ears. >> >> Best, >> D.N. > > Just an idea. Are you on windows? > If so, then your foreign calls would probably have to be > > foreign import stdcall "srilm.h whatever" ... > > instead of > > foreign import ccall "..." > >> >> Malcolm Wallace wrote: >> > However, if you are unsure of which Haskell packages are needed, it is >> > wise to let ghc work out the dependencies for you, e.g. with >> > ghc --make Main.hs slirm.o >> > >> > It cannot work out the C/C++ dependencies though, so every time you >> > get "undefined reference" linking errors, you must discover which C >> > code provides those symbols, and add its object file to the >> > commandline by hand. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- View this message in context: http://old.nabble.com/FFI%2C-C-C%2B%2B-and-undefined-references-tp27139612p27167751.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From bulat.ziganshin at gmail.com Thu Jan 14 15:36:28 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Thu Jan 14 15:18:47 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <27167019.post@talk.nabble.com> References: <27139612.post@talk.nabble.com> <61E9624C-CB47-469C-BC29-2FA4A670D845@cs.york.ac.uk> <27156254.post@talk.nabble.com> <27167019.post@talk.nabble.com> Message-ID: <1695352408.20100114233628@gmail.com> Hello DNM, Thursday, January 14, 2010, 10:42:42 PM, you wrote: there is better way rather than playing with random bits. just find tutorial on FFI, and try it. once this example works, start modifying it to learn various aspects of ffi and add functionality you need it's one thing i've learned in those 20 years - go forward in small steps keeping working code instead of jumping at large distance and then spending days without any clue > Which is weird, because 'srilm.o'/'srilm.h' are the files that define the > mysterious "undefined references". I'll keep plugging away and report > back when (or whether) I make some progress. In the meanwhile, if anyone > has a clue, I'm all ears. > Best, > D.N. > Malcolm Wallace wrote: >> >> However, if you are unsure of which Haskell packages are needed, it is >> wise to let ghc work out the dependencies for you, e.g. with >> ghc --make Main.hs slirm.o >> >> It cannot work out the C/C++ dependencies though, so every time you >> get "undefined reference" linking errors, you must discover which C >> code provides those symbols, and add its object file to the >> commandline by hand. >> -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From daniel.is.fischer at web.de Thu Jan 14 15:47:54 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Thu Jan 14 15:22:07 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <27167751.post@talk.nabble.com> References: <27139612.post@talk.nabble.com> <201001142108.26312.daniel.is.fischer@web.de> <27167751.post@talk.nabble.com> Message-ID: <201001142147.55386.daniel.is.fischer@web.de> Am Donnerstag 14 Januar 2010 21:39:57 schrieb DNM: > Nope. Ubuntu Linux (Intrepid Ibex). I wish it were that simple. > > --D.N. Okay, so it's not a borken OS 8-) Can you post "ought to be compiling" code? That might help locate the problem. From stephen.tetley at gmail.com Thu Jan 14 15:55:44 2010 From: stephen.tetley at gmail.com (Stephen Tetley) Date: Thu Jan 14 15:28:15 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <1695352408.20100114233628@gmail.com> References: <27139612.post@talk.nabble.com> <61E9624C-CB47-469C-BC29-2FA4A670D845@cs.york.ac.uk> <27156254.post@talk.nabble.com> <27167019.post@talk.nabble.com> <1695352408.20100114233628@gmail.com> Message-ID: <5fdc56d71001141255q62763b31je5d1ac544bcd9224@mail.gmail.com> 2010/1/14 Bulat Ziganshin : > there is better way rather than playing with random bits. just find > tutorial on FFI, and try it. once this example works, start modifying > it to learn various aspects of ffi and add functionality you need Also binding to a C library is easier than binding to a C++ one, if you can think of another library rather than SRILM that will meet your needs... Best wishes Stephen From j.russell at alum.mit.edu Thu Jan 14 16:03:14 2010 From: j.russell at alum.mit.edu (James Russell) Date: Thu Jan 14 15:36:03 2010 Subject: [Haskell-cafe] ANNOUNCE: Functional Programming Bibliography Message-ID: <58925be01001141303l3d7a55e4u7d10d54c363e352a@mail.gmail.com> I am pleased to announce the Functional Programming Bibliography at http://www.catamorphism.net/ The functional programming bibliography was created in the hope that it will be a useful resource to the functional programming community. The site is still in an early stage of development, and is pretty raw, and incomplete in a number of ways. Keyword categorization, in particular, is still fairly spotty. It currently contains in excess of 1500 references, heavily slanted toward Haskell-related topics, and contains links to publicly available versions of many papers, as well as links to gated versions of some papers. I am eager for suggestions as to how the site could be made more useful. Regards, James Russell From inforichland at gmail.com Thu Jan 14 16:11:16 2010 From: inforichland at gmail.com (Tim Wawrzynczak) Date: Thu Jan 14 15:43:46 2010 Subject: [Haskell-cafe] ANNOUNCE: Functional Programming Bibliography In-Reply-To: <58925be01001141303l3d7a55e4u7d10d54c363e352a@mail.gmail.com> References: <58925be01001141303l3d7a55e4u7d10d54c363e352a@mail.gmail.com> Message-ID: <4335a3261001141311s167d1e17pf3550bfcb758877a@mail.gmail.com> At a quick glance, +5 Awesome. Cheers - Tim On Thu, Jan 14, 2010 at 3:03 PM, James Russell wrote: > I am pleased to announce the Functional Programming Bibliography > at http://www.catamorphism.net/ > > The functional programming bibliography was created in the hope > that it will be a useful resource to the functional programming > community. The site is still in an early stage of development, > and is pretty raw, and incomplete in a number of ways. Keyword > categorization, in particular, is still fairly spotty. > > It currently contains in excess of 1500 references, heavily > slanted toward Haskell-related topics, and contains links to > publicly available versions of many papers, as well as links to > gated versions of some papers. > > I am eager for suggestions as to how the site could be made more > useful. > > Regards, > > James Russell > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100114/9ed6c6db/attachment.html From inforichland at gmail.com Thu Jan 14 16:12:23 2010 From: inforichland at gmail.com (Tim Wawrzynczak) Date: Thu Jan 14 15:44:53 2010 Subject: [Haskell-cafe] ANNOUNCE: Functional Programming Bibliography In-Reply-To: <4335a3261001141311s167d1e17pf3550bfcb758877a@mail.gmail.com> References: <58925be01001141303l3d7a55e4u7d10d54c363e352a@mail.gmail.com> <4335a3261001141311s167d1e17pf3550bfcb758877a@mail.gmail.com> Message-ID: <4335a3261001141312s3eaf6ee9l3e95f04ec909d205@mail.gmail.com> Oh also, I noticed that you say it's powered by Haskell. Would you mind sharing some of your architectural details as they relate to Haskell with us? On Thu, Jan 14, 2010 at 3:11 PM, Tim Wawrzynczak wrote: > At a quick glance, > > +5 Awesome. > > Cheers > - Tim > > > On Thu, Jan 14, 2010 at 3:03 PM, James Russell wrote: > >> I am pleased to announce the Functional Programming Bibliography >> at http://www.catamorphism.net/ >> >> The functional programming bibliography was created in the hope >> that it will be a useful resource to the functional programming >> community. The site is still in an early stage of development, >> and is pretty raw, and incomplete in a number of ways. Keyword >> categorization, in particular, is still fairly spotty. >> >> It currently contains in excess of 1500 references, heavily >> slanted toward Haskell-related topics, and contains links to >> publicly available versions of many papers, as well as links to >> gated versions of some papers. >> >> I am eager for suggestions as to how the site could be made more >> useful. >> >> Regards, >> >> James Russell >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100114/eb43603f/attachment.html From miguelimo38 at yandex.ru Thu Jan 14 16:19:08 2010 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Thu Jan 14 15:51:45 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <27167751.post@talk.nabble.com> References: <27139612.post@talk.nabble.com> <61E9624C-CB47-469C-BC29-2FA4A670D845@cs.york.ac.uk> <27156254.post@talk.nabble.com> <27167019.post@talk.nabble.com> <201001142108.26312.daniel.is.fischer@web.de> <27167751.post@talk.nabble.com> Message-ID: <7A9F334D-DA4C-4A55-819A-053A2C1DD58F@yandex.ru> Works fine here (Mac OS X 10.5): MigMit:ngram MigMit$ ghc --make Main.hs srilm.o [1 of 2] Compiling LM ( LM.hs, LM.o ) LM.hs:9:0: Warning: possible missing & in foreign import of FunPtr [2 of 2] Compiling Main ( Main.hs, Main.o ) Linking Main ... MigMit:ngram MigMit$ ls Main* Main* Main.hi Main.hs Main.hs~ Main.o MigMit:ngram MigMit$ cat Main.hs module Main where import LM(scoreSequence, buildLM) main :: IO () main = do let lm = buildLM 5 "eng.kn.5g.lm" putStrLn $ show $ scoreSequence lm 5 ["the", "prime", "minister", "gave","a", "speech", "."] MigMit:ngram MigMit$ cat LM.hs {-# INCLUDE "srilm.h" #-} {-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-} module LM where import Foreign import Foreign.C data Ngram data NGModel = NGModel {ng :: !(ForeignPtr Ngram)} foreign import ccall "srilm.h bldLM" c_blm :: CInt -> CString -> Ptr Ngram foreign import ccall "srilm.h deleteLM" c_dlm :: FunPtr ((Ptr Ngram) - > IO ()) foreign import ccall "srilm.h getSeqProb" c_ngramProb :: Ptr Ngram -> CString -> CUInt -> CUInt -> CFloat scoreSequence :: NGModel -> Int -> [String] -> Float scoreSequence ngram order seq = unsafePerformIO $ do stringSeq <- newCString (unwords seq) let sc = c_ngramProb (unsafeForeignPtrToPtr $ ng ngram) stringSeq (fromIntegral order) (fromIntegral $ length seq) return (realToFrac sc) buildLM :: Int -> String -> NGModel buildLM order fname = NGModel $ unsafePerformIO $ do cFName <- newCString fname let ng = c_blm (fromIntegral order) cFName return $ unsafePerformIO $ newForeignPtr c_dlm ng MigMit:ngram MigMit$ cat srilm.h #ifdef __cplusplus extern "C" { class Ngram{}; #else typedef struct Ngram Ngram; #endif Ngram* bldLM(int order, const char* filename); void deleteLM(Ngram* ngram); float getSeqProb(Ngram* ngram, const char* ngramstr, unsigned order, unsigned length); #ifdef __cplusplus } #endif MigMit:ngram MigMit$ cat srilm.c #include "srilm.h" Ngram* bldLM(int order, const char* filename) { return 0; } void deleteLM(Ngram* ngram) {} float getSeqProb(Ngram* ngram, const char* ngramstr, unsigned order, unsigned length) { return 0;} MigMit:ngram MigMit$ Maybe you just need to recompile srilm.c or something. On 14 Jan 2010, at 23:39, DNM wrote: > > Nope. Ubuntu Linux (Intrepid Ibex). I wish it were that simple. > > --D.N. > > > Daniel Fischer-4 wrote: >> >> Am Donnerstag 14 Januar 2010 20:42:42 schrieb DNM: >>> Which is weird, because 'srilm.o'/'srilm.h' are the files that >>> define >>> the mysterious "undefined references". I'll keep plugging away and >>> report back when (or whether) I make some progress. In the >>> meanwhile, >>> if anyone has a clue, I'm all ears. >>> >>> Best, >>> D.N. >> >> Just an idea. Are you on windows? >> If so, then your foreign calls would probably have to be >> >> foreign import stdcall "srilm.h whatever" ... >> >> instead of >> >> foreign import ccall "..." >> >>> >>> Malcolm Wallace wrote: >>>> However, if you are unsure of which Haskell packages are needed, >>>> it is >>>> wise to let ghc work out the dependencies for you, e.g. with >>>> ghc --make Main.hs slirm.o >>>> >>>> It cannot work out the C/C++ dependencies though, so every time you >>>> get "undefined reference" linking errors, you must discover which C >>>> code provides those symbols, and add its object file to the >>>> commandline by hand. >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> >> > > -- > View this message in context: http://old.nabble.com/FFI%2C-C-C%2B%2B-and-undefined-references-tp27139612p27167751.html > 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 From andrewcoppin at btinternet.com Thu Jan 14 17:11:26 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Thu Jan 14 16:43:40 2010 Subject: [Haskell-cafe] ANNOUNCE: Functional Programming Bibliography In-Reply-To: <58925be01001141303l3d7a55e4u7d10d54c363e352a@mail.gmail.com> References: <58925be01001141303l3d7a55e4u7d10d54c363e352a@mail.gmail.com> Message-ID: <4B4F968E.6020209@btinternet.com> James Russell wrote: > I am pleased to announce the Functional Programming Bibliography > at http://www.catamorphism.net/ > > I am eager for suggestions as to how the site could be made more > useful. > As is traditional, my ISP's spam filter ate this email. *sigh* Anyway, I did a search for "Simon Peyton Jones" and got... zero results. o_O But on further investigation, searching just "Peyton Jones" delivers the expected deluge of hits. Maybe make the searching smarter? (Or just make a small note to search by last name only...) Also, I did a search, changed the sort criteria, and... the previously entered information was not presurved. Hopefully that isn't hard to fix. This resource seems like a nice idea. There are a whole crocload of fascinating papers about GHC and program optimisation out there, but it tends to be a tad time-consuming to track them all down. Hopefully this site will make things significantly easier in that department. From dons at galois.com Thu Jan 14 17:21:14 2010 From: dons at galois.com (Don Stewart) Date: Thu Jan 14 16:53:52 2010 Subject: [Haskell-cafe] Quick, somebody do something! In-Reply-To: References: Message-ID: <20100114222114.GA25162@whirlpool.galois.com> While the month-old Go language makes the top 15? Methods considered unsound. hjgtuyl: > > Haskell has dropped out of the top 50 at Tiobe [1]; how could this hapen? > Let's start selling mobile phones that can only be programmed in Haskell > :-) > > > [1] http://www.tiobe.com/content/paperinfo/tpci/index.html > > > -- > Met vriendelijke groet, > Henk-Jan van Tuyl > > > -- > http://Van.Tuyl.eu/ > http://members.chello.nl/hjgtuyl/tourdemonad.html > -- > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From daniel.is.fischer at web.de Thu Jan 14 17:23:12 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Thu Jan 14 16:57:23 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <7A9F334D-DA4C-4A55-819A-053A2C1DD58F@yandex.ru> References: <27139612.post@talk.nabble.com> <27167751.post@talk.nabble.com> <7A9F334D-DA4C-4A55-819A-053A2C1DD58F@yandex.ru> Message-ID: <201001142323.12720.daniel.is.fischer@web.de> Am Donnerstag 14 Januar 2010 22:19:08 schrieb Miguel Mitrofanov: > Works fine here (Mac OS X 10.5): > > MigMit:ngram MigMit$ ghc --make Main.hs srilm.o > [1 of 2] Compiling LM ? ? ? ? ? ? ? ( LM.hs, LM.o ) > > LM.hs:9:0: Warning: possible missing & in foreign import of FunPtr > [2 of 2] Compiling Main ? ? ? ? ? ? ( Main.hs, Main.o ) > Linking Main ... Thanks Miguel. Yes, works here (openSuse 11.1), too (kind of): (move the typedef out of the #else clause in srilm.h, because my g++ doesn't know Ngram) $ g++ -c srilm.c $ ghc --make Main.hs srilm.o [1 of 2] Compiling LM ( LM.hs, LM.o ) LM.hs:1:11: Warning: -#include is deprecated: No longer has any effect LM.hs:13:0: Warning: possible missing & in foreign import of FunPtr [2 of 2] Compiling Main ( Main.hs, Main.o ) Linking Main ... $ ./Main 0.0 Speicherzugriffsfehler Fixing the two warnings (removing the {-# INCLUDE #-} pragma and changing the declaration of deleteLM to foreign import ccall "srilm.h &deleteLM" c_dlm :: FunPtr ((Ptr Ngram) -> IO ()) ), I get $ ghc -fforce-recomp --make Main.hs srilm.o [1 of 2] Compiling LM ( LM.hs, LM.o ) [2 of 2] Compiling Main ( Main.hs, Main.o ) Linking Main ... $ ./Main 0.0 $ From simons at cryp.to Thu Jan 14 17:30:29 2010 From: simons at cryp.to (Peter Simons) Date: Thu Jan 14 17:05:18 2010 Subject: [Haskell-cafe] I/O performance drop in ghc 6.12.1 Message-ID: <87pr5c5nga.fsf@write-only.cryp.to> Hi, I just updated to GHC 6.12.1, and I noticed a significant drop in I/O performance that I can't explain. The following code is a simple re-implementation of cat(1), i.e. it just echos all data from standard input to standard output: > module Main ( main ) where > > import System.IO > import Foreign ( allocaBytes ) > > bufsize :: Int > bufsize = 4 * 1024 > > catBuf :: Handle -> Handle -> IO () > catBuf hIn hOut = allocaBytes bufsize input > where > input ptr = hGetBuf hIn ptr bufsize >>= output ptr > output _ 0 = return () > output ptr n = hPutBuf hOut ptr n >> input ptr > > main :: IO () > main = do > mapM_ (\h -> hSetBuffering h NoBuffering) [ stdin, stdout ] > catBuf stdin stdout That program used to have exactly the same performance as /bin/cat, but now it no longer does: | $ dd if=/dev/urandom of=test.data bs=1M count=512 | | $ time /bin/cat /dev/null | | real 0m1.939s | user 0m0.003s | sys 0m1.923s | | $ time ./cat-hgetbuf /dev/null | | real 0m4.327s | user 0m1.967s | sys 0m2.317s I've tested different variants of the program that were built with -O, -O2, and -O2 -funbox-strict-fields, respectively, but it doesn't seem to make a difference. Is there something I'm missing? Any suggestion would be kindly appreciated. Take care, Peter From allbery at ece.cmu.edu Thu Jan 14 17:36:41 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Thu Jan 14 17:09:23 2010 Subject: [Haskell-cafe] I/O performance drop in ghc 6.12.1 In-Reply-To: <87pr5c5nga.fsf@write-only.cryp.to> References: <87pr5c5nga.fsf@write-only.cryp.to> Message-ID: <177ABA9E-7497-47E8-9CBF-A7F1497C4769@ece.cmu.edu> On Jan 14, 2010, at 17:30 , Peter Simons wrote: > I just updated to GHC 6.12.1, and I noticed a significant drop in I/O > performance that I can't explain. The following code is a simple > re-implementation of cat(1), i.e. it just echos all data from standard > input to standard output: GHC 6.12.1 has the first release of UTF-8 support, so there's translation overhead. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100114/e2c69eea/PGP.bin From bos at serpentine.com Thu Jan 14 17:38:21 2010 From: bos at serpentine.com (Bryan O'Sullivan) Date: Thu Jan 14 17:10:51 2010 Subject: [Haskell-cafe] I/O performance drop in ghc 6.12.1 In-Reply-To: <87pr5c5nga.fsf@write-only.cryp.to> References: <87pr5c5nga.fsf@write-only.cryp.to> Message-ID: On Thu, Jan 14, 2010 at 2:30 PM, Peter Simons wrote: > > I just updated to GHC 6.12.1, and I noticed a significant drop in I/O > performance that I can't explain. This is probably brought about by the new Unicode I/O support in 6.12. Your file isn't open in binary mode, so it's probably getting translated from something like UTF-8 before it reaches you. Might want to compare the two. I'm a little surprised by the magnitude of the difference; I might have expected it to be 33%, not 400%. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100114/0daf0f78/attachment.html From vanenkj at gmail.com Thu Jan 14 17:42:15 2010 From: vanenkj at gmail.com (John Van Enk) Date: Thu Jan 14 17:14:46 2010 Subject: [Haskell-cafe] Force -threaded from a library Message-ID: Hi List, Is it possible to prevent a library from being used unless -threaded is enabled? I have a specific case where lots-of-nasty shows up if the library is linked against an executable built without -threaded. I suppose this is GHC specific. /jve -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100114/fcc81c4f/attachment.html From svein.ove at aas.no Thu Jan 14 17:44:13 2010 From: svein.ove at aas.no (Svein Ove Aas) Date: Thu Jan 14 17:16:44 2010 Subject: [Haskell-cafe] I/O performance drop in ghc 6.12.1 In-Reply-To: References: <87pr5c5nga.fsf@write-only.cryp.to> Message-ID: <221b53ab1001141444t23848535t20c5ce908f59c85d@mail.gmail.com> On Thu, Jan 14, 2010 at 11:38 PM, Bryan O'Sullivan wrote: > On Thu, Jan 14, 2010 at 2:30 PM, Peter Simons wrote: >> >> I just updated to GHC 6.12.1, and I noticed a significant drop in I/O >> performance that I can't explain. > > This is probably brought about by the new Unicode I/O support in 6.12. Your > file isn't open in binary mode, so it's probably getting translated from > something like UTF-8 before it reaches you. Might want to compare the two. > I'm a little surprised by the magnitude of the difference; I might have > expected it to be 33%, not 400%. > Hold on, he's using hGetBuf/hPutBuf. Although I'd suggest wrapping that in bytestrings.. the point is, those functions are documented to ignore encoding and always use binary I/O. There shouldn't be a difference at all. I wonder if the difference goes away if the handle is explicitly set to binary? It shouldn't, but then again it shouldn't exist in the first place. -- Svein Ove Aas From alp at mestan.fr Thu Jan 14 18:03:22 2010 From: alp at mestan.fr (Alp Mestan) Date: Thu Jan 14 17:35:53 2010 Subject: [Haskell-cafe] Quick, somebody do something! In-Reply-To: <20100114222114.GA25162@whirlpool.galois.com> References: <20100114222114.GA25162@whirlpool.galois.com> Message-ID: On Thu, Jan 14, 2010 at 11:21 PM, Don Stewart wrote: > While the month-old Go language makes the top 15? > > Methods considered unsound. > I fully agree. But anyway, I don't think people either already in the haskell world or about to enter it will find this relevant. -- Alp Mestan http://alpmestan.wordpress.com/ http://alp.developpez.com/ -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100114/566aa61f/attachment.html From simons at cryp.to Thu Jan 14 18:05:10 2010 From: simons at cryp.to (Peter Simons) Date: Thu Jan 14 17:38:05 2010 Subject: [Haskell-cafe] Re: I/O performance drop in ghc 6.12.1 References: <87pr5c5nga.fsf@write-only.cryp.to> <221b53ab1001141444t23848535t20c5ce908f59c85d@mail.gmail.com> Message-ID: <87bpgw5luh.fsf@write-only.cryp.to> Hi Svein, > Hold on, he's using hGetBuf/hPutBuf. exactly, that's what I was thinking. When a program requests that 'n' bytes ought to be read into memory at the location designated by the given 'Ptr Word8', how could GHC possibly do any encoding or decoding? That API doesn't allow for multi-byte characters. I would assume that hGetBuf/hPutBuf are the equivalent to POSIX read() and write()? > I wonder if the difference goes away if the handle is explicitly set > to binary? I added an mapM_ (\h -> hSetBinaryMode h True) [ stdin, stdout ] to 'main', and it does seem to improve performance a little, but it's still quite a bit slower than /bin/cat: | $ time /bin/cat /dev/null | | real 0m2.119s | user 0m0.003s | sys 0m1.967s | | $ time ./cat-hgetbuf /dev/null | | real 0m3.449s | user 0m1.137s | sys 0m2.240s Take care, Peter From nominolo at googlemail.com Thu Jan 14 18:33:54 2010 From: nominolo at googlemail.com (Thomas Schilling) Date: Thu Jan 14 18:06:26 2010 Subject: [Haskell-cafe] RFC: Space-leak-free, efficient symbol table implementation. Message-ID: <17B140E4-D3D4-4B2E-9BD7-8A26299DD7C8@googlemail.com> Hello Caf?, Symbol tables are a very common data structure in compilers but the most common implementation uses a hash table as a global variable which results in a space leak. If we decide to use several symbol tables we still cannot join different symbol tables. After some Googling I found the following implementation. It could still be argued that there are some smaller space leaks left, but decide for yourself. The use case I have in mind is a collection of several long-running compiler worker threads, that for the most part write their result to disk but may occasionally need to communicate with each other (and agree on symbol identities.) I'd appreciate comments / code review on the following code. I think it's fairly well-commented. Thanks, / Thomas {-# LANGUAGE BangPatterns #-} {-# OPTIONS_GHC -funbox-strict-fields #-} -- | -- Module : Data.Atom.UF -- Copyright : (c) Thomas Schilling 2010 -- License : BSD-style -- -- Maintainer : nominolo@gmail.com -- Stability : experimental -- Portability : portable -- -- Symbols without a central symbol table. -- -- Symbols provide the following efficient operations: -- -- - /O(1)/ equality comparison (in practise) -- - /O(1)/ ordering comparison (in practise) -- - /O(n)/ creation -- -- This can be implemented by using a global variable mapping strings -- to symbols and a counter assigning ids to symbols. However, this -- has two problems: -- -- 1. It has a space leak. No symbols can ever be removed from this -- table. For example, if we add the symbol @\"foo\"@ the first -- time it might get assigned id 1, if we then delete it and -- insert it again it might get assigned id 42. However, there -- may still be symbols in memory which got assigned id 1. -- Instead, symbols should be garbage collected like other data. -- Using weak pointers has bad effects on performance due to -- garbage collector overhead. -- -- 2. It is not reliable to compare symbols created using different -- symbol tables. They would most likely get assigned different -- ids. -- -- This implementation of symbols allows *optional* use of a symbol -- table. If a symbol table is used, this implementation will tend to -- use less memory and its operations will be a little bit faster at -- the beginning. For longer runs, it won't make a big difference -- though, since the representation is self-optimising. -- -- Inspired by Richard O'Keefe's message to Erlang's eeps mailing list -- , which in turn was -- inspired by the Logix implementation of Flat Concurrent Prolog. -- -- -- * Implementation -- -- Each symbol is represented a pointer to the symbol info, which -- consists of: -- -- * a 'String' -- * a 'Hash' -- * a null-able parent pointer to an equivalent symbol info -- -- Creating the same symbol twice will at first be represented as two -- different entities. -- -- @ -- .----+-------+-----. -- A -----> | 42 | "foo" | nil | -- '----+-------+-----' -- B --. -- '--> .----+-------+-----. -- C -----> | 42 | "foo" | nil | -- '----+-------+-----' -- @ -- -- (Note that @A@, @B@ and @C@ are @IORefs@.) -- -- When comparing @A@ and @B@ we use the following properties: -- -- 1. If @A@ and @B@ are identical then they must be equal. -- -- 2. If they point to the same object, they must equal. -- -- 3. If they have different hashes, they are different. -- -- Unless there is a hash collision, we can decide equality and -- ordering for all symbols that have been built with the same hash -- table. -- -- If the two objects have no parent, have the same hash, and the same -- string, we now make one the first the parent of the other and -- update the pointer of @B@ accordingly. If there are no references -- to the second object left it can now be garbage collected. -- -- If an object already has a parent pointer we follow each object's -- parents to the roots and compare the roots. This process might -- again result in updates to @A@ or @B@ and various parent pointers. -- -- In the example above, after @A == B@ we have: -- -- @ -- .----+-------+-----. -- A -----> | 42 | "foo" | nil | -- .--> '----+-------+-----' -- B --' ^ -- .----+-------+--|--. -- C -----> | 42 | "foo" | * | -- '----+-------+-----' -- @ -- -- After @C == A@ or @C == B@ we have. -- -- @ -- A -----> .----+-------+-----. -- .--> | 42 | "foo" | nil | -- B --'.-> '----+-------+-----' -- | ^ -- | .----+-------+--|--. -- C ---' | 42 | "foo" | * | -- '----+-------+-----' -- @ -- -- The second object will now be garbage collected. -- -- In fact, after the first @A == B@, the remaining updates could use -- some help from the garbage collector. This could be done by -- somehow forcibly (and unsafely) replacing the second object by an -- update frame and then rely on the GC's indirection shortening -- feature. This is /very/ unsafe, since some code may rely \"know\" -- that the object is already evaluated. E.g., C's pointer could be -- tagged (c.f. \"Faster Laziness Using Dynamic Pointer Tagging\"). -- It /might/ work if we can match the physical layout of both -- structures, but it's equally likely that hell freezes over, so I'll -- leave that as an exercise for more braver hackers. -- -- * TODO -- -- - generalise to arbitrary hashable objects. need not be -- restricted to 'String'. -- -- - make thread-safe. (we only need a lock for the uncommon cases) -- -- - make sure the pointer update code is correct and has no bad -- cases -- -- - implement IntMap variant\/wrapper that respects that two -- different objects may have the same key (however unlikely). -- module Data.Atom.UF ( Symbol, intern, internInto, SymTab(..) ) where import Data.Word ( Word32 ) import Data.Char ( ord ) import Data.Bits ( xor ) import Data.IORef import System.IO.Unsafe import Control.Monad -- ( unless ) import System.Mem.Weak import System.Mem import Data.Maybe -- ------------------------------------------------------------------- -- Public API: -- | A symbol. newtype Symbol = Symbol (IORef SymbolInfo) instance Eq Symbol where x == y = cmpSymbol x y == EQ instance Ord Symbol where compare = cmpSymbol instance Show Symbol where show = showSym -- | Create a new local symbol. For best performance use -- 'internInto' together with a symbol table / map. intern :: String -> Symbol class SymTab s where lookupSymbol :: s -> String -> Maybe Symbol insertSymbol :: String -> Symbol -> s -> s -- | Insert a symbol into an existing table. internInto :: SymTab s => s -> String -> (s, Symbol) -- ------------------------------------------------------------------- -- Internals data SymbolInfo = SymInfo {-# UNPACK #-} !Word32 -- hash {-# UNPACK #-} !(IORef Link) -- parent [really unpack]? String type Link = Maybe SymbolInfo internInto st str = case lookupSymbol st str of Just sym -> (st, sym) _ -> let sym = intern str in (insertSymbol str sym st, sym) showSym :: Symbol -> String showSym (Symbol r) = unsafePerformIO $ do -- dupable/inline is fine, too, since the string never changes (SymInfo _ _ str) <- readIORef r return str intern s = unsafePerformIO $ do lnk <- newIORef Nothing r <- newIORef $ SymInfo (hash s) lnk s return (Symbol r) mkSymbolInfo :: String -> SymbolInfo mkSymbolInfo s = unsafePerformIO $ do lnk <- newIORef Nothing return $ SymInfo (hash s) lnk s cmpSymbol :: Symbol -> Symbol -> Ordering cmpSymbol (Symbol r1) (Symbol r2) | r1 == r2 = EQ | otherwise = unsafePerformIO $ do -- We only read. It should be safe to use unsafeInlineIO for -- the two reads. sym1@(SymInfo h1 l1 s1) <- readIORef r1 sym2@(SymInfo h2 l2 s2) <- readIORef r2 case h1 `compare` h2 of -- If the hashes are different they cannot be the same symbol LT -> return LT GT -> return GT EQ | sameSym sym1 sym2 -> -- The two references are not the same, but they point to -- the same object. That's fine, we can't optimise any -- further. return EQ -- END OF COMMON CASE -- -- If the symbols have been built using the same symbol table -- we will only reach this case if we have a hash collision or -- the symbols were built from different symbol tables. -- -- TODO: Extract into NOINLINE function, wrap unsafePerformIO, -- and use an MVar-based lock. | otherwise -> do -- The hashes are the same. It could be a collision, or the -- symbol was created using a different symbol table. -- -- Case 1: The symbols have already be joined, but this -- Symbol's IORef still points to the old version. We can -- determine this by following the union/find structure. rep1 <- repr sym1 rep2 <- repr sym2 let string_cmp = s1 `compare` s2 -- lazy! if sameSym rep1 rep2 || string_cmp == EQ then do -- They should in fact be the same symbol. Update the -- atoms and the symbol infos if necessary. -- TODO: Use MVar / lock. unless (sameSym sym1 rep1) $ do writeIORef r1 rep1 writeIORef l1 (Just rep1) -- path shortening unless (sameSym sym2 rep1) $ do writeIORef r2 rep1 writeIORef l2 (Just rep1) return EQ else do -- They are not the same, and they shouldn't return string_cmp {-# NOINLINE cmpSymbol #-} -- We abuse the fact that IORefs give us an identity (i.e., observable -- sharing) and that we need the IORef anyway. sameSym :: SymbolInfo -> SymbolInfo -> Bool sameSym (SymInfo _ r1 _) (SymInfo _ r2 _) = r1 == r2 repr :: SymbolInfo -> IO SymbolInfo repr sym@(SymInfo _ r _) = do parent <- readIORef r -- TODO: perform path shortening. case parent of Nothing -> return sym Just sym' -> repr sym' test1 = do let s1@(Symbol r1) = intern "foo" s2@(Symbol r2) = intern "foo" print $ r1 == r2 -- should be False -- create a weak reference to the second symbol, so we can observe -- when it is garbage collected w <- mk_weak =<< readIORef r2 print $ s1 == s2 -- should print True print =<< liftM2 sameSym (readIORef r1) (readIORef r2) -- should print True putStrLn "GCing" performGC -- this should print goodbye, representing the -- fact that the second symbol has been garbage -- collected. print . isJust =<< deRefWeak w -- should print False (object has been collected) where mk_weak o = mkWeakPtr o (Just (putStrLn "goodbye")) -- ------------------------------------------------------------------- -- Fowler / Noll / Vo (FNV) hash. Original code expected 'unsigned -- char' input. Don't know whether it behaves worse for unicode -- chars. hash :: String -> Word32 hash str = go magic_start (map ord str) where magic_start = 2166136261 :: Word32 go :: Word32 -> [Int] -> Word32 go !h [] = h go !h (c:cs) = go ((h * 16777619) `xor` fromIntegral c) cs From gue.schmidt at web.de Thu Jan 14 19:49:38 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Thu Jan 14 19:23:16 2010 Subject: [Haskell-cafe] IDL - compilers Message-ID: <4B4FBBA2.2050609@web.de> Hi, are there any IDL compilers that can create Haskelk modules from header files or type-libs? G?nther From j.russell at alum.mit.edu Thu Jan 14 19:54:50 2010 From: j.russell at alum.mit.edu (James Russell) Date: Thu Jan 14 19:27:41 2010 Subject: [Haskell-cafe] ANNOUNCE: Functional Programming Bibliography In-Reply-To: <4335a3261001141312s3eaf6ee9l3e95f04ec909d205@mail.gmail.com> References: <58925be01001141303l3d7a55e4u7d10d54c363e352a@mail.gmail.com> <4335a3261001141311s167d1e17pf3550bfcb758877a@mail.gmail.com> <4335a3261001141312s3eaf6ee9l3e95f04ec909d205@mail.gmail.com> Message-ID: <58925be01001141654oacf7928w7300d084fbcc0b0e@mail.gmail.com> On Thu, Jan 14, 2010 at 4:12 PM, Tim Wawrzynczak wrote: > Oh also, I noticed that you say it's powered by Haskell. > > Would you mind sharing some of your architectural details as they relate to > Haskell with us? > > Not much to it, really. It's a LAMH thing, if you will. The Haskell part just runs as a CGI app, and uses the HDBC, HDBC-mysql, cgi, and xhtml packages, and is just a few hundred lines, including all the html templates which I create with the xhtml package. As for the bibliography stuff, right now I actually maintain a master .bib file and use bibTeX along with a set of custom .bst files to munge everything up to be imported into MySQL. > > On Thu, Jan 14, 2010 at 3:11 PM, Tim Wawrzynczak > wrote: >> >> At a quick glance, >> >> +5 Awesome. >> >> Cheers >> - Tim >> >> On Thu, Jan 14, 2010 at 3:03 PM, James Russell >> wrote: >>> >>> I am pleased to announce the Functional Programming Bibliography >>> at http://www.catamorphism.net/ >>> >>> The functional programming bibliography was created in the hope >>> that it will be a useful resource to the functional programming >>> community. The site is still in an early stage of development, >>> and is pretty raw, and incomplete in a number of ways. Keyword >>> categorization, in particular, is still fairly spotty. >>> >>> It currently contains in excess of 1500 references, heavily >>> slanted toward Haskell-related topics, and contains links to >>> publicly available versions of many papers, as well as links to >>> gated versions of some papers. >>> >>> I am eager for suggestions as to how the site could be made more >>> useful. >>> >>> Regards, >>> >>> James Russell >>> _______________________________________________ >>> 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 > > From gue.schmidt at web.de Thu Jan 14 19:55:42 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Thu Jan 14 19:28:30 2010 Subject: [Haskell-cafe] Re: Design question, HTML for GUIs? In-Reply-To: <4B4A1EBD.1080605@web.de> References: <4B4A1EBD.1080605@web.de> Message-ID: <4B4FBD0E.6080706@web.de> Thank you guys for all your responses. I just came accross something called HTML-Dialogs. It's mentioned in the ANNOUNCE files of the 0.26 source package of HaskellDirect. Apparently it takes about (on Windows) using HTML to create GUIs and scripting the Internet Explorer via COM. That would eliminate the need to use a webserver. Does anyone here know more about it, I tried to google it, but guess how much comes up when the only keywords you have is "Internet Explorer HTML Dialogs". G?nther From j.russell at alum.mit.edu Thu Jan 14 19:56:56 2010 From: j.russell at alum.mit.edu (James Russell) Date: Thu Jan 14 19:29:45 2010 Subject: [Haskell-cafe] ANNOUNCE: Functional Programming Bibliography In-Reply-To: <4B4F968E.6020209@btinternet.com> References: <58925be01001141303l3d7a55e4u7d10d54c363e352a@mail.gmail.com> <4B4F968E.6020209@btinternet.com> Message-ID: <58925be01001141656u5a0c6065pcb92732e909dabdb@mail.gmail.com> On Thu, Jan 14, 2010 at 5:11 PM, Andrew Coppin wrote: > James Russell wrote: >> >> I am pleased to announce the Functional Programming Bibliography >> at http://www.catamorphism.net/ >> >> I am eager for suggestions as to how the site could be made more >> useful. >> > > As is traditional, my ISP's spam filter ate this email. *sigh* > > Anyway, I did a search for "Simon Peyton Jones" and got... zero results. o_O > But on further investigation, searching just "Peyton Jones" delivers the > expected deluge of hits. Maybe make the searching smarter? (Or just make a > small note to search by last name only...) > I'll see what I can do about that. > Also, I did a search, changed the sort criteria, and... the previously > entered information was not presurved. Hopefully that isn't hard to fix. Nope. Fixed it already. It was the first thing on my todo list, but I figured that if I waited to get everything perfect, I would never get it out there at all. > > This resource seems like a nice idea. There are a whole crocload of > fascinating papers about GHC and program optimisation out there, but it > tends to be a tad time-consuming to track them all down. Hopefully this site > will make things significantly easier in that department. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From dons at galois.com Thu Jan 14 20:00:25 2010 From: dons at galois.com (Don Stewart) Date: Thu Jan 14 19:32:56 2010 Subject: [Haskell-cafe] IDL - compilers In-Reply-To: <4B4FBBA2.2050609@web.de> References: <4B4FBBA2.2050609@web.de> Message-ID: <20100115010025.GB25621@whirlpool.galois.com> gue.schmidt: > Hi, > > are there any IDL compilers that can create Haskelk modules from header > files or type-libs? > The venerable hdirect. http://www.haskell.org/hdirect/ I've recently cabalized the package, which is still in fine condition. Let me know if you need a copy. -- Don From gue.schmidt at web.de Thu Jan 14 20:03:33 2010 From: gue.schmidt at web.de (=?ISO-8859-1?Q?G=FCnther_Schmidt?=) Date: Thu Jan 14 19:36:05 2010 Subject: [Haskell-cafe] IDL - compilers In-Reply-To: <20100115010025.GB25621@whirlpool.galois.com> References: <4B4FBBA2.2050609@web.de> <20100115010025.GB25621@whirlpool.galois.com> Message-ID: <4B4FBEE5.10505@web.de> Hi Don, Am 15.01.10 02:00, schrieb Don Stewart: > gue.schmidt: > >> Hi, >> >> are there any IDL compilers that can create Haskelk modules from header >> files or type-libs? >> >> > The venerable hdirect. http://www.haskell.org/hdirect/ > > I've recently cabalized the package, which is still in fine condition. > Let me know if you need a copy. > Oh yes!, please!, pretty please! > -- Don > From ok at cs.otago.ac.nz Thu Jan 14 22:00:31 2010 From: ok at cs.otago.ac.nz (Richard O'Keefe) Date: Thu Jan 14 21:33:03 2010 Subject: [Haskell-cafe] General Advice Needed .. In-Reply-To: <27162216.post@talk.nabble.com> References: <27161410.post@talk.nabble.com> <27162216.post@talk.nabble.com> Message-ID: On Jan 15, 2010, at 3:38 AM, Ian675 wrote: > > Pretty much yeah.. Im going through the book and things like : > > Define a function rangeProduct which when given natural numbers m > and n, > returns the product m*(m+1)*....*(n-1)*n Case analysis and recursion. If m > n, the answer is 1 (the product of an empty sequence is 1). If m <= n, the answer is m * the product of m+1 .. n. range_product m n = if m > n then 1 else m * range_product (m+1) n Try it in C: int range_product(int m, int n) { return m > n ? 1 : m * range_product(m+1, n); } Same thing. Of course the most direct way to express it in Haskell is range_product m n = product [m..n] > I got the solution from my lecture notes but I still dont understand > it.. > > rangeProduct :: Int -> Int -> Int > rangeProduct m n > | m > n = 0 > | m == n = m > | otherwise = m * rangeProduct (m+1) n > > Totally lost! Haha.. One reason you're totally lost is that the code in the book is WRONG. The product of an empty sequence is 1, not 0. There are two basic ways of "thinking functionally", and they are actually both important in practically every kind of programming. (1) programming-by-combination: look for existing functions that are "close" to what you want and plug them together. In this case, looking for "product of a sequence of numbers" leads to 'product' and looking for "sequence of consecutive numbers" leads to [ .. ] syntax, and plugging them together leads to the product [m..n] version. (2) programming-by-case-analysis (including recursion): look for a way of classifying the problem into alternative cases, at least some of which are obviously simpler to solve. Recursion is just the special case where some of the alternatives can be handled using the function you are trying to define. By the way, the problem here is ambiguous. I look at m * (m+1) * ... * (n-1) * n and think "n to the falling n-m+1" (see "Concrete Mathematics" by Graham, Knuth, and Patashnik) and this is actually defined (and not identically 1) when m > n. So there are at least two reasonable definitions of what the function should do for m > n. (Returning 0 is NOT reasonable.) From ck_kashyap at yahoo.com Fri Jan 15 00:18:16 2010 From: ck_kashyap at yahoo.com (CK Kashyap) Date: Thu Jan 14 23:50:46 2010 Subject: [Haskell-cafe] Haskell implementation of ideas from StandardML as a Metaprogramming language In-Reply-To: <5fdc56d71001141138k5669edaag65a63d2248af7751@mail.gmail.com> References: <897996.94253.qm@web112513.mail.gq1.yahoo.com> <5fdc56d71001141138k5669edaag65a63d2248af7751@mail.gmail.com> Message-ID: <982073.66027.qm@web112512.mail.gq1.yahoo.com> Thank you very much Stephen ... I'll try and work on the doc plus the code you've sent to understand it. If you do find the parser combinators, please do send it to me. Thanks and Regards, Kashyap ----- Original Message ---- > From: Stephen Tetley > Cc: haskell-cafe@haskell.org > Sent: Fri, January 15, 2010 1:08:20 AM > Subject: Re: [Haskell-cafe] Haskell implementation of ideas from StandardML as a Metaprogramming language > > Hello Kashyap > > I can do MSL and Region, maybe I did the parser combinators but I > can't find them at the moment. > > I tried to keep the code close to the original SML, so as Haskell code > its not pretty. Not having quasiquote was a problem. > > Best wishes > > Stephen > > > -------------------------------------------------------------------------------- > -- MSL > > > module MSL where > > > type Expr = String > type Predicate = Expr > type Statement = String > type Fieldname = String > > data Bitsource = Source Expr Expr > deriving Show > > > newbitsource a i = Source a i > > initbs (Source _ i) = i ++ " = 0;" > > getByte (Source a i) = a ++ "[" ++ i ++ "/8]" > > getNthByte :: Bitsource -> Int -> Expr > getNthByte (Source a i) n > | n == 0 = a ++ "[" ++ i ++ "/8]" > | otherwise = a ++ "[" ++ i ++ "/8+" ++ show n ++ "]" > > advanceByte (Source a i) = i ++ " = " ++ i ++ "-(" ++ i ++ "%8)+8;" > > advanceNBytes (Source a i) n > | n == 0 = "" > | otherwise = i ++ " = " ++ i ++ "-(" ++ i ++ "%8)+(8*" ++ show n++");" > > > data Recordfield = Field Expr [Fieldname] > deriving Show > > recordptr :: Expr -> Recordfield > recordptr e = Field e [] > > subfield :: Recordfield -> Fieldname -> Recordfield > subfield (Field e fl) f = Field e (f:fl) > > deref :: Recordfield -> Expr > deref (Field e fl) > = "(*" ++e++ ")" ++ concat ( map cojoin (reverse fl) ) > where > cojoin :: Fieldname -> String > cojoin s = "." ++ s > > > > type Message = Bitsource -> Recordfield -> Statement -> Statement > > infield :: Fieldname -> Message -> Message > infield f m src tgt > = m src (subfield tgt f) > > > c_if :: Expr -> Statement -> Statement -> Statement > c_if e s1 s2 > = if e=="1" || e=="(1)" > then s1 > else "if("++e++"){" > ++ s1 > ++ "}" ++ if s2 /= "" then "else {" ++ s2 ++ "}" else "" > > > seqmsg :: [Message] -> Message > seqmsg (m:ml) src tgt s > = (m src tgt "error_action();") ++ (seqmsg ml src tgt s) > seqmsg [] _ _ _ = "" > > asc2Int :: Int -> (Int,Int) -> Message > asc2Int w (lo,hi) src tgt s > = c_if ("inrange(" ++ (getByte src) ++ ", " > ++ (ms w) ++ ", " ++ (ms lo) > ++ ", " ++ (ms hi)) > "" > s > where > ms n = show n > > > alt :: [Message] -> Message > alt (m:ml) src tgt s > = m src tgt (alt ml src tgt s) > > > delim :: Expr -> Message > delim e src tgt s > = "if (" ++ getByte src ++ " == " ++ e ++")" > ++ advanceByte src > > rangex :: Int -> Int -> [Int] > rangex i j > | i > j = [] > | otherwise = (i:(rangex (i+1) j)) > > > c_and [] = "" > c_and [pred] = "(" ++ pred ++ ")" > c_and (pred1:pred2:preds) = "(" ++ pred1 ++ " && " ++ c_and (pred2:preds) ++ ")" > > asc :: String -> String -> Message > asc chars value src tgt s > = c_if "" > (deref tgt ++ " == " ++ value ++ ";" ) > s > > skip :: Int -> Message > skip n src tgt s > = (deref tgt) ++ "= 1;" > ++ (advanceNBytes src n) > > -------------------------------------------------------------------------------- > > bs = newbitsource "A" "bit" > f = recordptr "target" > > > main = delim "6" bs f "abort();" > > > to_confidence = alt [ asc "HH" "High" > , asc "MM" "Medium" > , asc "LL" "Low" > , asc "NN" "None" > ] > > > -------------------------------------------------------------------------------- > -- Region > > -- This one doesn't work properly - > -- CPoints are difficult to manipulate as strings, hence the `hasVar` > -- problems, it gives some idea of the method though. > > > > module Region where > > import Data.Char ( isAlpha ) > import Data.List ( foldl' ) > > > -- Prolog > type CExpr = String > type CPred = String > type CFloat = Float > > infixr 6 ++& > (++&) :: Show a => String -> a -> String > s ++& a = s ++ show a > > > sqrdist _ = "" > > add :: CPoint -> CPoint -> CPoint > add a b = a ++ "+" ++ b > > sub :: CPoint -> CPoint -> CPoint > sub a b = a ++ "-" ++ b > > hasVar :: CExpr -> Bool > hasVar = any isAlpha > > cfst :: CPoint -> CExpr > cfst a | hasVar a = a ++ ".x" > | otherwise = "1.1" > > csnd :: CPoint -> CExpr > csnd a | hasVar a = a ++".y" > | otherwise = "2.2" > > pt :: (CFloat,CFloat) -> CPoint > pt = show > > intersect :: [Region] -> Region > intersect (r:rs) = foldl' (/\) r rs > intersect [] = error $ "intersect on empty list" > > > > -- presentation > > type CPoint = CExpr > type Region = CPoint -> CPred > > > circle :: CFloat -> Region > circle n = \p -> "(" ++ sqrdist p ++ "<" ++& n ++ "*" ++& n ++ ")" > > halfplane :: CPoint -> CPoint -> Region > halfplane a b = \p -> "(" ++ zcross (a `sub` p) (b `sub` a) ++ " > 0.0)" > where > zcross e1 e2 = > "(" ++ cfst e1 ++ "*" ++ csnd e2 ++ "-" ++ csnd e2 ++ "*" ++ > cfst e1 ++ ")" > > > (/\) :: Region -> Region -> Region > r1 /\ r2 = \p -> "(" ++ r1 p ++ " && " ++ r2 p ++ ")" > > (\/) :: Region -> Region -> Region > r1 \/ r2 = \p -> "(" ++ r1 p ++ " || " ++ r2 p ++ ")" > > at :: Region -> CPoint -> Region > r `at` p0 = \p -> r (p `sub` p0) > > convexPoly :: [CPoint] -> Region > convexPoly (p:ps) = > intersect (zipWith halfplane ([p] ++ ps) (ps ++ [p])) > > > tightZone :: CPoint -> CPred > tightZone = > (convexPoly [pt (0.0,5.0), pt (118.0,32.0), > pt (118.0,62.0), pt (0.0,25.0) ]) > \/ > (convexPoly [pt (118.0,32.0), pt (259.0,5.0), > pt (259.0, 25.0), pt (118.0,62.0)]) > > > main = tightZone e1 where > e1::CExpr > e1 = "p" > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From mambo.banda.ext at gmail.com Fri Jan 15 02:51:28 2010 From: mambo.banda.ext at gmail.com (Mambo Banda) Date: Fri Jan 15 02:25:14 2010 Subject: [Haskell-cafe] ANN: Lite Haskell IDE Message-ID: <4B501E80.2090407@gmail.com> Hi Just started an open source project called Hoodoo. It is meant to be a Lite IDE for Haskell. I wrote it to learn Haskell, so if you are a beginner (like me) it might interest you. If you're interested follow this link (http://hoodoo.kenai.com/), and if you like what you see, grab the code and add something:) Mambo From bulat.ziganshin at gmail.com Fri Jan 15 03:35:30 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Fri Jan 15 03:08:14 2010 Subject: [Haskell-cafe] Force -threaded from a library In-Reply-To: References: Message-ID: <135124210.20100115113530@gmail.com> Hello John, Friday, January 15, 2010, 1:42:15 AM, you wrote: > Is it possible to prevent a library from being used unless > -threaded is enabled? I have a specific case where lots-of-nasty yes. it's how opposite checked in gtk2hs: when (rtsSupportsBoundThreads) $ fail $ "\n" ++ "initGUI: Gtk+ is single threaded and so cannot safely be used from\n" ++ "multiple Haskell threads when using GHC's threaded RTS. You can\n" ++ "avoid this error by relinking your program without using the\n" ++ "'-threaded' flag. If you have to use the threaded RTS and are\n" ++ "absolutely sure that you only ever call Gtk+ from a single OS\n" ++ "thread then you can use the function: unsafeInitGUIForThreadedRTS\n" -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From stephen.tetley at gmail.com Fri Jan 15 03:53:34 2010 From: stephen.tetley at gmail.com (Stephen Tetley) Date: Fri Jan 15 03:26:03 2010 Subject: [Haskell-cafe] Re: Design question, HTML for GUIs? In-Reply-To: <4B4FBD0E.6080706@web.de> References: <4B4A1EBD.1080605@web.de> <4B4FBD0E.6080706@web.de> Message-ID: <5fdc56d71001150053w791eab4dp73dbf2f77ca1fd8@mail.gmail.com> 2010/1/15 G?nther Schmidt : > Thank you guys for all your responses. > > I just came accross something called HTML-Dialogs. It's mentioned in the > ANNOUNCE files of the 0.26 source package of HaskellDirect. Apparently it > takes about (on Windows) using HTML to create GUIs and scripting the > Internet Explorer via COM. > > That would eliminate the need to use a webserver. > > Does anyone here know more about it, I tried to google it, but guess how > much comes up when the only keywords you have is "Internet Explorer HTML > Dialogs". > Sounds like "Client-side web scripting with HaskellScript" - Erik Meijier, Daan Leijen and James Hook from PADL'99 http://research.microsoft.com/en-us/um/people/emeijer/publications/client-side-web-scripting.pdf http://www.haskell.org/haskellscript/ Best wishes Stephen From ketil at malde.org Fri Jan 15 03:54:21 2010 From: ketil at malde.org (Ketil Malde) Date: Fri Jan 15 03:26:49 2010 Subject: [Haskell-cafe] Typed Configuration Files In-Reply-To: <404396ef1001140939m6e8dbf5wf90cc0e8596362ac@mail.gmail.com> (Neil Mitchell's message of "Thu, 14 Jan 2010 17:39:21 +0000") References: <0102AD94-4A7C-47F0-A412-748FF4850448@informatik.uni-kiel.de> <87y6k0yjgu.fsf@malde.org> <404396ef1001140939m6e8dbf5wf90cc0e8596362ac@mail.gmail.com> Message-ID: <87r5prvjcy.fsf@malde.org> Neil Mitchell writes: > The CmdArgs manual might help: > http://community.haskell.org/~ndm/darcs/cmdargs/cmdargs.htm Yes, this is what I used :-) Presenting examples is great, but gives me the hubris to rip off the example that seems to fit most closely, and modify it. This makes for a quick start, but also for the odd misunderstanding. > I'd describe cmdargs as referentially impure, but really concise. Concise is nice - I've often been a bit annoyed that the otherwise nice GetOpt stuff forces me to write a lot of boilerplate, enough of it that my programs usually have a separate Options module. For a lazy slob like me, this means I often just hack something on top of the raw GetArgs or write half-baked but simple solutions like my simpleargs library. > 'def' is the default value, empty has a particular semantic meaning > and serves to change the options. I should document this more > carefully. Perhaps empty should be renamed 'optional', since that's > what it does. 'whenMissing'? 'unspecified'? >> - As I wanted a single file argument, I tried to use 'args' in >> ?combination with a parameter of type FilePath. ?Apparently 'args' >> ?wants [FilePath] and appends command line arguments to the default >> ?value. Spoilt by Haskell, I'd have expected a type error here. > argPos 0 should do the trick. Right. Will subsequent arguments be ignored? > CmdArgs is very much a 0.1 release. The documentation isn't polished, > it does simple arguments nicely, but has flaws when you try and go > more advanced. I want to spend some more time on it at some point. That's great, I'm looking forward to it. -k -- If I haven't seen further, it is by standing in the footprints of giants From ivan.miljenovic at gmail.com Fri Jan 15 07:20:50 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Fri Jan 15 06:53:22 2010 Subject: [Haskell-cafe] Quick, somebody do something! In-Reply-To: <20100114222114.GA25162@whirlpool.galois.com> (Don Stewart's message of "Thu, 14 Jan 2010 14:21:14 -0800") References: <20100114222114.GA25162@whirlpool.galois.com> Message-ID: <87fx67imot.fsf@gmail.com> Don Stewart writes: > While the month-old Go language makes the top 15? > > Methods considered unsound. You mean ranking languages wrt popularity, etc. by looking at the noise in the blogosphere isn't sound research? :p > > hjgtuyl: >> >> Haskell has dropped out of the top 50 at Tiobe [1]; how could this hapen? >> Let's start selling mobile phones that can only be programmed in Haskell >> :-) >> >> >> [1] http://www.tiobe.com/content/paperinfo/tpci/index.html >> >> >> -- >> Met vriendelijke groet, >> Henk-Jan van Tuyl >> >> >> -- >> http://Van.Tuyl.eu/ >> http://members.chello.nl/hjgtuyl/tourdemonad.html >> -- >> _______________________________________________ >> 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 -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From kinch1967 at me.com Fri Jan 15 07:23:06 2010 From: kinch1967 at me.com (Peter Green) Date: Fri Jan 15 06:56:13 2010 Subject: [Haskell-cafe] Re: Space Efficiency When Sorting a List of Many Lists In-Reply-To: <20100110210516.8A0F03244F8@www.haskell.org> References: <20100110210516.8A0F03244F8@www.haskell.org> Message-ID: <0D54968D-B3BF-48EF-B6E1-9DA9D7C461F9@me.com> 3. Re: Space Efficiency When Sorting a List of Many Lists (Heinrich Apfelmus) >>> Another interesting problem is starting from a file of single >>> wagers and >> trying to compress them (i.e. inverse of 'explosion'. I believe this >> problem is analogous to Set Cover and therefore NP-Complete. >> Heuristics >> are the order of the day here. > > Interesting indeed! What kind of heuristics do you employ there? It > seems quite difficult to me, somehow. One approach I *did* consider early on was to define a kind of 'Pseudo Hamming Distance': i.e. define PHD such that any two single combination wagers differing in one leg's entrant number have PSD = 1 e.g. 1, 2, 3, 4 --A 1, 1, 3, 4 --B 5, 1, 3, 4 --C A and B have PHD = 1 B and C have PHD = 1 A and C have PHD = 2, but PSD > 1 is not of interest here. Construct an adjacency list for all PHD = 1 -> an undirected graph where nodes are combinations and edges link combinations with PSD = 1- > one starts to see various interesting hypercube type structures in the graphviz plots which are analogous to grouped wagers. Easy enough to see this by working backwards from (say) 1+2+2/4+5+6/7+8+9/10+11+12, exploding it by CP, constructing the PHD=1 adjacency list, turning this into a DOT file and firing up graphviz. These graphviz pictures look very lovely to the human eye. Unfortunately, computational extraction of such features in graph spaghetti land, let-alone the issue of extracting maximal features seems to be infeasible before the arrival of Quantum Computers, Maxwell's Demons in every car engine, and Unicorns in the back garden. I also considered a set cover approach, but got a little dispirited when I sat down to compute the number of potential covering sets - CP of power sets of race field sizes! Essentially wager generation in multi-leg races works like this: (1) We have estimated win probabilities for the entrants in each of the race legs. Assume that I have a black box which produces these estimated probabilities. (2) We generate the CP of the entrant numbers in the race fields: Leg 1 Entants x Leg 2 Entrants x.. For each combination generated by the CP, we apply some formula to the probabilities associated with combination entrant numbers to arrive at a decision about whether or not that particular combination represents a viable wager. (3) If a combination does represent a viable wager, we then need to ensure that we have sized its wager amount in a correct and optimal manner. This gives output looking like: 1, 1, 2, 3 - $1.10 1, 1, 2, 4 - $1.20 . . 15, 15, 15, 12, - $0.35 Unfortunately these are hard to compress well - and that is ignoring issues of what to do about differing wager sizes when we can match two combinations for merging together. So one possible hack is to insert step 1(a) where we k-means cluster the win probabilities in each leg, such that we end up with multiple entrant numbers per cluster mean (which is a probability). We then proceed through steps 2 and 3, but instead of generating single combinations, we are now directly producing wagers which look like: 1+6+12/3+4+7/13+14 - $1.20 In this case, k-means clustering will have clustered 1,6,12 together with cluster mean/probability of (say) 0.1, etc. This a bit of a hack, as clearly it will result in the wagers not covering exactly the same single combinations as if we had generated pure single wagers without k-means clustering. Hence my interest in doing set comparisons! Another brute force greedy approach is to start with single combinations and do something like this: def merge_combinations(combinations): """Greedily merge all combinations on one field, then next field, etc. Parameter combinations is structured so: [[[1], [2], [3], [4], [5], [6], [7]], [[1], [2], [3], [4], [5], [6], [8]]] The input combinations are modified *in place*. After calling this method, combinations would become: [[[1], [2], [3], [4], [5], [6], [7,8]]] """ def rotate_left(combi): combi.append(combi.pop(0)) for do_it_seven_times in xrange(7): combinations.sort() k = 1 while k < len(combinations): if combinations[k-1][:6] == combinations[k][:6]: combinations[k-1][6].extend(combinations.pop(k)[6]) combinations[k-1][6].sort() else: k += 1 map(rotate_left, combinations) def merge_demo(): from pprint import pprint combis = [[[1], [1], [1], [2], [2], [12], [1]], [[1], [1], [1], [2], [6], [3], [1]], [[1], [1], [1], [2], [6], [6], [1]], [[1], [1], [1], [2], [6], [7], [1]], [[1], [1], [1], [2], [6], [7], [2]], [[1], [1], [1], [2], [6], [12], [1]], [[1], [1], [1], [2], [8], [7], [1]], [[1], [1], [1], [2], [8], [12], [1]], [[1], [1], [1], [2], [9], [3], [1]], [[1], [1], [1], [2], [9], [7], [1]], [[1], [1], [1], [2], [9], [12], [1]], [[1], [1], [1], [3], [2], [7], [1]], [[1], [1], [1], [3], [2], [12], [1]]] pprint(sorted(combis)) # 13 print len(combis) merge_combinations(combis) pprint(sorted(combis)) # -> # [[[1], [1], [1], [2], [6], [6], [1]], # [[1], [1], [1], [2], [6], [7], [1, 2]], # [[1], [1], [1], [2], [6, 8, 9], [12], [1]], # [[1], [1], [1], [2], [6, 9], [3], [1]], # [[1], [1], [1], [2], [8, 9], [7], [1]], # [[1], [1], [1], [2, 3], [2], [12], [1]], # [[1], [1], [1], [3], [2], [7], [1]]] # 7 print len(combis) print print combis = [[[13], [6, 10, 13], [3, 6], [4], [2, 8], [7], [1]], [[13], [6, 10, 13], [3, 6], [4], [9], [7], [1]], [[13], [6, 10, 13], [3, 6], [4], [6], [12], [1]], [[13], [6, 10, 13], [3, 6], [4], [6], [7], [1]], [[13], [6, 10, 13], [5, 10], [10], [2, 8], [7], [1]], [[13], [6, 10, 13], [5, 10], [10], [9], [7], [1]], [[2, 9], [11], [7, 13], [6, 12], [9], [12], [3]], [[2, 9], [11], [7, 13], [6, 12], [9], [12], [2]], [[2, 9], [11], [7, 13], [6, 12], [9], [12], [1]], [[2, 9], [11], [7, 13], [6, 12], [9], [7], [5, 8, 14]], [[2, 9], [11], [7, 13], [6, 12], [9], [7], [7]], [[2, 9], [11], [7, 13], [6, 12], [9], [7], [4]]] pprint(combis) # 12 print len(combis) merge_combinations(combis) # -> # [[[13], [6, 10, 13], [3, 6], [4], [2, 6, 8, 9], [7], [1]], # [[13], [6, 10, 13], [3, 6], [4], [6], [12], [1]], # [[13], [6, 10, 13], [5, 10], [10], [2, 8, 9], [7], [1]], # [[2, 9], [11], [7, 13], [6, 12], [9], [12], [1, 2, 3]], # [[2, 9], [11], [7, 13], [6, 12], [9], [7], [4, 5, 7, 8, 14]]] pprint(combis) # 5 print len(combis) I wrote a version of this in PLT Scheme also a while back. IIRC, I had to flip everything around and perform actions at the head of lists instead of at the tail of Python lists (more like arrays really). Will have to try my hand at a Haskell version later and see how it goes - although I have the suspicion that feeding such a routine 1M single combinations is going to run into all sorts of space issues. Unfortunately this approach never seems to result in more than a 10 x compression factor. Can do much better with the k-means approach - at the cost of missing some theoretically desirable combinations and betting on some spurious combinations. As always, would be very interested to hear if you have any ideas/ insights on first seeing this kind of problem. I'm almost certainly too fixed in my thinking due to long association with the wagering problem domain and probably cannot see the wood for the trees! > What I mean is that there are two ways to represent sets of wagers: > > * A list of single combinations -> [Row a] > * A list of compressed wagers -> [Row [a]] > > To perform set operations, you first convert the latter into the > former. > But the idea is that there might be a way of performing set operations > without doing any conversion. > > Namely, the compressed wagers are cartesian products which behave well > under intersection: the intersection of two compressed wagers is > again a > compressed wager > > intersectC :: Eq a => Row [a] -> Row [a] -> Row [a] > intersectC [] [] = [] > intersectC (xs:xrow) (ys:yrow) = > intersect xs ys : intersectC xrow yrow > > In formulas: > > intersect (cartesian x) (cartesian y) > = cartesian (intersectC x y) > > for compressed wagers x, y :: Row [a] with > > intersect = list intersection, for instance Data.List.intersect > cartesian = converts a compressed wager to a list of > single combinations > > > This allows you to intersect two lists of compressed wagers directly > > intersect' :: [Row [a]] -> [Row [a]] -> [Row [a]] > intersect' xs ys = filter (not . null) $ > [intersectC x y | x<-xs, y<-ys] > Unfortunately, the result will have quadratic size; but if you have > significantly less compressed wagers than single combinations, this > may > be worth a try. Not to mention that you might be able to compress the > result again. Thank you for the explanation. This approach is going to be quite useful for most reasonable sized input sets. I'm thinking of running this as part of a suite of web services in something like a JEOS instance with relatively limited RAM - so there are advantages to avoiding exploding to singles and using 100+MB with a Map. import Data.List (intersect) import Data.List.Split (splitOn) import System.Environment (getArgs) type Row a = [a] type CombisGroup = Row [Int] -- e.g. ["8+12,11,7+13,10","1+2+3,1+9,3+6,4"] --> -- [[[8,12],[11],[7,13],[10]],[[1,2,3],[1,9],[3,6],[4]]] fromCSV :: [String] -> [CombisGroup] fromCSV = map parseOneLine where parseOneLine = map parseGroup . splitOn "," where parseGroup = map read . splitOn "+" parseInput :: String -> [CombisGroup] parseInput = fromCSV . lines singleCombisCount :: [CombisGroup] -> Int singleCombisCount = sum . map cpCardinality -- e.g. CP xss yss having zero common elements: -- intersectC [[1,2],[1,3,4],[5]] [[1,2],[4,5,6],[3]] --> [[1,2],[4],[]] -- e.g. CP xss yss having two common elements [[1,4,5],[2,4,5]] : -- intersectC [[1,2],[3,4],[5]] [[1,2],[4,5,6],[3,5]] --> [[1,2],[4], [5]] intersectC :: Eq a => Row [a] -> Row [a] -> Row [a] intersectC [] [] = [] intersectC (xs:xrow) (ys:yrow) = intersect xs ys : intersectC xrow yrow -- e.g. no common elements: -- intersect' [[[1,2],[1,3,4],[5]],[[1,2],[7,11],[5]]] -- [[[1,2],[4,5,6],[3]],[[11],[7,11],[3,5]]] --> [] -- e.g. two common elements: -- intersect' [[[1,2],[1,3,9],[5]],[[1,2],[3,4],[5]]] -- [[[1,2],[4,5,6],[3,5]],[[11],[4,5,6],[3,5]]] --> -- [[[1,2],[4],[5]]] --> CP --> [[1,4,5], [2,4,5]] intersect' :: Eq a => [Row [a]] -> [Row [a]] -> [Row [a]] intersect' xs ys = filter (notElem []) [intersectC x y | x <- xs, y <- ys] -- e.g. [[8,12],[11],[7,13],[10]] --> 4 cpCardinality :: Row [a] -> Int cpCardinality = product . map length main = do [arg1, arg2] <- getArgs compressedA <- return . parseInput =<< readFile arg1 compressedB <- return . parseInput =<< readFile arg2 putStrLn $ "A source: " ++ arg1 putStrLn $ "B source: " ++ arg2 putStrLn $ "|A Intersect B|: " ++ show (singleCombisCount $ intersect' compressedA compressedB) -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100115/5bcf6a9b/attachment-0001.html From rodrigogribeiro at gmail.com Fri Jan 15 08:35:32 2010 From: rodrigogribeiro at gmail.com (Rodrigo Geraldo) Date: Fri Jan 15 08:08:01 2010 Subject: [Haskell-cafe] New blog: mainly Haskell and wxHaskell related In-Reply-To: References: Message-ID: <21ba18fc1001150535r5e299113wf52673213f428e38@mail.gmail.com> Hi Jeremy! It?s a very nice Idea! Could you put a tutorial on how to install wxhaskell on different operating systems? I?ve tried to install it on ubuntu 9.10 and I got some compilation errors due to the installation process can?t find the wxdirect executable... Regards Rodrigo On Mon, Jan 11, 2010 at 9:54 AM, Jeremy O'Donoghue < jeremy.odonoghue@gmail.com> wrote: > Hi all, > > I have just started a new blog at http://wewantarock.wordpress.com. > > At least initially, my intention is to provide a set of 'tutorial' > style articles to help new wxHaskell users get beyond the 'Hello > World' stage by offering a few worked examples on things you might > want to do to put together a usable application. The idea is to offer > something which fits between the first tutorial and the reference > documents. > > The first few postings will explain the anatomy of a complete custom > wxHaskell control written in Haskell. > > Comments gratefully accepted, including (gentle please - I'm not > dons!) criticism of my Haskell style. > > Regards > Jeremy O'Donoghue > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100115/65c929c2/attachment.html From mblazevic at stilo.com Fri Jan 15 09:26:33 2010 From: mblazevic at stilo.com (=?UTF-8?B?TWFyaW8gQmxhxb5ldmnEhw==?=) Date: Fri Jan 15 08:59:01 2010 Subject: [Haskell-cafe] Re: [Haskell] ANN: Streaming Component Combinators 0.4 In-Reply-To: <4B4F9C87.5000502@henning-thielemann.de> References: <".1262910550"@magma.ca> <4B4F9C87.5000502@henning-thielemann.de> Message-ID: <4B507B19.9090206@stilo.com> Henning Thielemann wrote: > Mario Bla?evi? schrieb: >> Version 0.4 of Streaming Component Combinators, or SCC for short, has >> been released on Hackage. Get it at >> >> http://hackage.haskell.org/package/scc >> >> There isn't much new high-level functionality compared to the >> previous version, but the implementation has been heavily refactored and >> the foundations completely replaced. > > Stupid question: Is it related to Arrows? Not really. You might say it's more general than arrows, because the streaming components are not restricted to a single input and single output type. On the other hand, they are all specific to stream processing, much like Fudgets and Yampa which are arrow-based. I suppose the Transducer data type [1] could be made an Arrow instance, which would let me rename the 'connect' combinator [2] to (>>>). I'll have a look at Yampa to see if I can harvest more combinator names, thank you! [1] http://hackage.haskell.org/packages/archive/scc/0.4/doc/html/Control-Concurrent-SCC-Types.html#t%3ATransducer [2] http://hackage.haskell.org/packages/archive/scc/0.4/doc/html/Control-Concurrent-SCC-Combinators.html#v%3Aconnect From vandijk.roel at gmail.com Fri Jan 15 09:45:56 2010 From: vandijk.roel at gmail.com (Roel van Dijk) Date: Fri Jan 15 09:18:23 2010 Subject: [Haskell-cafe] Hackage strangeness Message-ID: I wrote a small cronjob to update my hackage reverse-deps. When checking if it worked I noticed that my hackage appears to be more up-to-date than the real thing! Compare the "What's new" of both: Real hackage: http://hackage.haskell.org/packages/archive/recent.html Play thing: http://bifunctor.homelinux.net/~roel/hackage/packages/archive/recent.html At the time of writing this message the newest package on Hackage is dated Tue Jan 12 16:24:18 UTC 2010. The newest on my mirror is Thu Jan 14 20:07:04 UTC 2010. I thought that possibly the recent.html page wasn't being built, but when I follow an actual package, like vacuum-opengl the most recent version on hackage is 0.0.2 while on my mirror it is 0.0.3. Is this a case of data loss or something else? From Christian.Maeder at dfki.de Fri Jan 15 09:57:13 2010 From: Christian.Maeder at dfki.de (Christian Maeder) Date: Fri Jan 15 09:29:46 2010 Subject: [Haskell-cafe] Re: deleteBy type too restrictive In-Reply-To: <3defcb4e1001140549w3fc71633qaf0fcc9caef509ab@mail.gmail.com> References: <3defcb4e1001140549w3fc71633qaf0fcc9caef509ab@mail.gmail.com> Message-ID: <4B508249.5080706@dfki.de> There's already a ticket for this proposal http://hackage.haskell.org/trac/ghc/ticket/3399 Christian Dan Ros?n schrieb: > Hello, > > I realized today that the type for deleteBy in Data.List is too > restrictive. The code is: > > deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a] > deleteBy _ _ [] = [] > deleteBy eq x (y:ys) = if x `eq` y then ys else y : deleteBy eq x ys > > though the type deleteBy :: (b -> a -> Bool) -> b -> [a] -> [a] will do > good as well. > > Is there a particular reason that the type has this restriction? > Otherwise, where can I post a suggestion to have it untightened? > > Best regards, > Dan Ros?n > > references: > http://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/Data-List.html#v:deleteBy > http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.2.0.0/src/Data-List.html#deleteBy > > > ------------------------------------------------------------------------ > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From Malcolm.Wallace at cs.york.ac.uk Fri Jan 15 09:58:13 2010 From: Malcolm.Wallace at cs.york.ac.uk (Malcolm Wallace) Date: Fri Jan 15 09:31:41 2010 Subject: [Haskell-cafe] Hackage strangeness In-Reply-To: References: Message-ID: <7D2D5967-CBB9-414B-BC32-2F25A3476D79@cs.york.ac.uk> > At the time of writing this message the newest package on Hackage is > dated Tue Jan 12 16:24:18 UTC 2010. > The newest on my mirror is Thu Jan 14 20:07:04 UTC 2010. I believe the Hackage data is being migrated to a new physical server machine (from monk to abbot). This may involve some period of catch-up. Regards, Malcolm From vanenkj at gmail.com Fri Jan 15 10:03:56 2010 From: vanenkj at gmail.com (John Van Enk) Date: Fri Jan 15 09:36:24 2010 Subject: [Haskell-cafe] Force -threaded from a library In-Reply-To: <135124210.20100115113530@gmail.com> References: <135124210.20100115113530@gmail.com> Message-ID: Thanks Bulat, I hadn't even considered doing it that way. :) /jve On Fri, Jan 15, 2010 at 3:35 AM, Bulat Ziganshin wrote: > Hello John, > > Friday, January 15, 2010, 1:42:15 AM, you wrote: > > > Is it possible to prevent a library from being used unless > > -threaded is enabled? I have a specific case where lots-of-nasty > > yes. it's how opposite checked in gtk2hs: > > when (rtsSupportsBoundThreads) $ fail $ "\n" ++ > "initGUI: Gtk+ is single threaded and so cannot safely be used from\n" > ++ > "multiple Haskell threads when using GHC's threaded RTS. You can\n" ++ > "avoid this error by relinking your program without using the\n" ++ > "'-threaded' flag. If you have to use the threaded RTS and are\n" ++ > "absolutely sure that you only ever call Gtk+ from a single OS\n" ++ > "thread then you can use the function: unsafeInitGUIForThreadedRTS\n" > > > -- > Best regards, > Bulat mailto:Bulat.Ziganshin@gmail.com > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100115/7f793803/attachment.html From nicolas.pouillard at gmail.com Fri Jan 15 10:06:59 2010 From: nicolas.pouillard at gmail.com (Nicolas Pouillard) Date: Fri Jan 15 09:39:30 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: <29bf512f1001140832h346cdb6cs1b3dbf985b1abe16@mail.gmail.com> References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> <29bf512f1001140832h346cdb6cs1b3dbf985b1abe16@mail.gmail.com> Message-ID: <1263567332-sup-4421@ks> Excerpts from Michael Snoyman's message of Thu Jan 14 17:32:26 +0100 2010: > On Thu, Jan 14, 2010 at 5:42 PM, Jeremy Shaw wrote: > [...] > > I wonder if the 'Response' portion of WAI should support all three > > currently used methods: > > - lazy I/O > > - Enumerator > > - sendFile > > [...] > As for your proposal of three methods, I'm not sure if it's necesary. I > understand that we would want sendfile for speedy serving of files straight > from the filesystem, but it's fairly straight-forward to convert a lazy > bytestring into an enumerator, and I don't think we get a performance > penalty for doing so (if there's a benchmark otherwise, I'd be happy to see > it). It is indeed easy to convert a lazy bytestring to an enumerator. What is not easy IMHO is to manipulate enumerators. I don't know if it is an issue in the context of using Wai/Hack, but for instance writing hack middleware could become a lot less fun. To be very specific how would you adapt hack-middleware-gzip [1] ? Regarding the unsafeness of lazy IO. I would like to recall the existence of safe-lazy-io [2] which was announced and explained here [3]. Best regards, [1]: http://hackage.haskell.org/package/hack-middleware-gzip [2]: http://hackage.haskell.org/package/safe-lazy-io [3]: http://www.haskell.org/pipermail/haskell/2009-March/021133.html -- Nicolas Pouillard http://nicolaspouillard.fr From ross at soi.city.ac.uk Fri Jan 15 10:08:36 2010 From: ross at soi.city.ac.uk (Ross Paterson) Date: Fri Jan 15 09:40:09 2010 Subject: [Haskell-cafe] Hackage strangeness In-Reply-To: References: Message-ID: <20100115150836.GA21692@soi.city.ac.uk> On Fri, Jan 15, 2010 at 03:45:56PM +0100, Roel van Dijk wrote: > I wrote a small cronjob to update my hackage reverse-deps. When > checking if it worked I noticed that my hackage appears to be more > up-to-date than the real thing! > > [...] > > Is this a case of data loss or something else? It's in the process of moving to a new (and hopefully more reliable) host. From vandijk.roel at gmail.com Fri Jan 15 10:12:33 2010 From: vandijk.roel at gmail.com (Roel van Dijk) Date: Fri Jan 15 09:45:01 2010 Subject: [Haskell-cafe] Hackage strangeness In-Reply-To: <20100115150836.GA21692@soi.city.ac.uk> References: <20100115150836.GA21692@soi.city.ac.uk> Message-ID: > It's in the process of moving to a new (and hopefully more reliable) host. That is good news. Nice work! From lemming at henning-thielemann.de Fri Jan 15 10:40:46 2010 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Fri Jan 15 10:13:21 2010 Subject: [Haskell-cafe] space leaks and optimizations In-Reply-To: <2f9b2d31001131711j43167935r9860a2c2606e96e8@mail.gmail.com> References: <4B471126.4010807@iqi.caltech.edu> <3e1162e61001080717i25e54a1bl16c983d0e8ebc68d@mail.gmail.com> <4B485910.7070701@iqi.caltech.edu> <2f9b2d31001131711j43167935r9860a2c2606e96e8@mail.gmail.com> Message-ID: <4B508C7E.5050106@henning-thielemann.de> Ryan Ingram schrieb: > Hi Alexei, you have a ton of great points but I wanted to discuss an > issue with this one. > > It's unusual that this is what you want either; since it only reduces > the state to WHNF. For example, if your state is a string, this only > evaluates enough to know whether or not the string is empty at each > step, and you can still get into trouble with code like this: > > put ("xxx" ++ some_bad_computation) > > which leave bottoms inside of your state which won't show up until later. > > Several attempts to solve this problem exist, but the most commonly > used one is the "rnf" strategy from Control.Parallel.Strategies, which > uses a typeclass to allow each type to specify how to evaluate itself > completely. Now available without parallelism in http://hackage.haskell.org/packages/archive/deepseq/1.1.0.0/doc/html/Control-DeepSeq.html I think that one should generally think before using seq, because it is only strict in the top most constructor. If you know the type you 'seq' on, then you might use a 'case' on it instead and can precisely control the depth of the strictness. Otherwise you might use 'rnf'. I have also some problems with space leaks. Recently I found a space leak in my code, that was because a finalizer did not run as expected. Now I'm seeking more information on how to use finalizers correctly ... From martijn at van.steenbergen.nl Fri Jan 15 11:27:00 2010 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Fri Jan 15 10:59:33 2010 Subject: [Haskell-cafe] Visualizing function application Message-ID: <4B509754.3030107@van.steenbergen.nl> Dear caf?, I am deeply impressed with Vacuum[1][2], Ubigraph[3] and especially their combination[4]. I can trivially and beautifully visualize the ASTs that my parser produces. I can visualize zippers of the ASTs and confirm that sharing is optimal. Ubigraph is also able to animate graph *mutations*, as shown by the various demos on Ubigraph's website. How cool would it be if we could tell vacuum-ubigraph: here, show this tree, and then show how the tree changes when we apply this function on it. We could see how [1,2,3] is transformed into a ring when cycle is applied on it, or we could see how a list is consumed node by node when a foldr is applied. I have no idea how difficult this is or how to begin, so I thought I'd throw the idea out here. Perhaps it is appealing enough that someone picks it up and implements it. :-) Martijn. [1] http://hackage.haskell.org/package/vacuum [2] http://www.youtube.com/watch?v=oujaqo9GAmA [3] http://ubietylab.net/ubigraph/content/Demos/index.html [4] http://hackage.haskell.org/package/vacuum-ubigraph From saul.malesac at gmail.com Fri Jan 15 12:08:26 2010 From: saul.malesac at gmail.com (Saul Malesac) Date: Fri Jan 15 11:40:56 2010 Subject: [Haskell-cafe] IDL - compilers In-Reply-To: <4B4FBEE5.10505@web.de> References: <4B4FBBA2.2050609@web.de> <20100115010025.GB25621@whirlpool.galois.com> <4B4FBEE5.10505@web.de> Message-ID: <59940e501001150908r771924a1la00958493a469088@mail.gmail.com> Yes please (bis) ! 2010/1/15 G?nther Schmidt : > Hi Don, > > Am 15.01.10 02:00, schrieb Don Stewart: >> >> gue.schmidt: >> >>> >>> Hi, >>> >>> are there any IDL compilers that can create Haskelk modules from header >>> files or type-libs? >>> >>> >> >> The venerable hdirect. http://www.haskell.org/hdirect/ >> >> I've recently cabalized the package, which is still in fine condition. >> Let me know if you need a copy. >> > > Oh yes!, please!, pretty please! > >> -- Don >> > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- Saul From sjurberengal at gmail.com Fri Jan 15 13:10:00 2010 From: sjurberengal at gmail.com (Sjur =?iso-8859-1?q?Gj=F8stein_Karevoll?=) Date: Fri Jan 15 12:42:37 2010 Subject: [Haskell-cafe] AlternativePrelude extension Message-ID: <201001151910.00488.sjurberengal@gmail.com> Here's an idea I'd like to air: A new extension called AlternativePrelude. Like the NoImplicitPrelude extension we have already, this would disable implicitly importing the Prelude in every other module, but would also implicitly import a substitute. The purpose is to make it easier to play around with alternative preludes. Today we have to specify NoImplicitPrelude, but also explicitly import our alternative everywhere, making the transition between the different preludes that much more painful. With this new extension, the alternative prelude can be specified in the cabal file, or on the command line when building. This will hopefully make the alternative prelude efforts a little bit more mainstream, giving us more data we can use to consider modifications to the current standard prelude. I'm thinking the syntax would be something like AlternativePrelude="MyPrelude". This is new among the extensions in that it requires a parameter. An alternative is an ImplicitImport extension that doesn't disable the implicit importing of the Prelude, but while this does serve the same purpose as the AlternativePrelude proposal, I think it might be easier to use it for nefarious purposes. -- Sjur Gj?stein Karevoll From dnmehay at gmail.com Fri Jan 15 13:20:19 2010 From: dnmehay at gmail.com (DNM) Date: Fri Jan 15 12:52:47 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <27139612.post@talk.nabble.com> References: <27139612.post@talk.nabble.com> Message-ID: <27181396.post@talk.nabble.com> Hi all, I got it to work...finally. Basically, I used Malcolm's suggestion of tracking down all the SRILM .o files needed. I need to run now, but I'll post the gory (oh, so gory) details soon. Thanks to all who helped. Best, D.N. -- View this message in context: http://old.nabble.com/FFI%2C-C-C%2B%2B-and-undefined-references-tp27139612p27181396.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From ross at soi.city.ac.uk Fri Jan 15 13:56:20 2010 From: ross at soi.city.ac.uk (Ross Paterson) Date: Fri Jan 15 13:27:18 2010 Subject: [Haskell-cafe] Hackage strangeness In-Reply-To: <20100115150836.GA21692@soi.city.ac.uk> References: <20100115150836.GA21692@soi.city.ac.uk> Message-ID: <20100115185620.GA30394@soi.city.ac.uk> On Fri, Jan 15, 2010 at 03:08:36PM +0000, Ross Paterson wrote: > It's in the process of moving to a new (and hopefully more reliable) host. Done. From niklas.broberg at gmail.com Fri Jan 15 14:57:55 2010 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Fri Jan 15 14:30:23 2010 Subject: [Haskell-cafe] ANN: haskell-src-exts 1.7.0 Message-ID: Fellow Haskelleers, As I was asked to start spamming again, I'm hereby pleased to announce the release of haskell-src-exts-1.7.0! * On hackage: http://hackage.haskell.org/package/haskell-src-exts * Via cabal: cabal install haskell-src-exts * Darcs repo: http://code.haskell.org/haskell-src-exts For users of hsx, this version works fine with hsx-0.6.1. Since I haven't sent out one of these announcements in a while, here's the complete CHANGELOG since the previous announcement: ** 1.7.x 1.6.1 --> 1.7.0 =============== * Operators defined on the form (a `op` b) c = ... could not be handled by the (annotated) AST, nor the parser. I had to change the definition of the AST node for InfixMatch to allow a list of right-hand subpatterns, i.e. InfixMatch l (Pat l) (Name l) (Pat l) ... has become InfixMatch l (Pat l) (Name l) [Pat l] ... I also had an epiphany and fixed the issue that would arise with exact printing of prefix definitions including parentheses (e.g. (foo x) y = ...), so that now works too! ** 1.6.x 1.6.0 --> 1.6.1 =============== * UnicodeSyntax now works not only for identifiers, but also for ->, <- and =>, as well as Arrows arrows and kind stars. (And before you send me bug reports for this one, do check that your version of readFile is Unicode aware, i.e. you use GHC 6.12 or the utf8-string version). 1.5.3 --> 1.6.0 =============== * (=~=) turns out to be too general at Functor (for intuitive and not technical reasons), so is specialised to Annotated to closer mirror the original intention. * applyFixities is hoisted to a monad, and now fails on ambiguous infix expressions. ** 1.5.x 1.5.2 --> 1.5.3 =============== * Several small bug fixes in the exact printer, and fail more gracefully if the number of srcInfoPoints doesn't match the needs of the node. 1.5.1 --> 1.5.2 =============== * Fix a bug in the exact printer that made it always print the first token at position (0,0). * In fixing the above, Annotated is now a superclass of ExactP. It was already a superclass in spirit, and nothing can break from this since ExactP is only exported abstractly. 1.5.0 --> 1.5.1 =============== * The pretty printer now introduces parentheses for non-atomic arguments to function application. Note that infix applications are left untouched, no parentheses will be inserted there, as it is assumed that fixities are already properly resolved. * Fix a bug in the pretty printer where view patterns and n+k patterns were not properly parenthesised. 1.4.0 --> 1.5.0 =============== * Add support for acting on LINE pragmas while parsing, i.e. updating the source position according to info given in LINE pragmas. This is done conditionally based on a new flag ignoreLinePragmas in the ParseMode, hence the need to increase the major version. ** 1.4.x 1.3.5 --> 1.4.0 =============== * The AST node for Proc in the simple AST is changed to include a SrcLoc argument, to make it consistent with similar nodes e.g. Lambda. This is specifically needed for transformation of patterns in HSX. ** 1.3.x 1.3.4 --> 1.3.5 =============== * Added an entry point in the parser for statements, and an instance Parseable Stmt to go with it. * Ensured that .Annotated exports all relevant parseXXX(WithYYY) functions. 1.3.3 --> 1.3.4 =============== * Operator fixities are now resolved in patterns. 1.3.2 --> 1.3.3 =============== * Fixes a bug where qualified keywords are rejected even if the extension that enables the keyword in question is not turned on. 1.3.0 --> 1.3.2 =============== (Let's forget 1.3.1 ever existed.) * Fix a bug where declarations of infix operators were not properly merged as FunBinds. From niklas.broberg at gmail.com Fri Jan 15 15:16:03 2010 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Fri Jan 15 14:48:29 2010 Subject: [Haskell-cafe] Haddock question: hiding internal instances Message-ID: Hi all, The question I have is this: How can I get Haddock to omit listing instances of package-internal data types for exported classes? Here's an example of what I mean: http://hackage.haskell.org/packages/archive/haskell-src-exts/1.6.0/doc/html/Language-Haskell-Exts-Pretty.html#t%3APretty At the very end of the rather extensive list of instances, you'll find the following: SrcInfo loc => Pretty (PAsst loc) SrcInfo loc => Pretty (PType loc) SrcInfo loc => Pretty (PContext loc) SrcInfo loc => Pretty (ParseXAttr loc) SrcInfo loc => Pretty (PFieldUpdate loc) SrcInfo loc => Pretty (PExp loc) All these data types are internal to the package, and the module they live in is marked with 'hide'. As expected no links are generated to any documentation for these data types, but I want them removed from this list entirely. They are internal after all, so what's the point of listing them? How can I achieve this? Cheers, /Niklas From david.waern at gmail.com Fri Jan 15 15:24:05 2010 From: david.waern at gmail.com (David Waern) Date: Fri Jan 15 14:56:35 2010 Subject: [Haskell-cafe] Haddock question: hiding internal instances In-Reply-To: References: Message-ID: 2010/1/15 Niklas Broberg : > Hi all, > > The question I have is this: How can I get Haddock to omit listing > instances of package-internal data types for exported classes? You currently can't, unfortunately. See: http://trac.haskell.org/haddock/ticket/37 David From ross at soi.city.ac.uk Fri Jan 15 15:29:28 2010 From: ross at soi.city.ac.uk (Ross Paterson) Date: Fri Jan 15 15:00:27 2010 Subject: [Haskell-cafe] Haddock question: hiding internal instances In-Reply-To: References: Message-ID: <20100115202928.GA32525@soi.city.ac.uk> On Fri, Jan 15, 2010 at 09:16:03PM +0100, Niklas Broberg wrote: > The question I have is this: How can I get Haddock to omit listing > instances of package-internal data types for exported classes? It's a known limitation: http://trac.haskell.org/haddock/ticket/37 From niklas.broberg at gmail.com Fri Jan 15 15:39:52 2010 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Fri Jan 15 15:12:18 2010 Subject: [Haskell-cafe] Haddock question: hiding internal instances In-Reply-To: References: Message-ID: >> The question I have is this: How can I get Haddock to omit listing >> instances of package-internal data types for exported classes? > > You currently can't, unfortunately. See: > > ?http://trac.haskell.org/haddock/ticket/37 Roger that, cc added. Cheers, /Niklas From bulat.ziganshin at gmail.com Fri Jan 15 15:44:31 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Fri Jan 15 15:19:39 2010 Subject: [Haskell-cafe] ANN: haskell-src-exts 1.7.0 In-Reply-To: References: Message-ID: <824628553.20100115234431@gmail.com> Hello Niklas, Friday, January 15, 2010, 10:57:55 PM, you wrote: > * UnicodeSyntax now works not only for identifiers, but also for does this mean that unicode identifiers are allowed only when UnicodeSyntax enabled? ghc allows them anyway -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From niklas.broberg at gmail.com Fri Jan 15 15:58:43 2010 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Fri Jan 15 15:31:11 2010 Subject: [Haskell-cafe] ANN: haskell-src-exts 1.7.0 In-Reply-To: <824628553.20100115234431@gmail.com> References: <824628553.20100115234431@gmail.com> Message-ID: >> * UnicodeSyntax now works not only for identifiers, but also for > > does this mean that unicode identifiers are allowed only when > UnicodeSyntax enabled? ghc allows them anyway Well spotted, that was poorly worded of me. haskell-src-exts works like GHC, allowing Unicode identifier always and Unicode keywords/keysymbols when UnicodeSyntax is enabled. Cheers, /Niklas From schlepptop at henning-thielemann.de Fri Jan 15 17:36:56 2010 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Fri Jan 15 17:09:54 2010 Subject: [Haskell-cafe] Re: [Haskell] ANN: Streaming Component Combinators 0.4 In-Reply-To: <4B507B19.9090206@stilo.com> References: <".1262910550"@magma.ca> <4B4F9C87.5000502@henning-thielemann.de> <4B507B19.9090206@stilo.com> Message-ID: <4B50EE08.20106@henning-thielemann.de> Mario Bla?evi? schrieb: > Henning Thielemann wrote: >> >> Stupid question: Is it related to Arrows? > > Not really. You might say it's more general than arrows, because > the streaming components are not restricted to a single input and > single output type. On the other hand, they are all specific to stream > processing, much like Fudgets and Yampa which are arrow-based. Arrows use tuple values for multiple inputs and outputs. Actually I'm using arrows this way for signal processing. > I suppose the Transducer data type [1] could be made an Arrow > instance, which would let me rename the 'connect' combinator [2] to > (>>>). I'll have a look at Yampa to see if I can harvest more > combinator names, thank you! > > > [1] > http://hackage.haskell.org/packages/archive/scc/0.4/doc/html/Control-Concurrent-SCC-Types.html#t%3ATransducer > > [2] > http://hackage.haskell.org/packages/archive/scc/0.4/doc/html/Control-Concurrent-SCC-Combinators.html#v%3Aconnect > In whatever way it is related to arrows, maybe you can mention it on the project page. From niklas.broberg at gmail.com Fri Jan 15 18:13:51 2010 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Fri Jan 15 17:46:18 2010 Subject: [Haskell-cafe] Re: ANN: haskell-src-exts 1.7.0 In-Reply-To: References: Message-ID: > * UnicodeSyntax now works not only for identifiers, but also for > ?->, <- and =>, as well as Arrows arrows and kind stars. (And > ?before you send me bug reports for this one, do check that your > ?version of readFile is Unicode aware, i.e. you use GHC 6.12 > ?or the utf8-string version). ... and with the newly released 1.7.1, UnicodeSyntax now also enables the fancy ? to mean forall. Cheers, /Niklas From schlepptop at henning-thielemann.de Fri Jan 15 18:42:39 2010 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Fri Jan 15 18:15:39 2010 Subject: [Haskell-cafe] Capped lists and |append| In-Reply-To: <3283f7fe1001081538w5d390c14mf5ac33dfc4436be2@mail.gmail.com> References: <3283f7fe1001081538w5d390c14mf5ac33dfc4436be2@mail.gmail.com> Message-ID: <4B50FD6F.2010600@henning-thielemann.de> John Millikin schrieb: > Earlier today I uploaded the capped-list package; I didn't think there > would be any interest, since it's a relatively trivial data structure, > but already there's been three emails and an IRC convo about it. > > In short, this is Heinrich Apfelmus's "Train" type from > , > which showed up in a thread I posted regarding lazy error handling > . > The structure of a Train / CappedList (I like my name better) is: > > data Train a b = Wagon a (Train a b) | Loco b > data CappedList cap a = Next a (CappedList cap a) | Cap cap > > Since uploading, there's been a big problem pointed out to me > regarding this structure, namely the possible definitions of |append|. > Because the list terminus is itself a value, but isn't / shouldn't be > the same type as the elements, either obvious implementation will drop > it. > > append :: CappedList cap a -> CappedList cap a -> CappedList cap a > append (Cap 0) (Cap 1) = -- either (Cap 0) or (Cap 1), but > information has been lost > > For exception handling I need append :: CappedList (Maybe exception) a -> CappedList (Maybe exception) a -> CappedList (Maybe exception) a where 'append' appends the second list only, if the first list did not end with an exception. From taruti at taruti.net Fri Jan 15 23:40:06 2010 From: taruti at taruti.net (Taru Karttunen) Date: Fri Jan 15 23:12:33 2010 Subject: [Haskell-cafe] From records to a type class Message-ID: <1263616111-sup-5031@oz.taruti.net> Hello I am wrapping Fuse in a pure Haskell binding and have some issues with the interface. Currently I am using a record for managing the callback functions, but I think there may be a more elegant formulation. Any ideas how to formulate the Fuse record as a typeclass elegantly? Some notes: + TFs not FDs. + Separate fh* implementations (raw/stableptr/custom implemented by user) easily selected by the library user. + Readable type errors. + One large typeclass + overlapping instances works, but seems hacky. + MPTCs will probably work but is it good form to use them with TFs? + Or is using a record better currently? ps. Note that the interface is very much simplified for the sake of the discussion. (e.g. [Word8] instead of ByteString). > import Data.Word > > data IsDir > data IsFile > > type Ino = Word32 > data Attr = Attr {} > > data Fuse (fh :: * -> *) = Fuse { > open :: Ino -> IO (fh IsFile) > , read :: Ino -> fh IsFile -> Word64 -> Word32 -> IO [Word8] > , opendir :: Ino -> IO (fh IsDir) > , getattr :: forall fileOrDir. Ino -> fh fileOrDir -> IO Attr > -- ... > > -- File handle management > , fhFree :: Word64 -> IO () > , fhAlloc :: forall any. fh any -> IO Word64 > , fhRef :: forall any. Word64 -> IO (fh any) > } > > -- Optimally get rid of this wrapping... > newtype RawFH t = R { r :: Word64 } > noFhEmpty :: Fuse RawFH > noFhEmpty = Fuse { fhFree = \_ -> return () > , fhAlloc = return . r > , fhRef = return . R > } > > stablePtrEmpty :: Fuse anyfh > stablePtrEmpty = Fuse {} -- implement fh* with StablePtrs (omitted) > > -- User file handle type might be like this: > > data Obj t where > Dir :: {} -> Obj IsDir > File :: {} -> Obj IsFile - Taru Karttunen From stephen.tetley at gmail.com Sat Jan 16 03:27:33 2010 From: stephen.tetley at gmail.com (Stephen Tetley) Date: Sat Jan 16 03:00:00 2010 Subject: [Haskell-cafe] From records to a type class In-Reply-To: <1263616111-sup-5031@oz.taruti.net> References: <1263616111-sup-5031@oz.taruti.net> Message-ID: <5fdc56d71001160027t4179379gcb8c6e449ac0e307@mail.gmail.com> Hi Taru If you haven't obviously got dispatch on type then records are certainly fine. Some obigatory examples: http://www.cas.mcmaster.ca/~kahl/Publications/TR/2000-01/Kahl-Braun-Scheffczyk-2000a.pdf (see the Editor type page 13) http://www.cas.mcmaster.ca/~kahl/Publications/Conf/Kahl-1999a.pdf http://web.cecs.pdx.edu/~sheard/papers/JfpPearl.ps Parsec's Text.ParserCombinators.Parsec.Token module is an example that has seen widespread use. http://hackage.haskell.org/packages/archive/parsec/2.1.0.1/doc/html/Text-ParserCombinators-Parsec-Token.html Best wishes Stephen From taruti at taruti.net Sat Jan 16 09:19:57 2010 From: taruti at taruti.net (Taru Karttunen) Date: Sat Jan 16 08:52:22 2010 Subject: [Haskell-cafe] From records to a type class In-Reply-To: <5fdc56d71001160027t4179379gcb8c6e449ac0e307@mail.gmail.com> References: <1263616111-sup-5031@oz.taruti.net> <5fdc56d71001160027t4179379gcb8c6e449ac0e307@mail.gmail.com> Message-ID: <1263650910-sup-7489@oz.taruti.net> Excerpts from Stephen Tetley's message of Sat Jan 16 10:27:33 +0200 2010: > If you haven't obviously got dispatch on type then records are certainly fine. Yes, no dispatch on type. I got a class based implementation compiling, but it seems overly complex. Maybe the record approach is better after all. This is a bit more complex than Parsec unfortunately. (an analogue would be adding encodings to the types of Parsec parsers) import Data.Word data IsDir data IsFile type Ino = Word32 data Attr = Attr {} data Proxy t type family FT (fht :: ((* -> *) -> *)) (fd :: *) class FH (t :: (* -> *) -> *) where fhFre :: Proxy t -> Word64 -> IO () fhAllo :: forall any. FT t any -> IO Word64 fhRe :: forall any. Word64 -> IO (FT t any) data UseRaw :: ((* -> *) -> *) type instance FT UseRaw any = Word64 instance FH UseRaw where fhFre _ _ = return () fhAllo = return fhRe = return data UseStablePtr :: (* -> *) -> (* -> *) -> * type instance FT (UseStablePtr ty) fh = ty fh instance FH (UseStablePtr ty) where -- omitted class FH (FhImpl ty) => Fuse' ty where type FhImpl ty :: (* -> *) -> * open' :: ty -> Ino -> IO (FT (FhImpl ty) IsFile) read' :: ty -> Ino -> FT (FhImpl ty) IsFile -> Word64 -> Word32 -> IO [Word8] opendir' :: ty -> Ino -> IO (FT (FhImpl ty) IsDir) getattr' :: forall fileOrDir. ty -> Ino -> FT (FhImpl ty) fileOrDir -> IO Attr data MyUserType = MyUserType instance Fuse' MyUserType where type FhImpl MyUserType = UseRaw open' = \_ _ -> return 22 - Taru Karttunen From jon at ffconsultancy.com Sat Jan 16 12:50:11 2010 From: jon at ffconsultancy.com (Jon Harrop) Date: Sat Jan 16 11:07:43 2010 Subject: [Haskell-cafe] =?iso-8859-1?q?Na=EFve_Parallelization=3A_C++_vs?= Haskell Message-ID: <201001161750.11839.jon@ffconsultancy.com> I felt the previous comparison left a little to be desired so I have repeated the experiment on 8 cores using the original Haskell code and giving results for 9, 12 and 13 levels of spheres: http://flyingfrogblog.blogspot.com/2010/01/naive-parallelization-c-vs-haskell.html -- Dr Jon Harrop, Flying Frog Consultancy Ltd. http://www.ffconsultancy.com/?e From will_n48 at yahoo.com Sat Jan 16 12:53:33 2010 From: will_n48 at yahoo.com (Will Ness) Date: Sat Jan 16 12:26:24 2010 Subject: [Haskell-cafe] Re: FASTER primes References: <201001131233.23024.daniel.is.fischer@web.de> <201001141202.37294.daniel.is.fischer@web.de> Message-ID: Daniel Fischer web.de> writes: > > Am Donnerstag 14 Januar 2010 08:25:48 schrieb Will Ness: > > Daniel Fischer web.de> writes: > > > Am Mittwoch 13 Januar 2010 10:43:42 schrieb Heinrich Apfelmus: > > > > I wonder whether it's really the liveness of ?pair ?in > > > > > > > > ? mergeSP (a,b) pair > > > > ? ? ?= let sm = spMerge b (fst pair) > > > > ? ? ? ?in (a ++ fst sm, merge (snd sm) (snd pair)) > > > > > > > > that is responsible for the space leak, ... > > > > > > I think that is responsible. At least that's how I understand the > > > core: > > > > > > mergeSP (a,b) ~(c,d) = (a ++ bc, merge b' d) > > > where > > > (bc, b') = spMerge b c > > > spMerge ... > > > > That is equivalent to > > > > first (a++) . second (`merge`d) $ spMerge b c > > > > and Daniel's fix is equivalent to > > > > first (a++) $ spMerge b c d > > That should've been mergeSP (a,b) p = first(a++) . second(`merge`snd p) $ spMerge b (fst p) and mergeSP (a,b) p = first(a++) $ spMerge b (fst p) (snd p) The code fragments you've posted are essentially mergeSP (a,b) p = let res = case p of (c,_) -> case spMerge b c of (# x,y #) -> (x,y) in (# (++) a (case res of (bc,_)-> bc) , case res of (_,b') -> case p of (_,d) -> merge b' d #) and mergeSP (a,b) p = let res = case p of (c,d) -> case spMerge b c d of (# x,y #) -> (x,y) in (# (++) a (case res of (bc,_)-> bc) , case res of (_,b') -> b' #) This looks like Haskell to me, with many detailes explicitely written out, probaly serving as immediate input to the compiler - not its output. So it can't say to us much about how this is actually implemented on the lower level. (?) Your theory would certainly hold if the translation was done one-to-one without any further code rearrangements. But it could've been further re-arranged by the compiler at some later stage (is there one?) into an equivalent of, e.g. mergeSP (a,b) p = let (bc,b') = case p of (c,_) -> case spMerge b c of (x,y) -> (x,y) in (# (++) a bc , case p of (_,d) -> merge b' d #) and further, mergeSP (a,b) p = let (c,d) = case p of (x,y) -> (x,y) (bc,b') = case spMerge b c of (x,y) -> (x,y) in (# (++) a bc , merge b' d #) could it? This would take hold on /d/ and /c/ at the same time, right? What is that code that you've shown exactly? At which stage is it produced and is it subject to any further manipulation? I apologise if these are obvious questions, I don't know anything about GHC. I also don't know what (# x,y #) means? One thing seems certain - we should not hold explicit references to same entities in different parts of our code, to avoid space leaks with more confidence. To make code look as much tail-recursive as possible, so to speak. Does that make sense? Anyway that was a very educational (for me) and fruitful discussion, and I greatly appreciate your help, and fixing and improving of the code. Thanks! From schlepptop at henning-thielemann.de Sat Jan 16 13:20:43 2010 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Sat Jan 16 12:53:49 2010 Subject: [Haskell-cafe] addFinalizer to which object? Message-ID: <4B52037B.5020206@henning-thielemann.de> The documentation of System.Mem.Weak.addFinalizer suggests to me, that this function is very fragile, because the object we track, might be optimized away. In my case this applies. I have a resource that is needed for generating chunks of a lazy byte string. If the byte string is created completely or the byte string cannot be accessed anymore, this resource must be freed. It must also be freed within Haskell code, thus addForeignPtrFinalizer does not help. To illustrate that I have attached a small example, where I use a StablePtr as resource, that points to a list. This Haskell list is read from C code and written to a chunk of a lazy ByteString. A Haskell function creates the ByteString lazily and calls the C function for every new chunk. I have added a finalizer to the StablePtr itself. That works without optimization, but using optimization the finalizer is run immediately and the program aborts with segmentation fault. Thus my question: How to get reliable finalization? -------------- next part -------------- #include "ProcessList_stub.h" /* The function copies elements from a Haskell list to a piece of memory and returns the number of bytes that could be fetched. */ int copy_list_to_chunk (unsigned long int n, HsStablePtr list, char *p) { unsigned long int k = n; while (k>0) { if (!get_next_element(list, p)) {break; } p++; k--; } return (n-k); } -------------- next part -------------- {- # generate C stubs ghc -c ProcessList.hs # generate executable ghc -O --make ProcessChunk.c ProcessList.hs -} {- Use a C function for filling chunks of a lazy ByteString with data from a Haskell list. A StablePtr is needed to pass the list to C and back to Haskell. Somehow we must assert that the StablePtr is deleted and the list can be garbage collected, once the ByteString is constructed. We concatenate infinitely many such lists, thus many StablePtrs and referenced lists must be freed. Use addFinalizer? To which object shall I add the finalizer? Without optimization adding the finalizer to the StablePtr works, with optimization, its finalizer is run too early. I also tried to add the finalizer to the end of the list, which is not quite correct, but then the finalizer is run never. Whatever I tried: Finalizer is run immediately or never. What is the right way? -} {-# LANGUAGE ForeignFunctionInterface #-} module Main where import qualified Data.ByteString as B import qualified Data.ByteString.Internal as BI import qualified Data.ByteString.Lazy as BL import qualified Data.ByteString.Lazy.Internal as BLI import System.IO.Unsafe (unsafePerformIO, unsafeInterleaveIO, ) import System.Mem.Weak (addFinalizer, ) import Foreign.StablePtr (StablePtr, newStablePtr, freeStablePtr, deRefStablePtr, ) import Foreign.Storable (poke, ) import Foreign.C.Types (CULong, ) import Foreign.Ptr (FunPtr, Ptr, nullPtr, castPtr, ) import Data.IORef (IORef, newIORef, readIORef, writeIORef, ) import Data.Word (Word8, Word32, ) import Control.Monad (liftM2, ) getNextElement :: StablePtr (IORef [Word8]) -> Ptr Word8 -> IO Bool getNextElement stable elemPtr = do listRef <- deRefStablePtr stable xt <- readIORef listRef case xt of [] -> return False x:xs -> do poke elemPtr x writeIORef listRef xs return True foreign export ccall "get_next_element" getNextElement :: StablePtr (IORef [Word8]) -> Ptr Word8 -> IO Bool foreign import ccall "copy_list_to_chunk" copyListToChunk :: CULong -> StablePtr (IORef [Word8]) -> Ptr Word8 -> IO CULong chunkSize :: Int chunkSize = 13 byteStringFromList :: [Word8] -> BL.ByteString byteStringFromList list = unsafePerformIO $ do stable <- newStablePtr =<< newIORef list addFinalizer stable (putStrLn "free stable pointer" >> freeStablePtr stable) let go = unsafeInterleaveIO $ do v <- BI.createAndTrim chunkSize $ fmap fromIntegral . copyListToChunk (fromIntegral chunkSize) stable fmap (BLI.chunk v) $ if B.length v < chunkSize then return BL.empty else go go main :: IO () main = print $ BL.unpack $ -- BL.take 1000 $ BL.concat $ map (BL.take 42 . byteStringFromList . iterate (1+)) (iterate (1+) 0) From schlepptop at henning-thielemann.de Sat Jan 16 13:40:01 2010 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Sat Jan 16 13:13:02 2010 Subject: [Haskell-cafe] Re: Data.Ring -- Pre-announce In-Reply-To: <4B491506.3030400@freegeek.org> References: <4B491506.3030400@freegeek.org> Message-ID: <4B520801.8010300@henning-thielemann.de> wren ng thornton schrieb: > Tom Tobin wrote: >> ----- Heinrich Apfelmus wrote: >>> Since the name Ring is already taken by an ubiquitous mathematical >>> structure, and thus already in hackage for example as Algebra.Ring in >>> the numeric-prelude , I suggest to call the data structure Necklace >>> instead. >> >> Is Necklace a known name for this data structure? If not Ring, I was >> thinking Circular might be an appropriate name. > > I'm not sure if there's a canonical name, except perhaps "circular > queue". Necklace is cute, though Circular or CircleQueue might be > better. I'd also advise strongly against using Ring in order to avoid > confusing nomenclature. (Loop should be avoided for similar reasons.) When reading "Ring" first time in the e-mail subject, I also thought it would be about the algebraic structure with that name. CircularList seems fine to me. Necklace is nice but might be missed when someone searches for that data structure on Hackage. From gwern0 at gmail.com Sat Jan 16 14:25:09 2010 From: gwern0 at gmail.com (Gwern Branwen) Date: Sat Jan 16 13:57:38 2010 Subject: [Haskell-cafe] Compilers In-Reply-To: <20081130010231.GA7014@sliver.repetae.net> References: <20081124042513.GA23604@scytale.galois.com> <20081129034142.GR27887@scytale.galois.com> <20081129104132.GC31753@sliver.repetae.net> <200811292341.04247.daniel.is.fischer@web.de> <20081130010231.GA7014@sliver.repetae.net> Message-ID: On Sat, Nov 29, 2008 at 8:02 PM, John Meacham wrote: > On Sat, Nov 29, 2008 at 11:41:03PM +0100, Daniel Fischer wrote: >> Great, nothing I don't already have, so download the source tarball, unpack >> and >> ./configure --prefix=$HOME >> checking for a BSD-compatible install... /usr/bin/install -c >> checking whether build environment is sane... yes >> ... more configure output ... >> checking for drift-ghc... no >> configure: error: ?DrIFT not found get it from >> http://repetae.net/computer/haskell/DrIFT/ >> >> Huh? >> dafis@linux:~/jhc/jhc-0.5.20080307> which DrIFT >> /home/dafis/.cabal/bin/DrIFT >> dafis@linux:~/jhc/jhc-0.5.20080307> DrIFT --version >> Version DrIFT-2.2.3 > > Oh golly. I never put DrIFT on cabal, apparently whomever tried to > cabalize it didn't include the ghc driver script, and also appeared to > just drop the documentation from the package altogether. It is things > like that that make it very hard to get behind cabal, why was DrIFT > crippled just so it can be put on cabal? If cabal wasn't powerful enough > to compile DrIFT, and we already had a perfectly good way of compiling > it, why the need to shoehorn it in and cause this problem? sigh. ... > ? ? ? ?John Thought I'd mention that http://hackage.haskell.org/package/DrIFT-cabalized 2.2.3.1 includes a drift-ghc.hs (compiles to /home/gwern/bin/bin/DrIFT-cabalized-ghc) which is a clone of the drift-ghc.in shell script you allude to: import Data.List (isInfixOf) import System.Cmd (rawSystem) import System.Environment (getArgs) import System.Exit (ExitCode(ExitSuccess)) import Paths_DrIFT_cabalized (getBinDir) main :: IO ExitCode main = do args <- getArgs case args of (a:b:c:[]) -> conditional a b c _ -> error "This is a driver script allowing DrIFT to be used seamlessly with ghc.\n \ \ in order to use it, pass '-pgmF drift-ghc -F' to ghc when compiling your programs." conditional :: FilePath -> FilePath -> FilePath -> IO ExitCode conditional orgnl inf outf = do prefix <- getBinDir infile <- readFile inf if "{-!" `isInfixOf` infile then do putStrLn (prefix ++ "DriFT-cabalized " ++ inf ++ " -o " ++ outf) rawSystem inf ["-o", outf] else do writeFile outf ("{-# LINE 1 \"" ++ orgnl ++ " #-}") readFile inf >>= appendFile outf return ExitSuccess {- GHC docs say: "-pgmF cmd Use cmd as the pre-processor (with -F only). Use -pgmF cmd to select the program to use as the preprocessor. When invoked, the cmd pre-processor is given at least three arguments on its command-line: 1. the first argument is the name of the original source file, 2. the second is the name of the file holding the input 3. third is the name of the file where cmd should write its output to." -} John: I would appreciate you pointing out if I have made a mistake anywhere in that and not actually replicated the functionality of the shell script. (I think I have, but I didn't really understand what the first echo was supposed to do and just copied its functionality.) -- gwern From markl at glyphic.com Sat Jan 16 14:33:50 2010 From: markl at glyphic.com (Mark Lentczner) Date: Sat Jan 16 14:06:15 2010 Subject: [Haskell-cafe] GHC bug? Cabal bug? Haddock bug? Message-ID: === Short Story === If I build syb-with-class-0.6 via cabal (cabal configure; cabal build) in the unpacked tar directory, it builds correctly. If I build it via "cabal install" (either from the unpacked directory, or by letting cabal fetch it), then the resulting package is corrupted. In particular, the .hi interface file for Data.Generics.SYB.WithClass.Instances mentions symbols that aren't in the .a file. (Or rather, they have the wrong names.) I compared verbose logs of both builds and the differ only in temporary file names.... execpt that the "cabal install" version builds haddock, as my .cabal/conf file has documentation: True. Turns out that if turn documentation off, then then "cabal install" builds a .hi file that matches the .a file... and all is well. Is this a bug in cabal? cabal-install? ghc? haddock? I have saved logs of all this if anyone wants. - Mark (MtnViewMark) Lentczner markl@glyphic.com http://www.ozonehouse.com/mark/ === Versions === [2373] : cabal -V cabal-install version 0.8.0 using version 1.8.0.2 of the Cabal library [2374] : ghc -V The Glorious Glasgow Haskell Compilation System, version 6.10.4 [2376] : ghc-pkg describe haddock | grep version version: 2.4.2 === Background & Details === I was installing happstack on my Mac with my Haskell Platform (GHC 6.10.4) installation. I have successfully installed dozens of other packages in this environment before, and these results are annomalous. I kicked this off via: cabal install --user happstack This installs many packages, including syb-with-class-0.6, which compiled and installed just fine. When installing happstack-data, and compiling the file Happstack/Data/Proxy.hs, during the Template Haskell step (where things get loaded up in ghci), the build encounters this link error: [ 7 of 16] Compiling Happstack.Data.Proxy ( src/Happstack/Data/Proxy.hs, dist/build/Happstack/Data/Proxy.o ) Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Loading package syb ... linking ... done. Loading package array-0.2.0.0 ... linking ... done. Loading package bytestring-0.9.1.5 ... linking ... done. Loading package containers-0.2.0.1 ... linking ... done. Loading package packedstring-0.1.0.1 ... linking ... done. Loading package pretty-1.0.1.0 ... linking ... done. Loading package template-haskell ... linking ... done. Loading package syb-with-class-0.6 ... linking ... done. (... many more loads elided...) Loading package HaXml-1.13.3 ... linking ... done. ghc: unknown symbol `_sybzmwithzmclasszm0zi6_DataziGenericsziSYBziWithClassziInstances_dataTypeZMabOQZN_closure' That symbol decodes to something referring to: package: syb-with-class-0.6 module: Data.Generics.SYB.WithClass.Instances reference: dataType[abOQ] The reference turns out to be from Loading Happstack.Data.Default, which in turn imports Data.Generics.SYB.WithClass.Instances. Poking around, I found that the interface (.hi) file for Data.Generics.SYB.WithClass.Instances does indeed export such an object: [2324] : ghc --show-iface Data/Generics/SYB/WithClass/Instances.hi | fgrep dataType[a Data.Generics.SYB.WithClass.Instances.dataType[abOQ]) -} Data.Generics.SYB.WithClass.Instances.dataType[abSm]) -} dataType[abOQ] :: Data.Generics.SYB.WithClass.Basics.DataType dataType[abSm] :: Data.Generics.SYB.WithClass.Basics.DataType But, the library doesn't export it: [2325] : nm libHSsyb-with-class-0.6.a | fgrep dataTypeZMa 0001854c D _sybzmwithzmclasszm0zi6_DataziGenericsziSYBziWithClassziInstances_dataTypeZMaeuiZN_closure 00018604 D _sybzmwithzmclasszm0zi6_DataziGenericsziSYBziWithClassziInstances_dataTypeZMaexTZN_closure These refer to dataType[aeui] and dataType[aexT], which don't exist in the interface file. Something seems amiss here: The interface file is exporting generated names that don't match what the library is exporting. If I do the same investigation with the profiling versions of this module, they match: [2326] : ghc --show-iface Data/Generics/SYB/WithClass/Instances.p_hi | fgrep dataType[a Data.Generics.SYB.WithClass.Instances.dataType[anmx]) -} Data.Generics.SYB.WithClass.Instances.dataType[anq8]) -} dataType[anmx] :: Data.Generics.SYB.WithClass.Basics.DataType dataType[anq8] :: Data.Generics.SYB.WithClass.Basics.DataType markl@mtree ~/Library/Haskell/packages/syb-with-class-0.6/lib/ghc-6.10.4 [2327] : nm libHSsyb-with-class-0.6_p.a | fgrep dataTypeZMa 00032704 D _sybzmwithzmclasszm0zi6_DataziGenericsziSYBziWithClassziInstances_dataTypeZManmxZN_closure 0003282c D _sybzmwithzmclasszm0zi6_DataziGenericsziSYBziWithClassziInstances_dataTypeZManq8ZN_closure These both export something dataType[anmx] and dataType[anq8] These two objects, by the way, stem from the last two lines of Data.Generics.SYB.WithClass.Instances.hs: $( deriveData [''ByteString] ) $( deriveData [''L.ByteString] ) From nicolas.pouillard at gmail.com Sat Jan 16 14:35:59 2010 From: nicolas.pouillard at gmail.com (Nicolas Pouillard) Date: Sat Jan 16 14:08:25 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> Message-ID: <1263670342-sup-6302@ks> Excerpts from Michael Snoyman's message of Wed Jan 13 15:46:12 +0100 2010: > Hi, > > I recently read (again) the wiki page on a web application interface[1] for > Haskell. It seems like this basically works out to Hack[2], but using an > enumerator instead of lazy bytestring in the response type. Is anyone > working on implementing this? If not, I would like to create the package, > though I wouldn't mind some community input on some design decisions: Wai seems to lightly rely on ImpredicativeTypes which becomes deprecated in GHC 6.12 and could be removed in 6.14. This seems to be due to the response tuple. Is there any plan to change this to a more forward compatible solution? -- Nicolas Pouillard http://nicolaspouillard.fr From aslatter at gmail.com Sat Jan 16 14:41:18 2010 From: aslatter at gmail.com (Antoine Latter) Date: Sat Jan 16 14:13:43 2010 Subject: [Haskell-cafe] GHC bug? Cabal bug? Haddock bug? In-Reply-To: References: Message-ID: <694519c51001161141l72eb15b3ob55f515473de2131@mail.gmail.com> This sounds similar to an issue I was seeing over here: http://groups.google.com/group/happs/msg/04ecfe4fd6285c0d The module being compiled also includes TH top-level statements, and was only reproducible when building from Cabal. Here's another occurance on a different platform: http://groups.google.com/group/happs/msg/0f65ba6e4f7e822d And the workaround: http://groups.google.com/group/happs/msg/1e7761d421b0e5eb Here's the GHC bug report: http://hackage.haskell.org/trac/ghc/ticket/3799 Antoine 2010/1/16 Mark Lentczner : > === Short Story === > > If I build syb-with-class-0.6 via cabal (cabal configure; cabal build) in the unpacked tar directory, it builds correctly. > > If I build it via "cabal install" (either from the unpacked directory, or by letting cabal fetch it), then the resulting package is corrupted. In particular, the .hi interface file for Data.Generics.SYB.WithClass.Instances mentions symbols that aren't in the .a file. (Or rather, they have the wrong names.) > > I compared verbose logs of both builds and the differ only in temporary file names.... execpt that the "cabal install" version builds haddock, as my .cabal/conf file has documentation: True. Turns out that if turn documentation off, then then "cabal install" builds a .hi file that matches the .a file... and all is well. > > Is this a bug in cabal? cabal-install? ghc? haddock? > > I have saved logs of all this if anyone wants. > > ? ?- Mark (MtnViewMark) Lentczner > ? ?markl@glyphic.com > ? ?http://www.ozonehouse.com/mark/ > > === Versions === > > ? ?[2373] : cabal -V > ? ?cabal-install version 0.8.0 > ? ?using version 1.8.0.2 of the Cabal library > > ? ?[2374] : ghc -V > ? ?The Glorious Glasgow Haskell Compilation System, version 6.10.4 > > ? ?[2376] : ghc-pkg describe haddock | grep version > ? ?version: 2.4.2 > > === Background & Details === > > I was installing happstack on my Mac with my Haskell Platform (GHC 6.10.4) installation. I have successfully installed dozens of other packages in this environment before, and these results are annomalous. > > I kicked this off via: > ? ? ? ?cabal install --user happstack > > This installs many packages, including syb-with-class-0.6, which compiled and installed just fine. > > When installing happstack-data, and compiling the file Happstack/Data/Proxy.hs, during the Template Haskell step (where things get loaded up in ghci), the build encounters this link error: > > ? ?[ 7 of 16] Compiling Happstack.Data.Proxy ( src/Happstack/Data/Proxy.hs, dist/build/Happstack/Data/Proxy.o ) > ? ?Loading package ghc-prim ... linking ... done. > ? ?Loading package integer ... linking ... done. > ? ?Loading package base ... linking ... done. > ? ?Loading package syb ... linking ... done. > ? ?Loading package array-0.2.0.0 ... linking ... done. > ? ?Loading package bytestring-0.9.1.5 ... linking ... done. > ? ?Loading package containers-0.2.0.1 ... linking ... done. > ? ?Loading package packedstring-0.1.0.1 ... linking ... done. > ? ?Loading package pretty-1.0.1.0 ... linking ... done. > ? ?Loading package template-haskell ... linking ... done. > ? ?Loading package syb-with-class-0.6 ... linking ... done. > ? ?(... many more loads elided...) > ? ?Loading package HaXml-1.13.3 ... linking ... done. > ? ?ghc: > ? ?unknown symbol `_sybzmwithzmclasszm0zi6_DataziGenericsziSYBziWithClassziInstances_dataTypeZMabOQZN_closure' > > That symbol decodes to something referring to: > ? ?package: ? syb-with-class-0.6 > ? ?module: ? ?Data.Generics.SYB.WithClass.Instances > ? ?reference: dataType[abOQ] > > The reference turns out to be from Loading Happstack.Data.Default, which in turn imports Data.Generics.SYB.WithClass.Instances. > > Poking around, I found that the interface (.hi) file for Data.Generics.SYB.WithClass.Instances does indeed export such an object: > > ? ?[2324] : ghc --show-iface Data/Generics/SYB/WithClass/Instances.hi | fgrep dataType[a > ? ? ? ? ? ? ? ? ? ? ? Data.Generics.SYB.WithClass.Instances.dataType[abOQ]) -} > ? ? ? ? ? ? ? ? ? ? ? Data.Generics.SYB.WithClass.Instances.dataType[abSm]) -} > ? ? ?dataType[abOQ] :: Data.Generics.SYB.WithClass.Basics.DataType > ? ? ?dataType[abSm] :: Data.Generics.SYB.WithClass.Basics.DataType > > But, the library doesn't export it: > > ? ?[2325] : nm libHSsyb-with-class-0.6.a | fgrep dataTypeZMa > ? ?0001854c D _sybzmwithzmclasszm0zi6_DataziGenericsziSYBziWithClassziInstances_dataTypeZMaeuiZN_closure > ? ?00018604 D _sybzmwithzmclasszm0zi6_DataziGenericsziSYBziWithClassziInstances_dataTypeZMaexTZN_closure > > These refer to dataType[aeui] and dataType[aexT], which don't exist in the interface file. > > Something seems amiss here: The interface file is exporting generated names that don't match what the library is exporting. > > If I do the same investigation with the profiling versions of this module, they match: > > ? ?[2326] : ghc --show-iface Data/Generics/SYB/WithClass/Instances.p_hi | fgrep dataType[a > ? ? ? ? ? ? ? ? ? ? ? Data.Generics.SYB.WithClass.Instances.dataType[anmx]) -} > ? ? ? ? ? ? ? ? ? ? ? Data.Generics.SYB.WithClass.Instances.dataType[anq8]) -} > ? ? ?dataType[anmx] :: Data.Generics.SYB.WithClass.Basics.DataType > ? ? ?dataType[anq8] :: Data.Generics.SYB.WithClass.Basics.DataType > > ? ?markl@mtree ? ~/Library/Haskell/packages/syb-with-class-0.6/lib/ghc-6.10.4 > ? ?[2327] : nm libHSsyb-with-class-0.6_p.a | fgrep dataTypeZMa > ? ?00032704 D _sybzmwithzmclasszm0zi6_DataziGenericsziSYBziWithClassziInstances_dataTypeZManmxZN_closure > ? ?0003282c D _sybzmwithzmclasszm0zi6_DataziGenericsziSYBziWithClassziInstances_dataTypeZManq8ZN_closure > > These both export something dataType[anmx] and dataType[anq8] > > These two objects, by the way, stem from the last two lines of Data.Generics.SYB.WithClass.Instances.hs: > > ? ?$( deriveData [''ByteString] ) > ? ?$( deriveData [''L.ByteString] ) > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From schlepptop at henning-thielemann.de Sat Jan 16 14:51:42 2010 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Sat Jan 16 14:24:42 2010 Subject: [Haskell-cafe] Poor man's generic programming Message-ID: <4B5218CE.5090902@henning-thielemann.de> Is any of the existing Generics packages able to work without compiler extensions, that is Haskell 98? I mean, it is ok if the developer of the generic parts of a library needs compiler extensions or extra tools, but the user who calls 'cabal install' shall not need them and the developer, who does not touch generic definitions, should not need them as well. I think this could be done with pragmas in the following way: class C a where f :: a -> [Int] {-# GENERICDEFAULT f {| Unit |} Unit = [] #-} {-# GENERATEDINSTANCEBEGIN Automatically generated - Do not edit! #-} instance C () where f () = [] {-# GENERATEDINSTANCEEND Automatically generated - Do not edit! #-} Now, by running a tool, the part between the GENERATEDINSTANCE pragmas can generated or updated. Everything outside the pragmas can be Haskell 98. It does not only avoid extensions of the building compiler, but also extensions of a programmer's brain. Because for programmers it is often easier to understand a set of instances and see the common patterns, than to understand generic code that builds the instances. From schlepptop at henning-thielemann.de Sat Jan 16 14:57:47 2010 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Sat Jan 16 14:31:27 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B4CE8CE.9060202@btinternet.com> References: <4B4CE8CE.9060202@btinternet.com> Message-ID: <4B521A3B.30004@henning-thielemann.de> Andrew Coppin schrieb: > Hmm, I wonder if there's some way to compare the size of the language > specification documents? :-} > > PS. It comes as absolutely no surprise to me that C++ has the most > keywords. But then, if I were to add AMOS Professional, that had well > over 800 keywords at the last count... Because those BASIC dialects had a large set of built-in functions that would have been library functions in other languages. BlitzBasic II had many such functions defined as library functions. GFA-Basic provided many system library functions as built-in functions. There was a famous book about Murphy's law applied to computers where programming languages were advertised by the number of their built-in commands. :-) From schlepptop at henning-thielemann.de Sat Jan 16 15:01:07 2010 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Sat Jan 16 14:34:05 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> Message-ID: <4B521B03.1070603@henning-thielemann.de> Niklas Broberg schrieb: >> Haskell '98 apparently features 25 reserved words. (Not counting "forall" >> and "mdo" and so on, which AFAIK are not in Haskell '98.) >> > > 21 actually. case, class, data, default, deriving, do, else, if, > import, in, infix, infixl, infixr, instance, let, module, newtype, of, > then, type, where. There's also three special words that can still be > used as identifiers, so aren't reserved: as, qualified, hiding. > Recently I added 'export' to my NEdit highlight patterns in order to support FFI statements more completely. From schlepptop at henning-thielemann.de Sat Jan 16 15:15:21 2010 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Sat Jan 16 14:48:17 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <27137827.post@talk.nabble.com> References: <4B4CE8CE.9060202@btinternet.com> <27137827.post@talk.nabble.com> Message-ID: <4B521E59.8050505@henning-thielemann.de> Eduard Sergeev schrieb: > Andrew Coppin wrote: > >> OK people, it's random statistics time! >> > > OK, my version of meaningless statistics: > > C++ (ISO/IEC 14882:1998(E)): 325 pages (712 including standard libraries) > C# (ECMA-334): 505 pages (language only) > Java: 450 pages (language only?) > Scala (2.7): 125 pages (157 including standard library) > Eiffel (ECMA-367): 160 pages (language only) > ANSI SQL-92: 685 pages (language only) > Haskell-98: 77 pages (247 including Prelude) > Erlang (4.7.3) 162 pages (251 including builtin functions) > Scheme (R5RS): 17 pages (45 including standard procedures) > Modula-3 is advertised for needing only 60 pages for the language definition. From daniel.is.fischer at web.de Sat Jan 16 15:37:56 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sat Jan 16 15:12:04 2010 Subject: [Haskell-cafe] Re: FASTER primes In-Reply-To: References: <201001141202.37294.daniel.is.fischer@web.de> Message-ID: <201001162137.56659.daniel.is.fischer@web.de> Am Samstag 16 Januar 2010 18:53:33 schrieb Will Ness: > Daniel Fischer web.de> writes: > > Am Donnerstag 14 Januar 2010 08:25:48 schrieb Will Ness: > > > Daniel Fischer web.de> writes: > > > > Am Mittwoch 13 Januar 2010 10:43:42 schrieb Heinrich Apfelmus: > > > > > I wonder whether it's really the liveness of ?pair ?in > > > > > > > > > > ? mergeSP (a,b) pair > > > > > ? ? ?= let sm = spMerge b (fst pair) > > > > > ? ? ? ?in (a ++ fst sm, merge (snd sm) (snd pair)) > > > > > > > > > > that is responsible for the space leak, ... > > > > > > > > I think that is responsible. At least that's how I understand the > > > > core: > > > > > > > > mergeSP (a,b) ~(c,d) = (a ++ bc, merge b' d) > > > > where > > > > (bc, b') = spMerge b c > > > > spMerge ... > > > > > > That is equivalent to > > > > > > first (a++) . second (`merge`d) $ spMerge b c > > > > > > and Daniel's fix is equivalent to > > > > > > first (a++) $ spMerge b c d > > That should've been > > mergeSP (a,b) p = first(a++) . second(`merge`snd p) $ spMerge b (fst > p) > > and > > mergeSP (a,b) p = first(a++) $ spMerge b (fst p) (snd p) > > > The code fragments you've posted are essentially > > > mergeSP (a,b) p = let res = case p of (c,_) -> > case spMerge b c of (# x,y #) -> > (x,y) > in > (# (++) a (case res of (bc,_)-> bc) , > case res of (_,b') -> > case p of (_,d) -> merge b' d #) > > and > > mergeSP (a,b) p = let res = case p of (c,d) -> > case spMerge b c d of (# x,y #) -> > (x,y) > in > (# (++) a (case res of (bc,_)-> bc) , > case res of (_,b') -> b' #) > > > This looks like Haskell to me, with many detailes explicitely written > out, probaly serving as immediate input to the compiler - not its > output. So it can't say to us much about how this is actually > implemented on the lower level. (?) It's 'core', the intermediate language GHC uses and does its transformations upon. It's more or less a slimmed down version of Haskell. That came from -ddump-simpl, thus it's the output of the simplifier, after numerous transformation/optimisation passes. I think that is then fairly directly translated to assembly (via Cmm), the STG to STG and Cmm passes do not much optimisation anymore (I may be wrong, what know I about the compiler. However, I've found that the -ddump-simpl output corresponds well to the actual behaviour whenever I look.). I find that much more redable than the -fext-core output (http://www.haskell.org/ghc/docs/6.12.1/html/users_guide/ext-core.html "GHC can dump its optimized intermediate code (said to be in ?Core? format) to a file as a side-effect of compilation."), which says the same, only more verbose and less readable. Of course, if I could read assembly, that would exactly reveal what happens. > > Your theory would certainly hold if the translation was done one-to-one > without any further code rearrangements. But it could've been further > re-arranged by the compiler at some later stage (is there one?) into an > equivalent of, e.g. > > > mergeSP (a,b) p = let (bc,b') = case p of (c,_) -> > case spMerge b c of (x,y) -> > (x,y) > in > (# (++) a bc , > case p of (_,d) -> merge b' d #) > > > and further, > > > mergeSP (a,b) p = let (c,d) = case p of (x,y) -> (x,y) > (bc,b') = case spMerge b c of (x,y) -> > (x,y) > in > (# (++) a bc , merge b' d #) > > > could it? This would take hold on /d/ and /c/ at the same time, right? It would. But AFAICT, after the simplifier is done, no such rearrangements occur anymore. > > What is that code that you've shown exactly? At which stage is it > produced and is it subject to any further manipulation? I'm no GHC expert either, so I don't know what it does when exactly. But after parsing and desugaring, there come a few iterations of the simplifier, intermingled with specialising, demand-analysis, CSE, let- floating, worker-wrapper-split, ... . At the end of all that, the Tidy Core is generated (part of which I posted). What happens from then on, well ... > I apologise if > these are obvious questions, I don't know anything about GHC. I also > don't know what (# x,y #) means? Unboxed tuple (pair in this case). That means, have the components for themselves, don't wrap them in a (,) constructor. > > One thing seems certain - we should not hold explicit references to same > entities in different parts of our code, to avoid space leaks with more > confidence. Except when it's good to share ;) > To make code look as much tail-recursive as possible, so to speak. Tail recursion isn't really important (for GHC at least, I think for lazy languages in general), due to different evaluation models (cf. http://www.haskell.org/pipermail/haskell-cafe/2009-March/058607.html and the thread starting with http://www.haskell.org/pipermail/haskell-cafe/2007-May/025570.html). > > Does that make sense? In general, yes. > > Anyway that was a very educational (for me) and fruitful discussion, and > I greatly appreciate your help, and fixing and improving of the code. > > Thanks! You're welcome. From malcolm.wallace at cs.york.ac.uk Sat Jan 16 16:40:17 2010 From: malcolm.wallace at cs.york.ac.uk (Malcolm Wallace) Date: Sat Jan 16 16:12:41 2010 Subject: [Haskell-cafe] AlternativePrelude extension In-Reply-To: <201001151910.00488.sjurberengal@gmail.com> References: <201001151910.00488.sjurberengal@gmail.com> Message-ID: > I'm thinking the syntax would be something like > AlternativePrelude="MyPrelude". There is a general principle that the semantics of a program should be completely described by the source code itself, and not dependent on options that may or may not be specified elsewhere. Hence, the idea of adding {-# LANGUAGE #-} pragmas, so that the source code is self- contained. Specifying {-# LANGUAGE NoImplicitPrelude #-} together with "import MyPrelude" satisfies this principle, as does {-# LANGUAGE AlternativePrelude="MyPrelude" #-} in all files where it matters. But the difference in usability is slight. If you are suggesting that {-# LANGUAGE AlternativePrelude="MyPrelude" #-} should somehow escape the scope of the module it appears in, then I think we heading for less firm ground. Regards, Malcolm From felipe.lessa at gmail.com Sat Jan 16 17:11:59 2010 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Sat Jan 16 16:44:27 2010 Subject: [Haskell-cafe] RFC: Space-leak-free, efficient symbol table implementation. In-Reply-To: <17B140E4-D3D4-4B2E-9BD7-8A26299DD7C8@googlemail.com> References: <17B140E4-D3D4-4B2E-9BD7-8A26299DD7C8@googlemail.com> Message-ID: <20100116221159.GA11082@kira.casa> Interesting code, it was nice to read, thanks! Just a few minor comments. On Thu, Jan 14, 2010 at 11:33:54PM +0000, Thomas Schilling wrote: > intern s = unsafePerformIO $ do > lnk <- newIORef Nothing > r <- newIORef $ SymInfo (hash s) lnk s > return (Symbol r) > > mkSymbolInfo :: String -> SymbolInfo > mkSymbolInfo s = unsafePerformIO $ do > lnk <- newIORef Nothing > return $ SymInfo (hash s) lnk s intern = fmap Symbol . newIORef . mkSymbolInfo > -- END OF COMMON CASE > -- > -- If the symbols have been built using the same symbol table > -- we will only reach this case if we have a hash collision or > -- the symbols were built from different symbol tables. -- END OF COMMON CASE -- -- We will only reach this case if we have a hash collision or -- the symbols were built from different symbol tables. Thanks for sharing, -- Felipe. From sjurberengal at gmail.com Sat Jan 16 18:09:38 2010 From: sjurberengal at gmail.com (Sjur =?iso-8859-1?q?Gj=F8stein_Karevoll?=) Date: Sat Jan 16 17:42:05 2010 Subject: [Haskell-cafe] AlternativePrelude extension In-Reply-To: References: <201001151910.00488.sjurberengal@gmail.com> Message-ID: <201001170009.38549.sjurberengal@gmail.com> Laurdag 16. januar 2010 22.40.17 skreiv Malcolm Wallace: > > I'm thinking the syntax would be something like > > AlternativePrelude="MyPrelude". > > There is a general principle that the semantics of a program should be > completely described by the source code itself, and not dependent on > options that may or may not be specified elsewhere. Hence, the idea > of adding {-# LANGUAGE #-} pragmas, so that the source code is self- > contained. > > Specifying {-# LANGUAGE NoImplicitPrelude #-} together with "import > MyPrelude" satisfies this principle, as does {-# LANGUAGE > AlternativePrelude="MyPrelude" #-} in all files where it matters. But > the difference in usability is slight. > > If you are suggesting that {-# LANGUAGE AlternativePrelude="MyPrelude" > #-} should somehow escape the scope of the module it appears in, then > I think we heading for less firm ground. > > Regards, > Malcolm > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > Having a LANGUAGE pragma, or indeed any pragma, escape the module it's used in would be pretty silly, wouldn't it? In principle I'm a fan of the LANGUAGE pragmas. Self-contained source is usually much easier to read that source that depends on whatever command the author used to build the thing. However, the option to set language extension globally is still available, either as an option to the compiler when building, or in the cabal file describing the package. Allowing an alternative prelude in this fashion makes it easier to switch out the standard for alternatives in existing projects just to see what might happen, how things are changed or just for giggles. It might not be advisable to do so in code you plan on unleashing on the world, but it would make experimenting with alternatives cheaper than it currently is. -- Sjur Gj?stein Karevoll From markl at glyphic.com Sat Jan 16 20:21:26 2010 From: markl at glyphic.com (Mark Lentczner) Date: Sat Jan 16 19:53:49 2010 Subject: [Haskell-cafe] GHC bug? Cabal bug? Haddock bug? In-Reply-To: <694519c51001161141l72eb15b3ob55f515473de2131@mail.gmail.com> References: <694519c51001161141l72eb15b3ob55f515473de2131@mail.gmail.com> Message-ID: Indeed - all those look exactly like the same issue. > And the workaround: > http://groups.google.com/group/happs/msg/1e7761d421b0e5eb That doesn't fix the real issue: It causes happstack-data to not need the thing that is built wrong in syb-with-class. I believe my work-around (build syb-with-class w/o documentation) will be a more universal workaround, as at that point the syb-with-class install is no longer broken. > Here's the GHC bug report: http://hackage.haskell.org/trac/ghc/ticket/3799 Registration for that trac is broken, so I couldn't update that ticket. I see that you've added pointers to my post, thank you! Perhaps you can also add a note that the issue seems to have to do with something that cabal does differently when there is a documentation step enabled. - Mark From lennart at augustsson.net Sat Jan 16 20:23:56 2010 From: lennart at augustsson.net (Lennart Augustsson) Date: Sat Jan 16 19:56:20 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: References: <4B4CE8CE.9060202@btinternet.com> <87my0inv07.fsf@malde.org> Message-ID: PL/I has keywords, they're just not reserved words. With as many keywords as PL/I has, there something to say for not making them reserved. :) On Wed, Jan 13, 2010 at 11:50 AM, Brandon S. Allbery KF8NH wrote: > On Jan 13, 2010, at 05:45 , Ketil Malde wrote: >> >> "Brandon S. Allbery KF8NH" writes: >>> >>> If we're going to go that far, FORTRAN and PL/1 have none. ?FORTRAN is >>> somewhat infamous for this: >> >> There's also the option (perhaps this was PL/1?) of writing constructs >> like: ?IF THEN THEN IF ELSE THEN etc. ?Having few reserved words isn't >> necessarily a benefit. ?:-) > > That'd be PL/I, and a prime example of why languages use keywords these days > (as if FORTRAN weren't enough). :) > > -- > brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com > system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu > electrical and computer engineering, carnegie mellon university ? ?KF8NH > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From uzytkownik2 at gmail.com Sat Jan 16 21:04:13 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Sat Jan 16 20:36:37 2010 Subject: [Haskell-cafe] ANNOUNCE: nntp 0.0.3 Message-ID: <1263693853.5616.15.camel@picard> Rather a 'bug-fix' release. Intended to add additional symbols to group names. I'd like to add support for explicit fetching some headers only and giving the message a more MIME-like behaviour but I'm afraid there is nowhere written how XHDR/HDR would behave with multiline headers nor I found a suitable package (mime[1] seems to not include even parsing the headers only and mime-string[2] does not take into account comments which may or may not be a problem with Message-ID comparaison). Regards [1] http://hackage.haskell.org/package/mime [2] http://hackage.haskell.org/package/mime-string -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100116/8dfe4374/attachment.bin From aslatter at gmail.com Sat Jan 16 21:08:48 2010 From: aslatter at gmail.com (Antoine Latter) Date: Sat Jan 16 20:41:12 2010 Subject: [Haskell-cafe] GHC bug? Cabal bug? Haddock bug? In-Reply-To: References: <694519c51001161141l72eb15b3ob55f515473de2131@mail.gmail.com> Message-ID: <694519c51001161808j103e4c4fx8a6402aef41bde4c@mail.gmail.com> 2010/1/16 Mark Lentczner : > Indeed - all those look exactly like the same issue. > >> And the workaround: >> http://groups.google.com/group/happs/msg/1e7761d421b0e5eb > > That doesn't fix the real issue: It causes happstack-data to not need the thing that is built wrong in syb-with-class. I believe my work-around (build syb-with-class w/o documentation) will be a more universal workaround, as at that point the syb-with-class install is no longer broken. > >> Here's the GHC bug report: http://hackage.haskell.org/trac/ghc/ticket/3799 > > Registration for that trac is broken, so I couldn't update that ticket. I see that you've added pointers to my post, thank you! Perhaps you can also add a note that the issue seems to have to do with something that cabal does differently when there is a documentation step enabled. > Here's the good stuff. First, I did a "cabal configure && cabal build" for syb-with-class. And then: >>>>> antoine-latters-macbook:syb-with-class-0.6.1 alatter$ find . | grep \\.o$ | xargs ls -l -rw-r--r-- 1 alatter staff 121496 Jan 16 20:04 ./dist/build/Data/Generics/SYB/WithClass/Basics.o -rw-r--r-- 1 alatter staff 5888 Jan 16 20:04 ./dist/build/Data/Generics/SYB/WithClass/Context.o -rw-r--r-- 1 alatter staff 157220 Jan 16 20:04 ./dist/build/Data/Generics/SYB/WithClass/Derive.o -rw-r--r-- 1 alatter staff 403216 Jan 16 20:04 ./dist/build/Data/Generics/SYB/WithClass/Instances.o -rw-r--r-- 1 alatter staff 602752 Jan 16 20:04 ./dist/build/HSsyb-with-class-0.6.1.o antoine-latters-macbook:syb-with-class-0.6.1 alatter$ find . | grep \\.hi$ | xargs ls -l -rw-r--r-- 1 alatter staff 33600 Jan 16 20:04 ./dist/build/Data/Generics/SYB/WithClass/Basics.hi -rw-r--r-- 1 alatter staff 2367 Jan 16 20:04 ./dist/build/Data/Generics/SYB/WithClass/Context.hi -rw-r--r-- 1 alatter staff 13960 Jan 16 20:04 ./dist/build/Data/Generics/SYB/WithClass/Derive.hi -rw-r--r-- 1 alatter staff 166039 Jan 16 20:04 ./dist/build/Data/Generics/SYB/WithClass/Instances.hi antoine-latters-macbook:syb-with-class-0.6.1 alatter$ cabal haddock Running Haddock for syb-with-class-0.6.1... Preprocessing library syb-with-class-0.6.1... Warning: The documentation for the following packages are not installed. No links will be generated to these packages: ffi-1.0, rts-1.0 Documentation created: dist/doc/html/syb-with-class/index.html antoine-latters-macbook:syb-with-class-0.6.1 alatter$ find . | grep \\.o$ | xargs ls -l -rw-r--r-- 1 alatter staff 121496 Jan 16 20:05 ./dist/build/Data/Generics/SYB/WithClass/Basics.o -rw-r--r-- 1 alatter staff 5896 Jan 16 20:05 ./dist/build/Data/Generics/SYB/WithClass/Context.o -rw-r--r-- 1 alatter staff 157220 Jan 16 20:05 ./dist/build/Data/Generics/SYB/WithClass/Derive.o -rw-r--r-- 1 alatter staff 403216 Jan 16 20:05 ./dist/build/Data/Generics/SYB/WithClass/Instances.o -rw-r--r-- 1 alatter staff 602752 Jan 16 20:04 ./dist/build/HSsyb-with-class-0.6.1.o antoine-latters-macbook:syb-with-class-0.6.1 alatter$ find . | grep \\.hi$ | xargs ls -l -rw-r--r-- 1 alatter staff 33600 Jan 16 20:05 ./dist/build/Data/Generics/SYB/WithClass/Basics.hi -rw-r--r-- 1 alatter staff 2367 Jan 16 20:05 ./dist/build/Data/Generics/SYB/WithClass/Context.hi -rw-r--r-- 1 alatter staff 13960 Jan 16 20:05 ./dist/build/Data/Generics/SYB/WithClass/Derive.hi -rw-r--r-- 1 alatter staff 166039 Jan 16 20:05 ./dist/build/Data/Generics/SYB/WithClass/Instances.hi <<<<< Note that after running "cabal haddock" we re-build all of our .hi and .o files EXCEPT ./dist/build/HSsyb-with-class-0.6.1.o And now, since TH generates random symbols, we have symbols in the new .hi files that aren't in the old (and only) HSsyb-with-class-0.6.1.o. Antoine From nowgate at yahoo.com Sat Jan 16 22:02:59 2010 From: nowgate at yahoo.com (michael rice) Date: Sat Jan 16 21:35:24 2010 Subject: [Haskell-cafe] What's going on here? Message-ID: <97671.12408.qm@web31101.mail.mud.yahoo.com> I don't see anything wrong with this function, which just subtracts 1 from the first element of an Int list (if there is a first element). Michael My function: dropFirst :: [Int] -> [Int] dropFirst [] = [] dropFirst (x:xs) = (x-1) : xs My output: > :l dropfirst [1 of 1] Compiling Main???????????? ( dropfirst.hs, interpreted ) Ok, modules loaded: Main. *Main> dropFirst [3 4 5 6] :1:11: ??? No instance for (Num (t -> t1 -> t2 -> Int)) ????? arising from the literal `3' at :1:11-17 ??? Possible fix: ????? add an instance declaration for (Num (t -> t1 -> t2 -> Int)) ??? In the expression: 3 4 5 6 ??? In the first argument of `dropFirst', namely `[3 4 5 6]' ??? In the expression: dropFirst [3 4 5 6] *Main> -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100116/f08e78c7/attachment.html From voidprayer at gmail.com Sat Jan 16 22:05:25 2010 From: voidprayer at gmail.com (VoidPrayer) Date: Sat Jan 16 21:37:57 2010 Subject: [Haskell-cafe] What's going on here? In-Reply-To: <97671.12408.qm@web31101.mail.mud.yahoo.com> References: <97671.12408.qm@web31101.mail.mud.yahoo.com> Message-ID: <201001171105.26032.voidprayer@gmail.com> ? 2010? 1? 17? ??? 11:02:59?michael rice ??: > I don't see anything wrong with this function, which just subtracts 1 from > the first element of an Int list (if there is a first element). > > Michael > > My function: > > dropFirst :: [Int] -> [Int] > dropFirst [] = [] > dropFirst (x:xs) = (x-1) : xs > > My output: > > :l dropfirst > > [1 of 1] Compiling Main ( dropfirst.hs, interpreted ) > Ok, modules loaded: Main. > *Main> dropFirst [3 4 5 6] Use dropFirst [3,4,5,6], I think. > > :1:11: > No instance for (Num (t -> t1 -> t2 -> Int)) > arising from the literal `3' at :1:11-17 > Possible fix: > add an instance declaration for (Num (t -> t1 -> t2 -> Int)) > In the expression: 3 4 5 6 > In the first argument of `dropFirst', namely `[3 4 5 6]' > In the expression: dropFirst [3 4 5 6] > *Main> > From uzytkownik2 at gmail.com Sat Jan 16 22:12:26 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Sat Jan 16 21:45:13 2010 Subject: [Haskell-cafe] Re: AlternativePrelude extension In-Reply-To: <201001170009.38549.sjurberengal@gmail.com> References: <201001151910.00488.sjurberengal@gmail.com> <201001170009.38549.sjurberengal@gmail.com> Message-ID: <1263697945.5616.22.camel@picard> On Sun, 2010-01-17 at 00:09 +0100, Sjur Gj?stein Karevoll wrote: > However, the option to set language extension globally is still > available, either as an option to the compiler when building, or in > the cabal file describing the package. Hmm. Since the extensions should be specified in Cabal anyway (at least I guess it does some detection if compiler supports them) shouldn't it be specified in one place? Regards From rk at trie.org Sat Jan 16 22:15:01 2010 From: rk at trie.org (Rahul Kapoor) Date: Sat Jan 16 21:47:24 2010 Subject: [Haskell-cafe] What's going on here? In-Reply-To: <97671.12408.qm@web31101.mail.mud.yahoo.com> References: <97671.12408.qm@web31101.mail.mud.yahoo.com> Message-ID: >>*Main> dropFirst [3 4 5 6] List members are separated by commas. Space in Haskell denotes function application. Hence the error message: Hence t > No instance for (Num (t -> t1 -> t2 -> Int)) > arising from the literal `3' at :1:11-17 > Possible fix: > add an instance declaration for (Num (t -> t1 -> t2 -> Int)) From nowgate at yahoo.com Sat Jan 16 22:16:15 2010 From: nowgate at yahoo.com (michael rice) Date: Sat Jan 16 21:48:38 2010 Subject: [Haskell-cafe] What's going on here? In-Reply-To: <201001171105.26032.voidprayer@gmail.com> Message-ID: <533995.31504.qm@web31102.mail.mud.yahoo.com> Dumb! I've been hacking Lisp and just slipped over to Haskell to check on something. Thanks, Michael --- On Sat, 1/16/10, VoidPrayer wrote: From: VoidPrayer Subject: Re: [Haskell-cafe] What's going on here? To: haskell-cafe@haskell.org Date: Saturday, January 16, 2010, 10:05 PM ? 2010? 1? 17? ??? 11:02:59?michael rice ??: > I don't see anything wrong with this function, which just subtracts 1 from >? the first element of an Int list (if there is a first element). > > Michael > > My function: > > dropFirst :: [Int] -> [Int] > dropFirst [] = [] > dropFirst (x:xs) = (x-1) : xs > > My output: > > :l dropfirst > > [1 of 1] Compiling Main? ? ? ? ? ???( dropfirst.hs, interpreted ) > Ok, modules loaded: Main. > *Main> dropFirst [3 4 5 6] Use dropFirst [3,4,5,6], I think. > > :1:11: >? ???No instance for (Num (t -> t1 -> t2 -> Int)) >? ? ???arising from the literal `3' at :1:11-17 >? ???Possible fix: >? ? ???add an instance declaration for (Num (t -> t1 -> t2 -> Int)) >? ???In the expression: 3 4 5 6 >? ???In the first argument of `dropFirst', namely `[3 4 5 6]' >? ???In the expression: dropFirst [3 4 5 6] > *Main> > _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100116/4d8660db/attachment.html From ekmett at gmail.com Sat Jan 16 23:40:58 2010 From: ekmett at gmail.com (Edward Kmett) Date: Sat Jan 16 23:13:23 2010 Subject: [Haskell-cafe] Re: Data.Ring -- Pre-announce In-Reply-To: <4B520801.8010300@henning-thielemann.de> References: <4B491506.3030400@freegeek.org> <4B520801.8010300@henning-thielemann.de> Message-ID: <7fb8f82f1001162040j1d83cf1dl57ca198ab68ec47d@mail.gmail.com> One other name I've heard used, pretty much ever since the dos days when the 16 character fixed sized keyboard buffer was the first instance of such a structure I'd seen, was a 'ring buffer'. Data.RingBuffer perhaps? I agree that Data.Ring is a terrible name, partially because I already have a Data.Ring in the monoids package! -Edward Kmett On Sat, Jan 16, 2010 at 1:40 PM, Henning Thielemann < schlepptop@henning-thielemann.de> wrote: > wren ng thornton schrieb: > > Tom Tobin wrote: >> >>> ----- Heinrich Apfelmus wrote: >>> >>>> Since the name Ring is already taken by an ubiquitous mathematical >>>> structure, and thus already in hackage for example as Algebra.Ring in >>>> the numeric-prelude , I suggest to call the data structure Necklace >>>> instead. >>>> >>> >>> Is Necklace a known name for this data structure? If not Ring, I was >>> thinking Circular might be an appropriate name. >>> >> >> I'm not sure if there's a canonical name, except perhaps "circular queue". >> Necklace is cute, though Circular or CircleQueue might be better. I'd also >> advise strongly against using Ring in order to avoid confusing nomenclature. >> (Loop should be avoided for similar reasons.) >> > When reading "Ring" first time in the e-mail subject, I also thought it > would be about the algebraic structure with that name. > > CircularList seems fine to me. Necklace is nice but might be missed when > someone searches for that data structure on Hackage. > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100116/fd85f3cb/attachment-0001.html From markl at glyphic.com Sat Jan 16 23:43:42 2010 From: markl at glyphic.com (Mark Lentczner) Date: Sat Jan 16 23:16:05 2010 Subject: [Haskell-cafe] GHC bug? Cabal bug? Haddock bug? In-Reply-To: <694519c51001161808j103e4c4fx8a6402aef41bde4c@mail.gmail.com> References: <694519c51001161141l72eb15b3ob55f515473de2131@mail.gmail.com> <694519c51001161808j103e4c4fx8a6402aef41bde4c@mail.gmail.com> Message-ID: AHA! > Note that after running "cabal haddock" we re-build all of our .hi and > .o files EXCEPT ./dist/build/HSsyb-with-class-0.6.1.o > > And now, since TH generates random symbols, we have symbols in the new > .hi files that aren't in the old (and only) HSsyb-with-class-0.6.1.o. So, this leaves us with two questions: 1) Why does "cabal haddock" rebuild the .hi and .o files? On the face of it, this seems odd: Build documentation and your library gets rebuilt? 2) Why doesn't Instances.o get rebuilt? Surely this has something to do with the fact that Instances.hs contains only orphan instances. But any answer here just leads to a raft of other questions: Surely this problem would plague other modules have have similar source files? What is Haddock doing? If Haddock needs the .hi files, why not just use them? If it just "builds them to be sure", why in the dist tree and not some place temporary? If is going to build .o files, why not all? Curiouser..... - Mark Mark Lentczner http://www.ozonehouse.com/mark/ IRC: mtnviewmark From michael at snoyman.com Sun Jan 17 02:08:38 2010 From: michael at snoyman.com (Michael Snoyman) Date: Sun Jan 17 01:41:03 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: <1263670342-sup-6302@ks> References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> <1263670342-sup-6302@ks> Message-ID: <29bf512f1001162308y2887d4e9u43b9e4d8a5b375d1@mail.gmail.com> Absolutely; the goals I have are minimal dependencies and no warnings for compilation ;). On Sat, Jan 16, 2010 at 9:35 PM, Nicolas Pouillard < nicolas.pouillard@gmail.com> wrote: > Excerpts from Michael Snoyman's message of Wed Jan 13 15:46:12 +0100 2010: > > Hi, > > > > I recently read (again) the wiki page on a web application interface[1] > for > > Haskell. It seems like this basically works out to Hack[2], but using an > > enumerator instead of lazy bytestring in the response type. Is anyone > > working on implementing this? If not, I would like to create the package, > > though I wouldn't mind some community input on some design decisions: > > Wai seems to lightly rely on ImpredicativeTypes which becomes deprecated > in GHC 6.12 and could be removed in 6.14. This seems to be due to the > response tuple. > > Is there any plan to change this to a more forward compatible solution? > > -- > Nicolas Pouillard > http://nicolaspouillard.fr > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100117/10761c07/attachment.html From andrewcoppin at btinternet.com Sun Jan 17 05:05:47 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jan 17 04:38:08 2010 Subject: [Haskell-cafe] Parse error Message-ID: <4B52E0FB.5070201@btinternet.com> Is there a specific reason why GHC consistently refuses to accept the following perfectly reasonable code snippet? main = do putStrLn "Line 1" putStrLn "Line 2" let xs = do x <- [1..10] y <- [1..10] return (x+y) print xs No matter which way I rearrange this, it *insists* that there's a parse error. This is very frustrating, given that it's utterly clear what I want... From andrewcoppin at btinternet.com Sun Jan 17 05:09:14 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jan 17 04:41:35 2010 Subject: [Haskell-cafe] Dependency trickery Message-ID: <4B52E1CA.70904@btinternet.com> Suppose I write some code that can work with Gtk2hs or wxHaskell. How do I go about making that into a package? Specifically, how do I make it so that you don't have to install Gtk2hs *and* wxHaskell to build it? Do I have to actually make it into two seperate packages to do that? Also, supposing we have another package which requires the first, but doesn't care whether it's using Gtk2hs or wxHaskell. How do I do that? Obviously the answer depends on what happens in the previous step. If I make two seperate packages, for example, and they both export the same module, can I just add optional dependancies on both? Does Cabal support that? Not that I'm attempting to *do* this, you understand. I'd just like to know if it's possible... From voidprayer at gmail.com Sun Jan 17 05:10:32 2010 From: voidprayer at gmail.com (VoidPrayer) Date: Sun Jan 17 04:43:03 2010 Subject: [Haskell-cafe] Parse error In-Reply-To: <4B52E0FB.5070201@btinternet.com> References: <4B52E0FB.5070201@btinternet.com> Message-ID: <201001171810.32810.voidprayer@gmail.com> let ... in ... I guess GHC is finding where "in" is. ? 2010? 1? 17? ??? 18:05:47?Andrew Coppin ??: > Is there a specific reason why GHC consistently refuses to accept the > following perfectly reasonable code snippet? > > main = do > putStrLn "Line 1" > putStrLn "Line 2" > > let xs = do > x <- [1..10] > y <- [1..10] > return (x+y) > > print xs > > No matter which way I rearrange this, it *insists* that there's a parse > error. This is very frustrating, given that it's utterly clear what I > want... > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From tonymorris at gmail.com Sun Jan 17 05:23:33 2010 From: tonymorris at gmail.com (Tony Morris) Date: Sun Jan 17 04:56:04 2010 Subject: [Haskell-cafe] Parse error In-Reply-To: <4B52E0FB.5070201@btinternet.com> References: <4B52E0FB.5070201@btinternet.com> Message-ID: <4B52E525.50300@gmail.com> No, but there's a specific reason why GHC consistently refuses to accept your perfectly unreasonable code snippet :) GHC accepts the following perfectly reasonable code snippet: main = do putStrLn "Line 1" putStrLn "Line 2" let xs = do x <- [1..10] y <- [1..10] return (x+y) print xs Andrew Coppin wrote: > Is there a specific reason why GHC consistently refuses to accept the > following perfectly reasonable code snippet? > > main = do > putStrLn "Line 1" > putStrLn "Line 2" > > let xs = do > x <- [1..10] > y <- [1..10] > return (x+y) > > print xs > > No matter which way I rearrange this, it *insists* that there's a > parse error. This is very frustrating, given that it's utterly clear > what I want... > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- Tony Morris http://tmorris.net/ From daniel.is.fischer at web.de Sun Jan 17 05:31:16 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sun Jan 17 05:05:24 2010 Subject: [Haskell-cafe] Parse error In-Reply-To: <4B52E0FB.5070201@btinternet.com> References: <4B52E0FB.5070201@btinternet.com> Message-ID: <201001171131.16947.daniel.is.fischer@web.de> Am Sonntag 17 Januar 2010 11:05:47 schrieb Andrew Coppin: > Is there a specific reason why GHC consistently refuses to accept the > following perfectly reasonable code snippet? Yes, you violated the layout rule. > > main = do > putStrLn "Line 1" > putStrLn "Line 2" > > let xs = do > x <- [1..10] > y <- [1..10] > return (x+y) > > print xs > > No matter which way I rearrange this, it *insists* that there's a parse > error. This is very frustrating, given that it's utterly clear what I > want... It's not. ACLayout.hs:7:11: Empty 'do' construct should give a hint (line 7 is " let xs = do"). The next line after that is indented less than the "xs", so it ends the binding for xs (in fact, the entire let binding group) . You have to indent the lines in the do-block defining xs more than xs itself. From andrewcoppin at btinternet.com Sun Jan 17 05:33:45 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jan 17 05:06:06 2010 Subject: [Haskell-cafe] Parse error In-Reply-To: <4B52E525.50300@gmail.com> References: <4B52E0FB.5070201@btinternet.com> <4B52E525.50300@gmail.com> Message-ID: <4B52E789.5060204@btinternet.com> Tony Morris wrote: > No, but there's a specific reason why GHC consistently refuses to accept > your perfectly unreasonable code snippet :) > She sells csh on the sea shore. :-) > GHC accepts the following perfectly reasonable code snippet: > > main = do > putStrLn "Line 1" > putStrLn "Line 2" > > let xs = do x <- [1..10] > y <- [1..10] > return (x+y) > > print xs > Urg, but that's *ugly*. Is there no way I can reduce the amount of indentation to something more reasonable? From daniel.is.fischer at web.de Sun Jan 17 05:38:05 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sun Jan 17 05:12:35 2010 Subject: [Haskell-cafe] Parse error In-Reply-To: <4B52E789.5060204@btinternet.com> References: <4B52E0FB.5070201@btinternet.com> <4B52E525.50300@gmail.com> <4B52E789.5060204@btinternet.com> Message-ID: <201001171138.05884.daniel.is.fischer@web.de> Am Sonntag 17 Januar 2010 11:33:45 schrieb Andrew Coppin: > Tony Morris wrote: > > No, but there's a specific reason why GHC consistently refuses to > > accept your perfectly unreasonable code snippet :) > > She sells csh on the sea shore. :-) > > > GHC accepts the following perfectly reasonable code snippet: > > > > main = do > > putStrLn "Line 1" > > putStrLn "Line 2" > > > > let xs = do x <- [1..10] > > y <- [1..10] > > return (x+y) > > > > print xs > > Urg, but that's *ugly*. Is there no way I can reduce the amount of > indentation to something more reasonable? main = do ? putStrLn "Line 1" ? putStrLn "Line 2" ? let xs = do x <- [1..10] y <- [1..10] return (x+y) ? print xs That better? From ross at soi.city.ac.uk Sun Jan 17 05:43:32 2010 From: ross at soi.city.ac.uk (Ross Paterson) Date: Sun Jan 17 05:14:38 2010 Subject: [Haskell-cafe] Parse error In-Reply-To: <4B52E789.5060204@btinternet.com> References: <4B52E0FB.5070201@btinternet.com> <4B52E525.50300@gmail.com> <4B52E789.5060204@btinternet.com> Message-ID: <20100117104332.GA3803@soi.city.ac.uk> On Sun, Jan 17, 2010 at 10:33:45AM +0000, Andrew Coppin wrote: > Tony Morris wrote: > >main = do > > putStrLn "Line 1" > > putStrLn "Line 2" > > > > let xs = do x <- [1..10] > > y <- [1..10] > > return (x+y) > > > > print xs > > Urg, but that's *ugly*. Is there no way I can reduce the amount of > indentation to something more reasonable? Sure: start a new line and indentation level after every where, let, do or of. From andrewcoppin at btinternet.com Sun Jan 17 05:44:39 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jan 17 05:16:59 2010 Subject: [Haskell-cafe] Parse error In-Reply-To: <201001171138.05884.daniel.is.fischer@web.de> References: <4B52E0FB.5070201@btinternet.com> <4B52E525.50300@gmail.com> <4B52E789.5060204@btinternet.com> <201001171138.05884.daniel.is.fischer@web.de> Message-ID: <4B52EA17.5040201@btinternet.com> Daniel Fischer wrote: > Am Sonntag 17 Januar 2010 11:33:45 schrieb Andrew Coppin: > >> Urg, but that's *ugly*. Is there no way I can reduce the amount of >> indentation to something more reasonable? >> > > > main = do > putStrLn "Line 1" > putStrLn "Line 2" > > let xs = do > x <- [1..10] > y <- [1..10] > return (x+y) > > print xs > > That better? > It's an improvement. It's still not pretty, but I guess that's as good as it's going to get... Maybe this is an instance of Haskell trying to tell me "if you need to write a 20-line do-block in the middle of your function, you're doing it wrong". From jfredett at gmail.com Sun Jan 17 06:16:14 2010 From: jfredett at gmail.com (jfredett@gmail.com) Date: Sun Jan 17 05:48:38 2010 Subject: [Haskell-cafe] Haskell Weekly News: Issue 146 - January 17, 2010 Message-ID: <4b52f17e.9453f10a.31e3.00a9@mx.google.com> --------------------------------------------------------------------------- Haskell Weekly News http://sequence.complete.org/hwn/20100117 Issue 146 - January 17, 2010 --------------------------------------------------------------------------- Welcome to issue 146 of HWN, a newsletter covering developments in the [1]Haskell community. This has been a pretty light week in terms of discussion and announcments, but even in this comparative news lull we have the release of several new versions of packages. Inlcluding the start of a new IDE, some new job and graduate program openings, and some really excellent blog noise. Until next week, Haskellers, your Haskell Weekly News. Announcements haskell-src-exts 1.7.0. Niklas Broberg [2]announced a new release of haskell-src-exts Lite Haskell IDE. Mambo Banda [3]announced a new Haskell IDE, as part of his effort to learn Haskell. Functional Programming Bibliography. James Russell [4]announced the Functional Programming Bibliography, a new resource for the FP community. It, though in it's early stages, contains oer 1500 references (most of which are Haskell-related) to resources within the Functional Programming World. hakyll-1.0. Jasper Van der Jeugt [5]announced the release of version 1.0 of his static site generation tool, hakyll. From all (one) of us at the HWN, contragulations on the big 1.0! afv-0.0.0. Tom Hawkins [6]announced the initial release of 'Atom's Formal Verifier', a tool for verifying C code generated by Atom chp-2.0.0, chp-plus-1.0.0. Neil Brown [7]announced released new versions of his Comminicating Haskell Processes (CHP) packages. CHP is a message-passing concurrency library for Haskell. The major change in this version is a split of CHP into two packages, one containing core functionality, and one containing additional capabilities. Update for type-level library (0.2.4). Seyed Hosein Attarzadeh Niaki [8]announced a new version of his type-level library for type-level programming. This is a minor update to fix compatibility issues with dependencies. Two PhD positions in theoretical computer science. Alexandra Silva [9]announced vacancies for PhD positions in theoretical computer science at Leiden University. HaXml-1.20.1. Malcolm Wallace [10]announced a new, stable release of HaXml AST 2010 reminder--call for papers and presentations. John Hughes [11]reminded us of the AST 2010 call for papers and presentations. The submission deadline is only one week away. Job at Mylife. Julien Verlaguet [12]announced an availabiity for an OCaml developer at MyLife. Open Position (PhD student or Postdoc), U Tubingen, Germany. Torsten Grust [13]announced an open PhD/Postdoc position at the University of Tubingen in Germany. (ED: Apologies for the improper 'u' -- it should have an umlaut, but the compilation software is not cooperating) Palindromes 0.2. Johan Jeuring [14]announced a new release of the Palindromes package, including many new features and upgrades. Discussion From records to a type class. Taru Karttunen [15]asked about turning records into type classes, in an effort to make his bindings for Fuse more elegant. AlternativePrelude extension. Sjur Gjostein Karevoll [16]suggested a language pragma for alternative preludes. (ED: Again, apologies for the look-alike, but improper character). Blog noise [17]Haskell news from the [18]blogosphere. Blog posts from people new to the Haskell community are marked with >>>, be sure to welcome them! * Holumbus: [19]Linking Hayoo! Search Results. * Jeff Heard: [20]SPDE, Semi-functional programming for Processing. * Neil Mitchell: [21]Using .ghci files to run projects. * Neil Mitchell: [22]Better .ghci files. * Neil Brown: [23]Darcs. * Neil Brown: [24]Splitting CHP. * Darcs: [25]darcs weekly news #50. * Bryan O'Sullivan: [26]Progress on GHC's I/O manager. * Michael Snoyman: [27]New blog address. * Conal Elliot: [28]Exact Numeric Integration. I had missed this one last week (amidst the myriad, I failed to see it), so it is presented in this week's edition. Quotes of the Week * Jafet: closures are a poor man's object objects are a poor man's closure objects are a rich man's structs Poor programmers should start unions * monochrom: Time flies like an Arrow. Space leaks like a Monad. * monochrom: Haskell already has natural language support. Just switch your natural language to simple-typed lambda calculus. * edwardk: @remember Baugn @remember lambdabot fasta says: I think the @remember command is way overused. * Berengal: data Neither a b = Left | Right * Cale: Removing monad comprehensions was actually the snowball which caused the avalanche of fail in Haskell 98 About the Haskell Weekly News New editions are posted to [29]the Haskell mailing list as well as to [30]the Haskell Sequence and [31]Planet Haskell. [32]RSS is also available, and headlines appear on [33]haskell.org. To help create new editions of this newsletter, please see the information on [34]how to contribute. Send stories to jfredett . at . gmail . dot . com. The darcs repository is available at darcs get [35]http://patch-tag.com/r/jfredett/HWN2/pullrepo HWN2 . References 1. http://haskell.org/ 2. http://article.gmane.org/gmane.comp.lang.haskell.cafe/69197 3. http://article.gmane.org/gmane.comp.lang.haskell.cafe/69176 4. http://article.gmane.org/gmane.comp.lang.haskell.cafe/69153 5. http://article.gmane.org/gmane.comp.lang.haskell.cafe/69106 6. http://article.gmane.org/gmane.comp.lang.haskell.cafe/68995 7. http://article.gmane.org/gmane.comp.lang.haskell.cafe/68943 8. http://article.gmane.org/gmane.comp.lang.haskell.cafe/68940 9. http://article.gmane.org/gmane.comp.lang.haskell.general/17727 10. http://article.gmane.org/gmane.comp.lang.haskell.general/17725 11. http://article.gmane.org/gmane.comp.lang.haskell.general/17724 12. http://article.gmane.org/gmane.comp.lang.haskell.general/17723 13. http://article.gmane.org/gmane.comp.lang.haskell.general/17722 14. http://article.gmane.org/gmane.comp.lang.haskell.general/17721 15. http://thread.gmane.org/gmane.comp.lang.haskell.cafe/69207 16. http://thread.gmane.org/gmane.comp.lang.haskell.cafe/69194 17. http://planet.haskell.org/ 18. http://haskell.org/haskellwiki/Blog_articles 19. http://holumbus.fh-wedel.de/blog/?p=30 20. http://vis.renci.org/jeff/2010/01/15/spde-semi-functional-programming-for-processing/ 21. http://neilmitchell.blogspot.com/2010/01/using-ghci-files-to-run-projects.html 22. http://neilmitchell.blogspot.com/2010/01/better-ghci-files.html 23. http://chplib.wordpress.com/2010/01/14/darcs/ 24. http://chplib.wordpress.com/2010/01/11/splitting-chp/ 25. http://blog.darcs.net/2010/01/darcs-weekly-news-50.html 26. http://www.serpentine.com/blog/2010/01/11/progress-on-ghcs-io-manager/ 27. http://snoyberg.wordpress.com/2010/01/10/new-blog-address/ 28. http://conal.net/blog/posts/exact-numeric-integration/ 29. http://www.haskell.org/mailman/listinfo/haskell 30. http://sequence.complete.org/ 31. http://planet.haskell.org/ 32. http://sequence.complete.org/node/feed 33. http://haskell.org/ 34. http://haskell.org/haskellwiki/HWN 35. http://patch-tag.com/r/jfredett/HWN2/pullrepo%20HWN2 From jur at cs.uu.nl Sun Jan 17 06:17:36 2010 From: jur at cs.uu.nl (jur) Date: Sun Jan 17 05:50:00 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <4B521E59.8050505@henning-thielemann.de> References: <4B4CE8CE.9060202@btinternet.com> <27137827.post@talk.nabble.com> <4B521E59.8050505@henning-thielemann.de> Message-ID: >> Andrew Coppin wrote: >> >>> OK people, it's random statistics time! >>> >> >> OK, my version of meaningless statistics: >> Java: 450 pages (language only?) Which version is this? The version of the Java Language Specification (version 3.0, 2005) I am currently reading has 684 pages. I'd prefer to read only 450. Jur From ketil at malde.org Sun Jan 17 06:27:35 2010 From: ketil at malde.org (Ketil Malde) Date: Sun Jan 17 05:59:59 2010 Subject: [Haskell-cafe] Re: AlternativePrelude extension In-Reply-To: <1263697945.5616.22.camel@picard> (Maciej Piechotka's message of "Sun, 17 Jan 2010 03:12:26 +0000") References: <201001151910.00488.sjurberengal@gmail.com> <201001170009.38549.sjurberengal@gmail.com> <1263697945.5616.22.camel@picard> Message-ID: <87iqb1q8d4.fsf@malde.org> Maciej Piechotka writes: >> However, the option to set language extension globally is still >> available, either as an option to the compiler when building, or in >> the cabal file describing the package. > Hmm. Since the extensions should be specified in Cabal anyway (at least > I guess it does some detection if compiler supports them) shouldn't it > be specified in one place? I think there might be justification for doing it multiple places. The cabal file tells you what is required to build the package, the pragmas what is required to build each source file. Perhaps cabal should complain when source files use pragmas not declared in the cabal file, and perhaps also warn about options in the cabal file not used in any source file. -k (who didn't check the current state of affairs) -- If I haven't seen further, it is by standing in the footprints of giants From hreinhardt at gmail.com Sun Jan 17 06:35:08 2010 From: hreinhardt at gmail.com (Holger Reinhardt) Date: Sun Jan 17 06:07:31 2010 Subject: [Haskell-cafe] ANN: amqp-0.1 Message-ID: Hi, I've built an AMQP library. It currently only works with RabbitMQ and supports most of the 0-8 spec. If you don't know that AMQP is, this is a good introduction: http://blogs.digitar.com/jjww/2009/01/rabbits-and-warrens/ I have not done much testing, so this should be regarded as alpha quality. Get it here: http://hackage.haskell.org/package/amqp For some reason it doesn't compile on Hackage. It says "At least the following dependencies are missing: network-bytestring >=0.1.2". Is there a way to solve this? Regards, Holger -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100117/f2b4ce96/attachment.html From jv at informatik.uni-bonn.de Sun Jan 17 06:42:30 2010 From: jv at informatik.uni-bonn.de (=?ISO-8859-15?Q?Janis_Voigtl=E4nder?=) Date: Sun Jan 17 06:14:56 2010 Subject: [Haskell-cafe] Presentation about ICFP'09 programming contest Message-ID: <4B52F7A6.1000806@informatik.uni-bonn.de> Hi Haskell folk, If you are in Madrid tomorrow (Monday), you will likely not want to miss the video presentation by Andy Gill and his group about the techniques behind their running the ICFP'09 programming contest: http://www.program-transformation.org/PEPM10/SpecialFeature The presentation is scheduled to start 17:15, in the PEPM workshop room. Ciao, Janis. -- Jun.-Prof. Dr. Janis Voigtl?nder http://www.iai.uni-bonn.de/~jv/ mailto:jv@iai.uni-bonn.de From andrewcoppin at btinternet.com Sun Jan 17 06:47:35 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jan 17 06:19:55 2010 Subject: [Haskell-cafe] Language simplicity In-Reply-To: <27137827.post@talk.nabble.com> References: <4B4CE8CE.9060202@btinternet.com> <27137827.post@talk.nabble.com> Message-ID: <4B52F8D7.3080207@btinternet.com> Eduard Sergeev wrote: > OK, my version of meaningless statistics: > > C++ (ISO/IEC 14882:1998(E)): 325 pages (712 including standard libraries) > C# (ECMA-334): 505 pages (language only) > Java: 450 pages (language only?) > Scala (2.7): 125 pages (157 including standard library) > Eiffel (ECMA-367): 160 pages (language only) > ANSI SQL-92: 685 pages (language only) > Haskell-98: 77 pages (247 including Prelude) > Erlang (4.7.3) 162 pages (251 including builtin functions) > Scheme (R5RS): 17 pages (45 including standard procedures) > Interesting. So Scheme is the shortest by a mile, followed by Haskell '98, followed by another big gap. Now is that because Haskell is simple? Or is it because the Report assumes that you already know what functional programming and Milner-Hindley type inference are? From vandijk.roel at gmail.com Sun Jan 17 06:50:22 2010 From: vandijk.roel at gmail.com (Roel van Dijk) Date: Sun Jan 17 06:22:45 2010 Subject: [Haskell-cafe] Re: AlternativePrelude extension In-Reply-To: <87iqb1q8d4.fsf@malde.org> References: <201001151910.00488.sjurberengal@gmail.com> <201001170009.38549.sjurberengal@gmail.com> <1263697945.5616.22.camel@picard> <87iqb1q8d4.fsf@malde.org> Message-ID: On Sun, Jan 17, 2010 at 12:27 PM, Ketil Malde wrote: > I think there might be justification for doing it multiple places. ?The > cabal file tells you what is required to build the package, the pragmas > what is required to build each source file. > > Perhaps cabal should complain when source files use pragmas not > declared in the cabal file, and perhaps also warn about options in the > cabal file not used in any source file. The "extensions" field in a cabal package description is a bit tricky. The documentation states "A list of Haskell extensions used by every module". This might give the impression that it documents the various extensions used in a package. What it actually does is enable those extensions for every module. Duncan's comments on this ticket are enlightening: http://hackage.haskell.org/trac/hackage/ticket/370 I think the idea of adding a new field "used-extensions" warrants a separate ticket. From miaubiz at gmail.com Sun Jan 17 07:16:38 2010 From: miaubiz at gmail.com (miaubiz) Date: Sun Jan 17 06:49:00 2010 Subject: [Haskell-cafe] ANN: atom-0.1.3 In-Reply-To: <594c1e830912030352sfe4714ag10a582e3f1bd416d@mail.gmail.com> References: <594c1e830912030352sfe4714ag10a582e3f1bd416d@mail.gmail.com> Message-ID: <27198213.post@talk.nabble.com> Tom Hawkins-2 wrote: > > period 20 $ atom "checkSomeStuff" $ do > cond ok > assert "A" a > assert "B" b > cover "C" c > I am trying to generate a square wave. Here's the code: square <- bool "square" False period 2 $ atom "square high" $ phase 0 $ do square <== true assert "square is low" $ not_ $ value square period 2 $ atom "square low" $ phase 1 $ do square <== false assert "square is high" $ value square The tests fail every cycle because after each rule one of them is wrong. What would be the right way to formulate this code? Use cond on the rules? period 2 $ atom "square high" $ phase 0 $ do cond $ not_ $ value square square <== true cover "lowSquare" true assert "square is low" $ not_ $ value square period 2 $ atom "square low" $ phase 1 $ do cond $ value square square <== false cover "highSquare" true assert "square is high" $ value square as an aside, in Unit.hs: covered = [ words line !! 1 | line <- lines log, isPrefixOf "covered:" line ] because covered is the second word of the line from the log, the name of cover must be a single word. assertions and atoms can contain spaces as far as I can tell. br, miau -- View this message in context: http://old.nabble.com/ANN%3A-atom-0.1.3-tp26624813p27198213.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From ross at soi.city.ac.uk Sun Jan 17 07:20:44 2010 From: ross at soi.city.ac.uk (Ross Paterson) Date: Sun Jan 17 06:51:48 2010 Subject: [Haskell-cafe] ANN: amqp-0.1 In-Reply-To: References: Message-ID: <20100117122044.GA6027@soi.city.ac.uk> On Sun, Jan 17, 2010 at 12:35:08PM +0100, Holger Reinhardt wrote: > Get it here: http://hackage.haskell.org/package/amqp > > For some reason it doesn't compile on Hackage. It says "At least the following > dependencies are missing: network-bytestring >=0.1.2". Is there a way to solve > this? Sorry, that was a glitch in the upgrade to GHC 6.12.1. From mark.spezzano at chariot.net.au Sun Jan 17 08:30:36 2010 From: mark.spezzano at chariot.net.au (Mark Spezzano) Date: Sun Jan 17 08:03:03 2010 Subject: [Haskell-cafe] Parsers for Text Adventures Message-ID: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> Hi, I am writing a Text Adventure game in Haskell (like Zork) I have all of the basic parser stuff written as described in Hutton's Programming in Haskell and his associated papers. (I'm trying to avoid using 3rd party libraries, so that I can learn this myself) Everything that I have works (so far...) except for the following problem: I want to define a grammar using a series of Verbs like this: data Verb = Go | Get | Jump | Climb | Give etc, etc deriving (Show, Read) and then have my parser "get" one of these Verb tokens if possible; otherwise it should do something (?) else like give an error message stating "I don't know that command" Now, Hutton gives examples of parsing strings into string whereas I want to parse Strings into my Verbs So, if the user types "get sword" then it will tokenise "get" as type Verb's data constructor Get and perhaps "sword" into a Noun called Sword My parser is defined like this: newtype Parser a = Parser (String -> [(a, String)]) So I CAN give it a Verb type but this is where I run into a problem.... I've written a Parser called keyword keyword :: Parser Verb keyword = do x <- many1 letter return (read x) (read this as "take-at-least-one-alphabetic-letter-and-convert-to-a-Verb-type") which DOES work provided that the user types in one of my Verbs. If they don't, well, the whole thing fails with an Exception and halts processing, returning to GHCi prompt. Question: Am I going about this the right way? I want to put together lots of "data" types like Verb and Noun etc so that I can build a kind of "BNF grammar". Question: If I am going about this the right way then what do I about the "read x" bit failing when the user stops typing in a recognised keyword. I could catch the exception, but typing an incorrect sentence is just a typo, not really appropriate for an exception, I shouldn't think. If it IS appropriate to do this in Haskell, then how do I catch this exception and continue processing. I thought that exceptions should be for exceptional circumstances, and it would seem that I might be misusing them in this context. Thanks Mark Spezzano From haberg at math.su.se Sun Jan 17 08:51:32 2010 From: haberg at math.su.se (Hans Aberg) Date: Sun Jan 17 08:23:55 2010 Subject: [Haskell-cafe] Parse error In-Reply-To: <4B52EA17.5040201@btinternet.com> References: <4B52E0FB.5070201@btinternet.com> <4B52E525.50300@gmail.com> <4B52E789.5060204@btinternet.com> <201001171138.05884.daniel.is.fischer@web.de> <4B52EA17.5040201@btinternet.com> Message-ID: <5CC1228E-3D9F-49C0-A8F7-875639EBC595@math.su.se> On 17 Jan 2010, at 11:44, Andrew Coppin wrote: >>> Urg, but that's *ugly*. Is there no way I can reduce the amount of >>> indentation to something more reasonable? >> >> main = do >> putStrLn "Line 1" >> putStrLn "Line 2" >> >> let xs = do >> x <- [1..10] >> y <- [1..10] >> return (x+y) >> >> print xs >> >> That better? > > It's an improvement. It's still not pretty, but I guess that's as > good as it's going to get... > > Maybe this is an instance of Haskell trying to tell me "if you need > to write a 20-line do-block in the middle of your function, you're > doing it wrong". Haskell starts the new indentation level where the following lexeme is (Haskell-98 Report, sec. 2.7). So to reduce indentation, one must start a new line (already mentioned in this thread). This works in Hugs: main = do putStrLn "Line 1" putStrLn "Line 2" let xs = do x <- [1..10] y <- [1..10] return (x+y) print xs The "xs" on a new line looks a bit unusual, and it takes a bit more vertical space, but one gets nice indentation levels. Hans From felipe.lessa at gmail.com Sun Jan 17 08:52:19 2010 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Sun Jan 17 08:24:44 2010 Subject: [Haskell-cafe] Dependency trickery In-Reply-To: <4B52E1CA.70904@btinternet.com> References: <4B52E1CA.70904@btinternet.com> Message-ID: <20100117135219.GA12958@kira.casa> On Sun, Jan 17, 2010 at 10:09:14AM +0000, Andrew Coppin wrote: > Suppose I write some code that can work with Gtk2hs or wxHaskell. > How do I go about making that into a package? > > Specifically, how do I make it so that you don't have to install > Gtk2hs *and* wxHaskell to build it? Do I have to actually make it > into two seperate packages to do that? You just need to add a flag 'gtk2hs' and then construct the Build-Depends depending on the value of the flag. However, if e.g. that flag is by default True, then users of wxHaskell will have to manually change its value. I.e. it is not automatic based on what the user has on his system. > Also, supposing we have another package which requires the first, > but doesn't care whether it's using Gtk2hs or wxHaskell. How do I do > that? Obviously the answer depends on what happens in the previous > step. If I make two seperate packages, for example, and they both > export the same module, can I just add optional dependancies on > both? Does Cabal support that? Just depend on the package :), how the first package was compiled is out of the scope of the second one. > Not that I'm attempting to *do* this, you understand. I'd just like > to know if it's possible... Another possibility is to factor out your API into an abstract interface (maybe using type classes). Then you would have firstpackage-base firstpackage-wx firstpackage-gtk secondpackage (depending on firstpackage-base) But then you only factor your problem to your outmost package, say, myapp (depends on -wx or -gtk depending on a flag) HTH, -- Felipe. From taruti at taruti.net Sun Jan 17 08:54:01 2010 From: taruti at taruti.net (Taru Karttunen) Date: Sun Jan 17 08:26:24 2010 Subject: [Haskell-cafe] Re: AlternativePrelude extension In-Reply-To: References: <201001151910.00488.sjurberengal@gmail.com> <201001170009.38549.sjurberengal@gmail.com> <1263697945.5616.22.camel@picard> <87iqb1q8d4.fsf@malde.org> Message-ID: <1263736150-sup-7877@oz.taruti.net> Excerpts from Roel van Dijk's message of Sun Jan 17 13:50:22 +0200 2010: > The "extensions" field in a cabal package description is a bit tricky. > The documentation states "A list of Haskell extensions used by every > module". This might give the impression that it documents the various > extensions used in a package. What it actually does is enable those > extensions for every module. > > Duncan's comments on this ticket are enlightening: > http://hackage.haskell.org/trac/hackage/ticket/370 > > I think the idea of adding a new field "used-extensions" warrants a > separate ticket. Why not have Cabal autogenerate that information? Hackage already displays generated info like "Built on" and thus it should be doable. i.e. 1) Scan all the source files used for extension pragmas 2) Generate a list of those 3) Include that on Hackage The functionality needed for this is also needed for validating the proposed used-extensions field is correct, and thus not harder to implement. - Taru Karttunen From lrpalmer at gmail.com Sun Jan 17 09:00:17 2010 From: lrpalmer at gmail.com (Luke Palmer) Date: Sun Jan 17 08:32:41 2010 Subject: [Haskell-cafe] Parsers for Text Adventures In-Reply-To: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> References: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> Message-ID: <7ca3f0161001170600x2440521anc367a91785c6ce03@mail.gmail.com> On Sun, Jan 17, 2010 at 6:30 AM, Mark Spezzano wrote: > I've written a Parser called keyword > > keyword :: Parser Verb > keyword = do x <- many1 letter > return (read x) > > (read this as > "take-at-least-one-alphabetic-letter-and-convert-to-a-Verb-type") > > which DOES work provided that the user types in one of my Verbs. If they > don't, well, the whole thing fails with an Exception and halts processing, > returning to GHCi prompt. > > Question: Am I going about this the right way? I want to put together lots > of "data" types like Verb and Noun etc so that I can build a kind of "BNF > grammar". > Sounds good to me. > > Question: If I am going about this the right way then what do I about the > "read x" bit failing when the user stops typing in a recognised keyword. I > could catch the exception, but typing an incorrect sentence is just a typo, > not really appropriate for an exception, I shouldn't think. If it IS > appropriate to do this in Haskell, then how do I catch this exception and > continue processing. > In my opinion, traditional exceptions have no place in Haskell. In some others' opinions, they have their place, but are infrequently used. In any case, you're right, this is not the time to catch an exception. This is a usability failure on the part of the Haskell prelude. read should have the type Read a => String -> Maybe a, because failure is possible. You can write a proper version: import Data.Maybe (listToMaybe) maybeRead :: Read a => String -> Maybe a maybeRead = fmap fst . listToMaybe . reads Luke -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100117/1f2eb538/attachment.html From stephen.tetley at gmail.com Sun Jan 17 09:02:38 2010 From: stephen.tetley at gmail.com (Stephen Tetley) Date: Sun Jan 17 08:34:59 2010 Subject: [Haskell-cafe] Parsers for Text Adventures In-Reply-To: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> References: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> Message-ID: <5fdc56d71001170602q5ff52d7bu10f6e6c090546ae1@mail.gmail.com> Hello Mark [ Literate haskell follows... ] > module Verb where > import qualified Data.Map as Map > import Data.Char > data Verb = Go | Get | Jump | Climb | Give deriving (Show, Read) I wouldn't use read instead something either a simple function: > verb :: String -> Maybe Verb > verb "Go" = Just Go > verb "Get" = Just Get > verb _ = Nothing Or possible a Map: > verb2 :: String -> Maybe Verb > verb2 s = Map.lookup s verb_map > verb_map :: Map.Map String Verb > verb_map = Map.fromAscList [ ("Go", Go), ("Get", Get) {- .. -} ] You could then do more about say case sensitivity - e.g. add ("get",Get) etc or always convert to upper before querying the map. > verb3 :: String -> Maybe Verb > verb3 s = Map.lookup (map toUpper s) verb_map2 > verb_map2 :: Map.Map String Verb > verb_map2 = Map.fromAscList [ ("GO", Go), ("GET", Get) {- .. -} ] Best wishes Stephen From daniel.is.fischer at web.de Sun Jan 17 09:02:59 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sun Jan 17 08:37:06 2010 Subject: [Haskell-cafe] Parsers for Text Adventures In-Reply-To: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> References: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> Message-ID: <201001171502.59923.daniel.is.fischer@web.de> Am Sonntag 17 Januar 2010 14:30:36 schrieb Mark Spezzano: > Hi, > > I am writing a Text Adventure game in Haskell (like Zork) > > I have all of the basic parser stuff written as described in Hutton's > Programming in Haskell and his associated papers. (I'm trying to avoid > using 3rd party libraries, so that I can learn this myself) > > Everything that I have works (so far...) except for the following > problem: > > I want to define a grammar using a series of Verbs like this: > > data Verb = Go | Get | Jump | Climb | Give etc, etc deriving (Show, > Read) > > and then have my parser "get" one of these Verb tokens if possible; > otherwise it should do something (?) else like give an error message > stating "I don't know that command" > > Now, Hutton gives examples of parsing strings into string whereas I want > to parse Strings into my Verbs > > So, if the user types "get sword" then it will tokenise "get" as type > Verb's data constructor Get and perhaps "sword" into a Noun called Sword But the Read instance can only read "Get", not "get". You'd have to capitalise the input to work with derived Read instances. > > My parser is defined like this: > > newtype Parser a = Parser (String -> [(a, String)]) > > So I CAN give it a Verb type > > but this is where I run into a problem.... > > I've written a Parser called keyword > > keyword :: Parser Verb > keyword = do x <- many1 letter case reads x of [(verb,"")] -> return verb _ -> fail "No verb" fails gracefully (assuming your Monad instance for Parser has fail _ = Parser (\_ -> []) ). > return (read x) > > (read this as > "take-at-least-one-alphabetic-letter-and-convert-to-a-Verb-type") > > which DOES work provided that the user types in one of my Verbs. If they > don't, well, the whole thing fails with an Exception and halts > processing, returning to GHCi prompt. > > Question: Am I going about this the right way? I want to put together > lots of "data" types like Verb and Noun etc so that I can build a kind > of "BNF grammar". > > Question: If I am going about this the right way then what do I about > the "read x" bit failing when the user stops typing in a recognised > keyword. I could catch the exception, but typing an incorrect sentence > is just a typo, not really appropriate for an exception, I shouldn't > think. If it IS appropriate to do this in Haskell, then how do I catch > this exception and continue processing. You could try guessing what the user meant (cf. Levenshtein distance) for added comfort. Or you could ask for corrected input immediately when parsing an input fails. With the graceful failing of the parse as above, that doesn't need exceptions. If you think catching exceptions might be preferable after all, take a look at Control.Exception. > > I thought that exceptions should be for exceptional circumstances, and > it would seem that I might be misusing them in this context. > > Thanks > > Mark Spezzano From uzytkownik2 at gmail.com Sun Jan 17 09:13:14 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Sun Jan 17 08:45:57 2010 Subject: [Haskell-cafe] Re: Parse error In-Reply-To: <201001171810.32810.voidprayer@gmail.com> References: <4B52E0FB.5070201@btinternet.com> <201001171810.32810.voidprayer@gmail.com> Message-ID: <1263737594.5590.1.camel@picard> On Sun, 2010-01-17 at 18:10 +0800, VoidPrayer wrote: > let ... > in ... > > I guess GHC is finding where "in" is. Except that: main = do l <- getLine let l' = lines l print l' Is perfectly valid without in. Similary: something = proc (x, y) -> do x' <- someArrow -< x let z = x + y + x' returnA -< z Regards From lrpalmer at gmail.com Sun Jan 17 09:20:06 2010 From: lrpalmer at gmail.com (Luke Palmer) Date: Sun Jan 17 08:52:31 2010 Subject: [Haskell-cafe] Parsers for Text Adventures In-Reply-To: <5fdc56d71001170602q5ff52d7bu10f6e6c090546ae1@mail.gmail.com> References: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> <5fdc56d71001170602q5ff52d7bu10f6e6c090546ae1@mail.gmail.com> Message-ID: <7ca3f0161001170620kd38faa1x83ee3d408b62b615@mail.gmail.com> On Sun, Jan 17, 2010 at 7:02 AM, Stephen Tetley wrote: > I wouldn't use read instead something either a simple function: > > > verb :: String -> Maybe Verb > > verb "Go" = Just Go > > verb "Get" = Just Get > > verb _ = Nothing > > Or possible a Map: > > > verb2 :: String -> Maybe Verb > > verb2 s = Map.lookup s verb_map > > > verb_map :: Map.Map String Verb > > verb_map = Map.fromAscList [ ("Go", Go), ("Get", Get) {- .. -} ] > Oh, yeah, I like these better than relying on the Read instance. Relying on Read and Show for program logic has been kind of an implicit smell to me, and I can put my finger on why now: you lose alpha conversion on the program scale. I like the ability to rename with confidence. Plus, this way it is natural to encode synonyms; eg. "take" and "get". Though depending on the vernacular of the game you might not want that. I'm not sure what it means to take out of bed. Luke > > > You could then do more about say case sensitivity - e.g. add ("get",Get) > etc > or always convert to upper before querying the map. > > > > verb3 :: String -> Maybe Verb > > verb3 s = Map.lookup (map toUpper s) verb_map2 > > > verb_map2 :: Map.Map String Verb > > verb_map2 = Map.fromAscList [ ("GO", Go), ("GET", Get) {- .. -} ] > > > Best wishes > > Stephen > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100117/6b1943cc/attachment-0001.html From malcolm.wallace at cs.york.ac.uk Sun Jan 17 09:25:39 2010 From: malcolm.wallace at cs.york.ac.uk (Malcolm Wallace) Date: Sun Jan 17 08:58:01 2010 Subject: [Haskell-cafe] Dependency trickery In-Reply-To: <20100117135219.GA12958@kira.casa> References: <4B52E1CA.70904@btinternet.com> <20100117135219.GA12958@kira.casa> Message-ID: <3425F3AA-0F7A-4664-A209-82E947508F07@cs.york.ac.uk> >> Suppose I write some code that can work with Gtk2hs or wxHaskell. >> How do I go about making that into a package? > > You just need to add a flag 'gtk2hs' and then construct the > Build-Depends depending on the value of the flag. However, if > e.g. that flag is by default True, then users of wxHaskell will > have to manually change its value. I.e. it is not automatic > based on what the user has on his system. Not true. The value of the flag *is* determined automatically based on what packages you already have on your system. For instance, if your cabal file says Flag hasGTK Default: True Library if hasGTK Build-Depends: gtk2hs else Build-Depends: wxHaskell and your installed system has wx but not gtk, then it will still select the wx branch, regardless of the value of the flag default. The only meaning of the default value is, if *both* possible solutions could potentially build successfully, then which one will be preferred. Regards, Malcolm From voidprayer at gmail.com Sun Jan 17 09:32:55 2010 From: voidprayer at gmail.com (VoidPrayer) Date: Sun Jan 17 09:05:29 2010 Subject: [Haskell-cafe] Re: Parse error In-Reply-To: <1263737594.5590.1.camel@picard> References: <4B52E0FB.5070201@btinternet.com> <201001171810.32810.voidprayer@gmail.com> <1263737594.5590.1.camel@picard> Message-ID: <201001172232.55688.voidprayer@gmail.com> Oh, I should know that. Thank you. By the way, is it only valid when "let" only affects the one expression after that? I read "where vs let" in the HaskellWiki but all the examples are "let ... in". ? 2010? 1? 17? ??? 22:13:14?Maciej Piechotka ??: > On Sun, 2010-01-17 at 18:10 +0800, VoidPrayer wrote: > > let ... > > in ... > > > > I guess GHC is finding where "in" is. > > Except that: > > main = do l <- getLine > let l' = lines l > print l' > > Is perfectly valid without in. Similary: > > something = proc (x, y) -> do x' <- someArrow -< x > let z = x + y + x' > returnA -< z > > Regards > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From felipe.lessa at gmail.com Sun Jan 17 09:42:19 2010 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Sun Jan 17 09:14:44 2010 Subject: [Haskell-cafe] Dependency trickery In-Reply-To: <3425F3AA-0F7A-4664-A209-82E947508F07@cs.york.ac.uk> References: <4B52E1CA.70904@btinternet.com> <20100117135219.GA12958@kira.casa> <3425F3AA-0F7A-4664-A209-82E947508F07@cs.york.ac.uk> Message-ID: <20100117144219.GB12958@kira.casa> On Sun, Jan 17, 2010 at 02:25:39PM +0000, Malcolm Wallace wrote: > Not true. The value of the flag *is* determined automatically based > on what packages you already have on your system. Oh, then please forgive my mistake. Cabal is smarter than I am :). Thanks, Malcolm! -- Felipe. From bulat.ziganshin at gmail.com Sun Jan 17 09:46:58 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Jan 17 09:19:25 2010 Subject: [Haskell-cafe] Re: Parse error In-Reply-To: <201001172232.55688.voidprayer@gmail.com> References: <4B52E0FB.5070201@btinternet.com> <201001171810.32810.voidprayer@gmail.com> <1263737594.5590.1.camel@picard> <201001172232.55688.voidprayer@gmail.com> Message-ID: <1783642139.20100117174658@gmail.com> Hello VoidPrayer, Sunday, January 17, 2010, 5:32:55 PM, you wrote: > By the way, is it only valid when "let" only affects the one expression after > that? I read "where vs let" in the HaskellWiki but all the examples are "let > ... in". the "let" inside "do" is just a syntax sugar: do xxx let yyy zzz ttt is equivalent to do xxx let yyy in do zzz; ttt -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From ozgurakgun at gmail.com Sun Jan 17 09:55:05 2010 From: ozgurakgun at gmail.com (Ozgur Akgun) Date: Sun Jan 17 09:27:27 2010 Subject: [Haskell-cafe] cabal install vacuum-cairo Message-ID: <7be1feae1001170655l7ce0aed8p62d154321b282464@mail.gmail.com> Cafe, I've been trying to install vacuum-cairo using cabal but I couldn't have it installed because of the missing packages cairo, svg and gtkcairo. What should I do to install vacuum-cairo? Thanks for any help in advance, -- Ozgur Akgun -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100117/b172eb40/attachment.html From gwern0 at gmail.com Sun Jan 17 10:01:22 2010 From: gwern0 at gmail.com (Gwern Branwen) Date: Sun Jan 17 09:33:42 2010 Subject: [Haskell-cafe] cabal install vacuum-cairo In-Reply-To: <7be1feae1001170655l7ce0aed8p62d154321b282464@mail.gmail.com> References: <7be1feae1001170655l7ce0aed8p62d154321b282464@mail.gmail.com> Message-ID: On Sun, Jan 17, 2010 at 9:55 AM, Ozgur Akgun wrote: > Cafe, > > I've been trying to install vacuum-cairo using cabal but I couldn't have it > installed because of the missing packages cairo, svg and gtkcairo. > > What should I do to install vacuum-cairo? > > Thanks for any help in advance, Those packages are provided by http://www.haskell.org/gtk2hs/ cabal-install didn't pull them in because they are too difficult to cabalize & hence not on Hackage. -- gwern From michael at snoyman.com Sun Jan 17 11:01:03 2010 From: michael at snoyman.com (Michael Snoyman) Date: Sun Jan 17 10:33:25 2010 Subject: [Haskell-cafe] PROPOSAL: Web application interface Message-ID: <29bf512f1001170801r15f1537bne4dd71c07b0682b8@mail.gmail.com> Following up on the previous thread, I've started a github project for some ideas of a web application interface. It's borrowing from both Hyena and Hack, with a few of its own ideas. The project is available at http://github.com/snoyberg/wai, and the Network.Wai module is available at http://github.com/snoyberg/wai/blob/master/Network/Wai.hs. The repository also includes a port of hack-handler-simpleserver, and an incredibly simple webapp to demonstrate usage. I intend to make the demonstration slightly more sophisticated. Finally, the repository is now yet cabalized. I consider this currently to be a straw-man proposal, intended to highlight the issues of contention that may arise. It would be wonderful is we could get the major players in the Haskell web space to get behind a single WAI. The entire Network.Wai module right now weighs in at only 74 lines, so I do not consider this to be a heavy-weight proposal. Here as some design notes: - Most important point: RequestBody and ResponseBody. I will explain below. - I've renamed "Env" in Hack and "Environment" in Hyena to "Request." This seems more consistent with other technologies out there. However, I have no feelings on this subject at all, and can easily bend to public demand. - I've stuck with UrlScheme from Hack, while Hyena called it protocol. Similar, the RequestMethod constructors are ALLCAPS like Hack, unlike Hyena's Uppercase. Once again, no strong feelings. - I've sided with Hyena as far as making all representations in ByteString. Current exception is remoteHost, which is a Hack-only variable in any event. - Instead of representing the response as a tuple ala Hyena, created a data type like Hack. - The only dependency for this module is bytestring. It might be tempting to represent RequestBody and ResponseBody with a ReaderT IO monad, but this would introduce a dependency on either mtl or transformers, which I would consider a Very Bad Idea. The main complaint against Hack is its lack of an enumerator interface for the request and response body. However, this simply words the complaint incorrectly; I don't think anyone is married to the need of an enumerator. Rather, we want to be able to efficiently handle arbitrarily lengthed content in constant space, without necesarily resorting to unsafeInterleaveIO (ie, lazy I/O). There are a number of issues with left-fold enumerators IMO. It is basically promoting an inversion of control. This may be often times valuable. However, to make this the *only* interface precludes other use cases. The most basic one I ran into was wanting to interleave with read processes. I do not mean to say that it's impossible to interleave reads in such a manner, but I think it's more natural in the approach advocated by wai. I consider RequestBody and ResponseBody to be mirroring the CGI protocol. Essentially, each handler (CGI, simpleserver, FastCGI, happstack server, etc) will define data types which instanciate RequestBodyClass and ResponseBodyClass. RequestBodyClass provides a single method, receiveByteString, to extract a chunk of data from the request body. ResponseBodyClass provides (currently) three methods, for sending strict bytestrings, lazy bytestrings, and files. While default implementations are provided for the last two based on the first, implementations can provide more efficient versions of them if desired. For example, sendFile might be replaced by a system call to sendfile. Let me know your thoughts. I'm purposely leaving out many of my reasons for the decisions I've made for brevity, since this e-mail is long enough as is. I'm happy to answer any questions as to why I went in a certain direction. It's also possible that I simply overlooked a detail. Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100117/9ad43fa3/attachment.html From mblazevic at stilo.com Sun Jan 17 11:59:50 2010 From: mblazevic at stilo.com (=?utf-8?B?TWFyaW8gQmxhxb5ldmnEhw==?=) Date: Sun Jan 17 11:32:15 2010 Subject: [Haskell-cafe] Re: Arrow instance of Transducer (Was: [Haskell] ANN: Streaming Component Combinators 0.4) Message-ID: <.1263747590@magma.ca> >>> Stupid question: Is it related to Arrows? >> >> Not really. You might say it's more general than arrows, because >> the streaming components are not restricted to a single input and >> single output type. On the other hand, they are all specific to stream >> processing, much like Fudgets and Yampa which are arrow-based. > > Arrows use tuple values for multiple inputs and outputs. Actually I'm > using arrows this way for signal processing. > >> I suppose the Transducer data type [1] could be made an Arrow >> instance, which would let me rename the 'connect' combinator [2] to >> (>>>). I'll have a look at Yampa to see if I can harvest more >> combinator names, thank you! After some investigation, I've concluded that Transducer cannot be made an instance of Arrow in any way that's both practical and general. The reason is that a Transducer converts a finite stream to another finite stream of arbitrary length. If we ignore effects, it's like a function of type [a] -> [b]. When trying to define an instance of Arrow for > newtype Transducer a b = Transducer ([a] -> [b]) the arr and (>>>) methods are trivial: > instance Arrow Transducer where > arr f = Transducer (map f) > Transducer t1 >>> Transducer t2 = Transducer (t2 . t1) but there is no satisfactory definition for the method first. A sensible definition, IMO, would have to give rise to a pairwise (***), so if we have two transducers t1 and t2 which respectively convert [a,b] to [c,d] and [1,2] to [3,4], t1 *** t2 would have to map [(a,1), (b,2)] to [(c,3), (d,4)]. There is no general way to define such a method first for the Transducer data type above. One can try appending the right-hand sides of the input to a queue and adding them to the outputs of the argument transducer: > first (Transducer t) = Transducer (uncurry (zip . t) . unzip) but this works only for injective transducers that map each new input item to exactly one output item. If the input stream has finite length, the input and output stream must be of equal length. In his paper "Generalising Monads to Arrows" from 1998, John Hughes defines a similar Arrow instance for stream processors operating on infinite streams which theoretically works for non-injective transforms, but leaks infinite space and can't be adopted to finite stream processors. HXT defines a different kind of an Arrow instance similar to the list monad instance. This approach can combine non-injective transforms, but in it the t1 *** t2 example above would map the input [(a,1), (b,2)] to [(c,3), (c,4), (d,3), (d,4)]. While this is a simple and lawful Arrow instance, I don't find it useful for stream processing. Yampa and other Functional Reactive Programming libraries associate a unique timestamp to each stream item. Method first can use this timestamp to associate input and output items even if the transducer leaves out some output items, and if the time stamps are ordered in each stream I guess it could also handle extra output items unrelated to any input. I'm not certain to what extent the FRP transducers (i.e., signal processors) are allowed to do this. To summarize: while I'd love the benefits of satisifying an Arrow instance, the loss of generality seems too high for me. SCC transducers work on finite streams of any values, and their output stream need not have any resemblance to the input stream. I may define an Arrow-conformant subclass of Transducer in a future version of SCC, perhaps operating on streams with timestamped values. >> >> [1] >> http://hackage.haskell.org/packages/archive/scc/0.4/doc/html/Control-Concurrent-SCC-Types.html#t%3ATransducer >> >> [2] >> http://hackage.haskell.org/packages/archive/scc/0.4/doc/html/Control-Concurrent-SCC-Combinators.html#v%3Aconnect > > In whatever way it is related to arrows, maybe you can mention it on the > project page. I'll copy this message there. From tomahawkins at gmail.com Sun Jan 17 13:16:03 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Sun Jan 17 12:48:24 2010 Subject: [Haskell-cafe] ANN: afv-0.0.2 Message-ID: <594c1e831001171016s7dffeaf0jc383e3c4da5e32d8@mail.gmail.com> AFV is an infinite state model checker for simple, iterative C programs. This release adds some new name checks, a few minor bug fixes, basic support for functions, and a little stronger type checking. Though most of the C language is still not supported, it can verify a lot of interesting behavior -- including one of my bugs that pulverized about $40K of hydraulics hardware last year. :-) http://hackage.haskell.org/package/afv/ From iavor.diatchki at gmail.com Sun Jan 17 13:33:26 2010 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Sun Jan 17 13:05:48 2010 Subject: [Haskell-cafe] Parsers for Text Adventures In-Reply-To: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> References: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> Message-ID: <5ab17e791001171033m82ebab4k164407e34d25deb8@mail.gmail.com> Hi Mark, On Sun, Jan 17, 2010 at 5:30 AM, Mark Spezzano wrote: > Question: Am I going about this the right way? I want to put together lots of "data" types like Verb and Noun etc so that I can build a kind of "BNF grammar". Your basic idea to use a datatype is a good one. You just need to implement it in a slightly different way. For example, you could write a function: string :: String -> Parser () Given a string, this function returns a parser that will try to recognize the string in the input. If successful, the parser returns a single trivial result, otherwise it fails (i.e. returns an empty list of result). You will also need a function, say (<+>): (<+>) :: Parser a -> Parser a -> Parser a This function will apply two parser two the same input and combine their results. Now you can write your verb parser: verb :: Parser Verb verb = (string "jump" >> return Jump) <+> ((string "get" <+> string "take") >> return Get) -- supports synonyms <+> ... etc .. Hope that this helps. -Iavor PS: By the way, there are a number of libraries that already implement such basic "parser combinators" so you can use one of them if you are not interested in the actual low level details of how the parser works. One such library is "parsimony", another is "parsec". > Question: If I am going about this the right way then what do I about the "read x" bit failing when the user stops typing in a recognised keyword. I could catch the exception, but typing an incorrect sentence is just a typo, not really appropriate for an exception, I shouldn't think. If it IS appropriate to do this in Haskell, then how do I catch this exception and continue processing. From inforichland at gmail.com Sun Jan 17 13:45:00 2010 From: inforichland at gmail.com (Tim Wawrzynczak) Date: Sun Jan 17 13:17:21 2010 Subject: [Haskell-cafe] Parsers for Text Adventures In-Reply-To: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> References: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> Message-ID: <4335a3261001171045l2ab1a4f8s4911db79e84cae8e@mail.gmail.com> Hi Mark, I recently ported Conrad Barski's 'Casting SPELs in Lisp' to Haskell (a text adventure game). I had some of these problems as well, and you can find my code on Hackage (the package is called Advgame). Some things in there might be of some help. Cheers, - Tim On Sun, Jan 17, 2010 at 7:30 AM, Mark Spezzano wrote: > Hi, > > I am writing a Text Adventure game in Haskell (like Zork) > > I have all of the basic parser stuff written as described in Hutton's > Programming in Haskell and his associated papers. (I'm trying to avoid using > 3rd party libraries, so that I can learn this myself) > > Everything that I have works (so far...) except for the following problem: > > I want to define a grammar using a series of Verbs like this: > > data Verb = Go | Get | Jump | Climb | Give etc, etc deriving (Show, Read) > > and then have my parser "get" one of these Verb tokens if possible; > otherwise it should do something (?) else like give an error message stating > "I don't know that command" > > Now, Hutton gives examples of parsing strings into string whereas I want to > parse Strings into my Verbs > > So, if the user types "get sword" then it will tokenise "get" as type > Verb's data constructor Get and perhaps "sword" into a Noun called Sword > > My parser is defined like this: > > newtype Parser a = Parser (String -> [(a, String)]) > > So I CAN give it a Verb type > > but this is where I run into a problem.... > > I've written a Parser called keyword > > keyword :: Parser Verb > keyword = do x <- many1 letter > return (read x) > > (read this as > "take-at-least-one-alphabetic-letter-and-convert-to-a-Verb-type") > > which DOES work provided that the user types in one of my Verbs. If they > don't, well, the whole thing fails with an Exception and halts processing, > returning to GHCi prompt. > > Question: Am I going about this the right way? I want to put together lots > of "data" types like Verb and Noun etc so that I can build a kind of "BNF > grammar". > > Question: If I am going about this the right way then what do I about the > "read x" bit failing when the user stops typing in a recognised keyword. I > could catch the exception, but typing an incorrect sentence is just a typo, > not really appropriate for an exception, I shouldn't think. If it IS > appropriate to do this in Haskell, then how do I catch this exception and > continue processing. > > I thought that exceptions should be for exceptional circumstances, and it > would seem that I might be misusing them in this context. > > Thanks > > Mark Spezzano > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100117/d1255949/attachment.html From gue.schmidt at web.de Sun Jan 17 14:48:05 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Sun Jan 17 14:20:53 2010 Subject: [Haskell-cafe] Takusen - reading from one db inserting into another Message-ID: <4B536975.1050500@web.de> Hi, I know how to use Takusen with a *single* connection, but I cannot figure out how to read from one database while inserting to another. Could someone please explain to me how I can do that? G?nther From will_n48 at yahoo.com Sun Jan 17 15:22:07 2010 From: will_n48 at yahoo.com (Will Ness) Date: Sun Jan 17 14:54:54 2010 Subject: [Haskell-cafe] Why no merge and listDiff? Message-ID: Hello cafe, I wonder, if we have List.insert and List.union, why no List.merge (:: Ord a => [a] -> [a] -> [a]) and no List.minus ? These seem to be pretty general operations. Brief look into haskell-prime-report/list.html reveals nothing. Could we please have them? On the wider perspective, is their a way to declare an /ordered/ list on the type level (e.g. [1,2,3] would be one, but not [2,3,1])? Non-decreasing lists? Cyclical, or of certain length? What are such types called? TIA! From miguelimo38 at yandex.ru Sun Jan 17 15:41:17 2010 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Sun Jan 17 15:13:39 2010 Subject: [Haskell-cafe] Why no merge and listDiff? In-Reply-To: References: Message-ID: On 17 Jan 2010, at 23:22, Will Ness wrote: > What are such types called? Dependent ones. From derek.a.elkins at gmail.com Sun Jan 17 15:54:10 2010 From: derek.a.elkins at gmail.com (Derek Elkins) Date: Sun Jan 17 15:26:30 2010 Subject: [Haskell-cafe] Why no merge and listDiff? In-Reply-To: References: Message-ID: <61f84eff1001171254pddefd6eo57943727b01d7cb2@mail.gmail.com> On Sun, Jan 17, 2010 at 2:22 PM, Will Ness wrote: > Hello cafe, > > I wonder, if we have List.insert and List.union, why no List.merge (:: Ord a => > [a] -> [a] -> [a]) and no List.minus ? These seem to be pretty general > operations. Presumably by List.minus you mean the (\\) function in Data.List. You probably also want to look at the package data-ordlist on hackage (http://hackage.haskell.org/packages/archive/data-ordlist/0.0.1/doc/html/Data-OrdList.html) which represents sets and bags as ordered lists and has all of the operations you mention. > Brief look into haskell-prime-report/list.html reveals nothing. > > Could we please have them? The trend is to remove things from "standard" libraries and to push them more to 3rd party libraries hosted on hackage. > On the wider perspective, is their a way to declare an /ordered/ list on the > type level (e.g. [1,2,3] would be one, but not [2,3,1])? Non-decreasing lists? > Cyclical, or of certain length? What are such types called? There are a few ways to encode such things. The most direct route is to use dependent types as Miguel mentioned, but Haskell has no support for those. See languages like Agda or Coq. Another approach is to use a type that specifically represents what you want and nothing else. For example, a list of a set length is just a tuple. It is easy to make a type that represents cyclic lists. Finally, the most general method is to use an abstract data type to maintain the invariant. It is trivial to handle ordered/non-decreasing lists in this way. One note about the dependent types route is that the ability to assert arbitrary properties comes with it the responsibility to prove them later on. So you can make a function which only accepts ordered lists, but then the users need to pass in a proof that their lists are ordered when they use such functions and these proofs can be a significant burden. From carlos.camarao at gmail.com Sun Jan 17 16:32:04 2010 From: carlos.camarao at gmail.com (Carlos Camarao) Date: Sun Jan 17 16:04:25 2010 Subject: [Haskell-cafe] Type Inference for Overloading without Restrictions In-Reply-To: References: Message-ID: On Wed, Jan 13, 2010 at 7:57 AM, Peter Verswyvelen wrote: > A while ago, someone provided me a link to the paper "Type Inference > for Overloading without Restrictions" > http://www.dcc.ufmg.br/~camarao/ct-flops99.ps.gz > > Although I don't understand everything in this paper, I wander what > people's opinions are about this regarding a future Haskell language > revision or extension? > System CT (as it was defined in the Flops99 paper) is a core system for constrained (parametric + ad-hoc) polymorphism, the main difference with respect to Haskell type classes being that it uses a closed world approach to overloading (as it was defined in the Flops99 paper), while Haskell type classes uses an open world. Open means that principal types of overloaded symbols are explicitly specified (in Haskell class declarations), and, informally speaking, satisfiability checking is performed only when overloading is resolved (i.e. satisfiability is delayed until it cannot be delayed any longer). Closed, on the other hand, means that principal types are determined (inferred) according to (definitions available in) the context (as occurs in the normal case, of non-overloaded symbols). For details, see e.g. [1]. A "mixed" approach, where annotation of types of overloaded symbols is not mandatory but satisfiability checking is done as in an open world approach, is possible and advantageous. Only prototype implementations exist to this date of system CT. A prototype implementation of a mixed approach is currently under way. > > Would a feature like this be preferable over typeclasses? The main disadvantage of system CT's closed world approach is the cost of satisfiability checking. (However, this does not hold in the case of a mixed approach, where satisfiability checking is restrictd as in an open world). The main advantage is that annotations (type classes) need not be mandatory and a priori determined by the programmer. Would it be practical to implement? Yes, I think so, in particular the mixed approach where satisfiability checking is delayed (it is done only if there exist "unreachable variables" in the constraint set), as explained in [2]. We have recently sent a message with a link to our paper, that describes this approach, as a proposal to solve Haskell's MPTC dilemma (without the need of functional dependencies or another mechanism). > Are people working on this? > Yes. We are. > Thanks, > Peter Verswyvelen > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > Cheers, Carlos [1] Open and Closed World Approaches to Overloading: a Definition and Support for Coexistence, Carlos Camar?o, Cristiano Vasconcellos, Luc?lia Figueiredo, Jo?o Nicola, Journal of Universal Computer Science 13(6), 854-873, 2007. http://www.dcc.ufmg.br/~camarao/CT/open-closed.pdf [2] A Solution to Haskell's Multi-paramemeter Type Class Dilemma, Carlos Camar?o, Rodrigo Ribeiro, Luc?lia Figueiredo, Cristiano Vasconcellos, SBLP'2009 (13th Brazilian Symposium on Programming Languages), 2009. http://www.dcc.ufmg.br/~camarao/CT/solution-to-mptc-dilemma.pdf -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100117/ee7f4f47/attachment.html From twanvl at gmail.com Sun Jan 17 16:47:48 2010 From: twanvl at gmail.com (Twan van Laarhoven) Date: Sun Jan 17 16:20:09 2010 Subject: [Haskell-cafe] Re: Arrow instance of Transducer (Was: [Haskell] ANN: Streaming Component Combinators 0.4) In-Reply-To: <.1263747590@magma.ca> References: <.1263747590@magma.ca> Message-ID: <4B538584.9020005@gmail.com> Mario Bla?evi? wrote: > After some investigation, I've concluded that Transducer cannot be made an > instance of Arrow in any way that's both practical and general. > > the arr and (>>>) methods are trivial: > > but there is no satisfactory definition for the method first. The Arrow class is too big, it includes too many things and it should be split up. This is yet another example. You can get some of the benefits of standard classes by making Transducer an instance of Control.Category.Category, for which you only need to implement (.) and id. Twan From tomahawkins at gmail.com Sun Jan 17 16:56:53 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Sun Jan 17 16:29:12 2010 Subject: [Haskell-cafe] ANN: atom-0.1.3 In-Reply-To: <27198213.post@talk.nabble.com> References: <594c1e830912030352sfe4714ag10a582e3f1bd416d@mail.gmail.com> <27198213.post@talk.nabble.com> Message-ID: <594c1e831001171356w21df7c3bl51204d3be6b7fd0@mail.gmail.com> On Sun, Jan 17, 2010 at 1:16 PM, miaubiz wrote: > > I am trying to generate a square wave. ?Here's the code: > > ? ?square <- bool "square" False > > ? ?period 2 $ atom "square high" $ phase 0 $ do > ? ? ? ?square <== true > ? ? ? ?assert "square is low" $ not_ $ value square > > ? ?period 2 $ atom "square low" $ phase 1 $ do > ? ? ? ?square <== false > ? ? ? ?assert "square is high" $ value square > > > The tests fail every cycle because after each rule one of them is wrong. If you are using the latest version of Atom, asserts are checked between the execution of every rule. The way you've coded it, it may appear as if the assertions are checked along with the associated rules, but this is not the case. And not only are the assertions not checked with the rules, they don't follow the period or phase constraints either. So what you have is essentially 2 assertions that are being checked at every time instance and between every atom state update. > > What would be the right way to formulate this code? Use cond on the rules? > > ? ?period 2 $ atom "square high" $ phase 0 $ do > ? ? ? ?cond $ not_ $ value square > ? ? ? ?square <== true > ? ? ? ?cover "lowSquare" true > ? ? ? ?assert "square is low" $ not_ $ value square > > ? ?period 2 $ atom "square low" $ phase 1 $ do > ? ? ? ?cond $ value square > ? ? ? ?square <== false > ? ? ? ?cover "highSquare" true > ? ? ? ?assert "square is high" $ value square > > Yes, guard conditions would help. Guards are hierarchical; they apply to all the sub Atom rules and assertions. As such ... cond $ not_ $ value square assert "squareIsLow" $ not_ $ value square .. is a redundant because the guard condition is the same as the assertion. The guard will only allow the assertion to be checked if 'square' is false, and if it does, the assertion is guaranteed to pass. An easier way to write a square wave is this... square <- bool "square" False period 2 $ atom "toggle" $ do square <== not_ (value square) > as an aside, in Unit.hs: > ? ? ? ? covered = [ words line !! 1 | line <- lines log, isPrefixOf > "covered:" line ] > > because covered is the second word of the line from the log, the name of > cover must be a single word. assertions and atoms can contain spaces as far > as I can tell. No, they really shouldn't. I've been meaning to add some checks to enforce some naming rules, but haven't gotten around to it. I hope this helps. -Tom > > br, miau > -- > View this message in context: http://old.nabble.com/ANN%3A-atom-0.1.3-tp26624813p27198213.html > 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 > From mblazevic at stilo.com Sun Jan 17 17:01:01 2010 From: mblazevic at stilo.com (=?utf-8?B?TWFyaW8gQmxhxb5ldmnEhw==?=) Date: Sun Jan 17 16:33:22 2010 Subject: [Haskell-cafe] Re: Arrow instance of Transducer (Was: [Haskell] ANN: Streaming Component Combinators 0.4) Message-ID: <.1263765661@magma.ca> On Sun 17/01/10 4:47 PM , Twan van Laarhoven twanvl@gmail.com sent: > The Arrow class is too big, it includes too many things and it should be > split up. This is yet another example. You can get some of the benefits of > standard classes by making Transducer an instance of Control.Category.Category, for > which you only need to implement (.) and id. Yes, perhaps I'll do that. Is there any relatively accepted package that defines PointedCategory? From waldmann at imn.htwk-leipzig.de Sun Jan 17 18:35:00 2010 From: waldmann at imn.htwk-leipzig.de (Johannes Waldmann) Date: Sun Jan 17 18:07:29 2010 Subject: [Haskell-cafe] parallel matrix multiply (dph, par/pseq) Message-ID: <4B539EA4.2020804@imn.htwk-leipzig.de> Hello. How can I multiply matrices (of Doubles) with dph (-0.4.0)? (ghc-6.12.1) - I was trying type Vector = [:Double:] type Matrix = [:Vector:] times :: Matrix -> Matrix -> Matrix times a b = mapP ( \ row -> mapP ( \ col -> sumP ( zipWithP (*) row col ) ) ( transposeP b ) ) a but there is no such thing as transposeP. When I try any kind of index manipulations, the compiler invariably tells me that it does not want to build [: :] - lists of indices (e.g., there is no enumFromToP) (I guess because I'm using Data.Array.Parallel.Prelude.Double) Puzzled - J.W. PS: what's the recommended way to multiply matrices (better modelled as Array (Int,Int) Double or [[Double]] ?) with the par/pseq approach (if this is recommended at all)? As I said earlier, I just want to have some nice and easy benchmarks for demonstration in a lecture (to be run on 2, 4, or 8 cores). Of course if they work, I'd use them in real life as well... -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 260 bytes Desc: OpenPGP digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100117/31e81b8c/signature.bin From z_axis at 163.com Sun Jan 17 23:13:50 2010 From: z_axis at 163.com (zaxis) Date: Sun Jan 17 22:46:10 2010 Subject: [Haskell-cafe] xmonad cannot find its library after upgrading GHC Message-ID: <27206013.post@talk.nabble.com> After `pacman -Syu`, the ghc is upgraded to 6.12.1 %ghc --version The Glorious Glasgow Haskell Compilation System, version 6.12.1 However, the xmonad still stay as it is: %pacman -Q|grep -i xmonad xmonad 0.9-2.1 xmonad-contrib 0.9-1.2 %pacman -Ql xmonad|more ...... xmonad /usr/lib/ghc-6.10.4/ xmonad /usr/lib/ghc-6.10.4/site-local/ xmonad /usr/lib/ghc-6.10.4/site-local/xmonad-0.9/ xmonad /usr/lib/ghc-6.10.4/site-local/xmonad-0.9/HSxmonad-0.9.o xmonad /usr/lib/ghc-6.10.4/site-local/xmonad-0.9/XMonad.hi xmonad /usr/lib/ghc-6.10.4/site-local/xmonad-0.9/XMonad/ ..... So it will fail when running `xmonad --recompile` as xmonad cannot find its library in /usr/lib/ghc-6.12.1. Do i need to re-install xmonad ? Sincerely! ----- fac n = foldr (*) 1 [1..n] -- View this message in context: http://old.nabble.com/xmonad-cannot-find-its-library-after-upgrading-GHC-tp27206013p27206013.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From dons at galois.com Sun Jan 17 23:30:16 2010 From: dons at galois.com (Don Stewart) Date: Sun Jan 17 23:02:41 2010 Subject: [Haskell-cafe] xmonad cannot find its library after upgrading GHC In-Reply-To: <27206013.post@talk.nabble.com> References: <27206013.post@talk.nabble.com> Message-ID: <20100118043016.GA7193@whirlpool.galois.com> z_axis: > > After `pacman -Syu`, the ghc is upgraded to 6.12.1 > %ghc --version > The Glorious Glasgow Haskell Compilation System, version 6.12.1 > > However, the xmonad still stay as it is: > %pacman -Q|grep -i xmonad > xmonad 0.9-2.1 > xmonad-contrib 0.9-1.2 > > %pacman -Ql xmonad|more > ...... > xmonad /usr/lib/ghc-6.10.4/ > xmonad /usr/lib/ghc-6.10.4/site-local/ > xmonad /usr/lib/ghc-6.10.4/site-local/xmonad-0.9/ > xmonad /usr/lib/ghc-6.10.4/site-local/xmonad-0.9/HSxmonad-0.9.o > xmonad /usr/lib/ghc-6.10.4/site-local/xmonad-0.9/XMonad.hi > xmonad /usr/lib/ghc-6.10.4/site-local/xmonad-0.9/XMonad/ > ..... > > So it will fail when running `xmonad --recompile` as xmonad cannot find its > library in /usr/lib/ghc-6.12.1. > Do i need to re-install xmonad ? > Yes, that's right. You need to reinstall xmonad. -- Don From markl at glyphic.com Mon Jan 18 01:54:16 2010 From: markl at glyphic.com (Mark Lentczner) Date: Mon Jan 18 01:26:38 2010 Subject: [Haskell-cafe] PROPOSAL: Web application interface In-Reply-To: <29bf512f1001170801r15f1537bne4dd71c07b0682b8@mail.gmail.com> References: <29bf512f1001170801r15f1537bne4dd71c07b0682b8@mail.gmail.com> Message-ID: <67C931AB-57FC-4891-9037-AAAD8489B7B3@glyphic.com> I like this project! Thanks for resurrecting it! Some thoughts: Methods in HTTP are extensible. The type RequestMethod should probably have a "catchall" constructor | Method B.ByteString Other systems (the WAI proposal on the Wiki, Hack, etc...) have broken the path into two parts: scriptName and pathInfo. While I'm not particularly fond of those names, they do break the path into "traversed" and "non-traversed" portions of the URL. This is very useful for achieving "location independence" of one's code. While this API is trying to stay agnostic to the web framework, some degree of traversal is pretty universal, and I think it would benefit being in here. The fields serverPort, serverName, and urlScheme are typically only used by an application to "reconstruct" URLs for inclusion in the response. This is a constant source of bugs in many web sites. It is also a problem in creating modular web frameworks, since the application can't be unaware of its context (unless the server interprets and re-writes HTML and other content on the fly - which isn't realistic.) Perhaps a better solution would be to pass a "URL generating" function in the Request and hide all this. Of course, web frameworks *could* use these data to dispatch on "virtual host" like configurations. Though, perhaps that is the provenance of the server side of the this API? I don't have a concrete proposal here, just a gut that the inclusion of these breaks some amount of encapsulation we'd like to achieve for the Applications. The HTTP version information seems to have been dropped from Request. Alas, this is often needed when deciding what response headers to generate. I'm in favor of a simple data type for this: data HttpVersion = Http09 | Http10 | Http11 Using ByteString for all the non-body values I find awkward. Take headers, for example. The header names are going to come from a list of about 50 well known ones. It seems a shame that applications will be littered with expressions like: [(B.pack "Content-Type", B.pack "text/html;charset=UTF-8")] Seems to me that it would be highly beneficial to include a module, say Network.WAI.Header, that defined these things: [(Hdr.contentType, Hdr.mimeTextHtmlUtf8)] Further, since non-fixed headers will be built up out of many little String bits, I'd just as soon have the packing and unpacking be done by the server side of this API, and let the applications deal with Strings for these little snippets both in the Request and the Response. For header names, in particular, it might be beneficial (and faster) to treat them like RequestMethod and make them a data type with nullary constructors for all 47 defined headers, and one ExtensionHeader String constructor. Finally, note that HTTP/1.1 actually does well define the character encoding of these parts of the protocol. It is a bit hard to find in the spec, but the request line, status line and headers are all transmitted in ISO-8859-1, (with some restrictions), with characters outside the set encoded as per RFC 2047 (MIME Message Header extensions). Mind you, I believe that most web servers *don't* do the 2047 decoding, and only either a) pass the strings as ISO-8859-1 strings, or decode that to native Unicode strings. - Mark Mark Lentczner http://www.ozonehouse.com/mark/ IRC: mtnviewmark From qdunkan at gmail.com Mon Jan 18 03:53:31 2010 From: qdunkan at gmail.com (Evan Laforge) Date: Mon Jan 18 03:25:55 2010 Subject: [Haskell-cafe] Parse error In-Reply-To: <4B52EA17.5040201@btinternet.com> References: <4B52E0FB.5070201@btinternet.com> <4B52E525.50300@gmail.com> <4B52E789.5060204@btinternet.com> <201001171138.05884.daniel.is.fischer@web.de> <4B52EA17.5040201@btinternet.com> Message-ID: <2518b95d1001180053k5bfaece5g7bf5b56366adcb3c@mail.gmail.com> > It's an improvement. It's still not pretty, but I guess that's as good as > it's going to get... > > Maybe this is an instance of Haskell trying to tell me "if you need to write > a 20-line do-block in the middle of your function, you're doing it wrong". 20 lines is a lot, but I have smaller ones all the time. You need >4 spaces of indent to continue a let. Here's another way to understand why: f = do let x = some big expression y = another big expression x y If you wonder why "multiple let" syntax is needed, well I don't really know for sure, but consider if x and y were mutually recursive. I was annoyed at first with all the indentation but got used to it. I use 4 space indents so it works out ok. Binding with <- or in where can reduce the indentation but is not always appropriate. From mikehartl at web.de Mon Jan 18 05:34:05 2010 From: mikehartl at web.de (Michael Hartl) Date: Mon Jan 18 05:06:25 2010 Subject: [Haskell-cafe] Takusen - reading from one db inserting into another In-Reply-To: <4B536975.1050500@web.de> References: <4B536975.1050500@web.de> Message-ID: <1263810845.2411.2.camel@cangaroo> Don't know if you can have two connections, sounds difficult in regard to the DBM monad. Only the deveolopers will know. However, two obvious solutions come to my mind: 1) build a result set and process it after returning from DBM or 2) use two separate threads and send the queried data from your source db to the other thread using an STM channel. You will have to think about lazyness, performance and space usage in both cases, however. Am Sonntag, den 17.01.2010, 20:48 +0100 schrieb G?nther Schmidt: > Hi, > > I know how to use Takusen with a *single* connection, but I cannot > figure out how to read from one database while inserting to another. > > > Could someone please explain to me how I can do that? > > G?nther > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From RafaelGCPP.Linux at gmail.com Mon Jan 18 05:35:42 2010 From: RafaelGCPP.Linux at gmail.com (Rafael Gustavo da Cunha Pereira Pinto) Date: Mon Jan 18 05:08:02 2010 Subject: [Haskell-cafe] parallel matrix multiply (dph, par/pseq) In-Reply-To: <4B539EA4.2020804@imn.htwk-leipzig.de> References: <4B539EA4.2020804@imn.htwk-leipzig.de> Message-ID: <351ff25e1001180235x37ed3f68ifef5a92627e29d71@mail.gmail.com> I never used DPH, but for Matrices, I always tend to use Array (Int,Int) Double, as it accesses its elements in O(1). Arrays also can be unboxed (UArray), which are much faster, or monadic and mutable (MArray), which are more flexible. I don't know if it is possible to use Arrays with DPH... On Sun, Jan 17, 2010 at 21:35, Johannes Waldmann < waldmann@imn.htwk-leipzig.de> wrote: > Hello. > > How can I multiply matrices (of Doubles) > with dph (-0.4.0)? (ghc-6.12.1) - I was trying > > type Vector = [:Double:] > type Matrix = [:Vector:] > > times :: Matrix -> Matrix -> Matrix > times a b = > mapP > ( \ row -> mapP ( \ col -> sumP ( zipWithP (*) row col ) ) > ( transposeP b ) > ) a > > but there is no such thing as transposeP. > > When I try any kind of index manipulations, > the compiler invariably tells me > that it does not want to build [: :] - lists of indices > (e.g., there is no enumFromToP) > (I guess because I'm using Data.Array.Parallel.Prelude.Double) > > Puzzled - J.W. > > > PS: what's the recommended way to multiply matrices > (better modelled as Array (Int,Int) Double or [[Double]] ?) > with the par/pseq approach (if this is recommended at all)? > > As I said earlier, I just want to have some nice and easy benchmarks > for demonstration in a lecture (to be run on 2, 4, or 8 cores). > Of course if they work, I'd use them in real life as well... > > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- Rafael Gustavo da Cunha Pereira Pinto -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100118/5fae7e51/attachment.html From gleb.alexeev at gmail.com Mon Jan 18 05:38:58 2010 From: gleb.alexeev at gmail.com (Gleb Alexeyev) Date: Mon Jan 18 05:11:40 2010 Subject: [Haskell-cafe] Re: Visualizing function application In-Reply-To: <4B509754.3030107@van.steenbergen.nl> References: <4B509754.3030107@van.steenbergen.nl> Message-ID: Martijn van Steenbergen wrote: > Dear caf?, > > I am deeply impressed with Vacuum[1][2], Ubigraph[3] and especially > their combination[4]. I can trivially and beautifully visualize the ASTs > that my parser produces. I can visualize zippers of the ASTs and confirm > that sharing is optimal. > > Ubigraph is also able to animate graph *mutations*, as shown by the > various demos on Ubigraph's website. How cool would it be if we could > tell vacuum-ubigraph: here, show this tree, and then show how the tree > changes when we apply this function on it. We could see how [1,2,3] is > transformed into a ring when cycle is applied on it, or we could see how > a list is consumed node by node when a foldr is applied. > > I have no idea how difficult this is or how to begin, so I thought I'd > throw the idea out here. Perhaps it is appealing enough that someone > picks it up and implements it. :-) > > Martijn. > > > [1] http://hackage.haskell.org/package/vacuum > [2] http://www.youtube.com/watch?v=oujaqo9GAmA > [3] http://ubietylab.net/ubigraph/content/Demos/index.html > [4] http://hackage.haskell.org/package/vacuum-ubigraph Hello, Martijn. I'm glad you found vacuum-ubigraph useful. I have to tell you that it was hacked in a hour or so based on the code from vacuum-cairo. I'm in no way an expert in GHC runtime internals. The spec of application visualization as you propose it is unclear: in what sense the list [1,2,3] is transformed to a ring, given that only values 1,2,3 are shared, not cons-cells? Can this definition of transformation be extrapolated to a function like parseXml :: [Char] -> XmlTree? As to 'list consumed by foldr', things seem even more unclear. I'm under impression that Vacuum allows inspection of representation of static values, and here we need the history of evaluation, with information which nodes and when get collected as garbage. I doubt this is possible, but we'll have to wait until Matt Morrow or anyone else more knowledgeable than me comments. From michael at snoyman.com Mon Jan 18 06:48:37 2010 From: michael at snoyman.com (Michael Snoyman) Date: Mon Jan 18 06:20:59 2010 Subject: [Haskell-cafe] PROPOSAL: Web application interface In-Reply-To: <67C931AB-57FC-4891-9037-AAAD8489B7B3@glyphic.com> References: <29bf512f1001170801r15f1537bne4dd71c07b0682b8@mail.gmail.com> <67C931AB-57FC-4891-9037-AAAD8489B7B3@glyphic.com> Message-ID: <29bf512f1001180348i2cd2d97p17ef1510ab8974fe@mail.gmail.com> Mark, thanks for the response, it's very well thought out. Let me state two things first to explain some of my design decisions. Firstly, I'm shooting for lowest-common-denominator here. Right now, I see that as the intersection between the CGI backend and a standalone server backend; I think anything contained in both of those will be contained in all other backends. If anyone has a contrary example, I'd be happy to see it. Secondly, the WAI is *not* designed to be "user friendly." It's designed to be efficient and portable. People looking for a user-friendly way to write applications should be using some kind of frontend, either a framework, or something like hack-frontend-monadcgi. That said, let's address your specific comments. On Mon, Jan 18, 2010 at 8:54 AM, Mark Lentczner wrote: > I like this project! Thanks for resurrecting it! > > Some thoughts: > > Methods in HTTP are extensible. The type RequestMethod should probably have > a "catchall" constructor > | Method B.ByteString > > Seems logical to me. > Other systems (the WAI proposal on the Wiki, Hack, etc...) have broken the > path into two parts: scriptName and pathInfo. While I'm not particularly > fond of those names, they do break the path into "traversed" and > "non-traversed" portions of the URL. This is very useful for achieving > "location independence" of one's code. While this API is trying to stay > agnostic to the web framework, some degree of traversal is pretty universal, > and I think it would benefit being in here. > > Going to the standalone vs CGI example: in a CGI script, scriptName is a well defined variable. However, it has absolutely no meaning to a standalone handler. I think we're just feeding rubbish into the system. I'm also not certain how one could *use* scriptName in any meaningful manner, outside of trying to reconstruct a URL (more on this topic below). > The fields serverPort, serverName, and urlScheme are typically only used by > an application to "reconstruct" URLs for inclusion in the response. This is > a constant source of bugs in many web sites. It is also a problem in > creating modular web frameworks, since the application can't be unaware of > its context (unless the server interprets and re-writes HTML and other > content on the fly - which isn't realistic.) Perhaps a better solution would > be to pass a "URL generating" function in the Request and hide all this. Of > course, web frameworks *could* use these data to dispatch on "virtual host" > like configurations. Though, perhaps that is the provenance of the server > side of the this API? I don't have a concrete proposal here, just a gut that > the inclusion of these breaks some amount of encapsulation we'd like to > achieve for the Applications. > > I think it's impossible to ever reconstruct a URL for a CGI application. I've tried it; once you start dealing with mod_rewrite, anything could happen. Given that I think we should encourage users to make pretty URLs via mod_rewrite, I oppose inserting such a function. When I need this kind of information (many of my web apps do), I've put it in a configuration file. However, I don't think it's a good idea to hide information that is universal to all webapps. urlScheme in particular seems very important to me; for example, maybe when serving an app over HTTPS you want to use a secure static-file server as well. Frankly, I don't have a use case for serverName and serverPort that don't involve reconstructing URLs, but my gut feeling is better to leave it in the protocol in case it does have a use case. > The HTTP version information seems to have been dropped from Request. Alas, > this is often needed when deciding what response headers to generate. I'm in > favor of a simple data type for this: > data HttpVersion = Http09 | Http10 | Http11 > > I had not thought of that at all, and I like it. However, do we want to hard-code in all possible HTTP versions? In theory, there could be more standards in the future. Plus, isn't Google currently working on a more efficient approach to HTTP that would affect this? > Using ByteString for all the non-body values I find awkward. Take headers, > for example. The header names are going to come from a list of about 50 well > known ones. It seems a shame that applications will be littered with > expressions like: > > [(B.pack "Content-Type", B.pack "text/html;charset=UTF-8")] > > Seems to me that it would be highly beneficial to include a module, say > Network.WAI.Header, that defined these things: > > [(Hdr.contentType, Hdr.mimeTextHtmlUtf8)] > > This approach would make WAI much more top-heavy and prone to becoming out-of-date. I don't oppose having this module in a separate package, but I want to keep WAI itself as lite as possible. > Further, since non-fixed headers will be built up out of many little String > bits, I'd just as soon have the packing and unpacking be done by the server > side of this API, and let the applications deal with Strings for these > little snippets both in the Request and the Response. > > As I stated at the beginning of this response, there should be a framework or frontend sitting between WAI and the application. And given that the actual data on the wire will be represented as a stream of bytes, I'd rather stick with that. For header names, in particular, it might be beneficial (and faster) to > treat them like RequestMethod and make them a data type with nullary > constructors for all 47 defined headers, and one ExtensionHeader String > constructor. > > Same comment of top-heaviness. > Finally, note that HTTP/1.1 actually does well define the character > encoding of these parts of the protocol. It is a bit hard to find in the > spec, but the request line, status line and headers are all transmitted in > ISO-8859-1, (with some restrictions), with characters outside the set > encoded as per RFC 2047 (MIME Message Header extensions). Mind you, I > believe that most web servers *don't* do the 2047 decoding, and only either > a) pass the strings as ISO-8859-1 strings, or decode that to native Unicode > strings. > > Thanks for that information, I was unaware. However, I think it still makes sense to keep WAI as low-level as possible, which would mean a sequence of bytes. Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100118/b3322d74/attachment.html From alistair at abayley.org Mon Jan 18 07:00:14 2010 From: alistair at abayley.org (Alistair Bayley) Date: Mon Jan 18 06:32:34 2010 Subject: [Haskell-cafe] Takusen - reading from one db inserting into another In-Reply-To: <4B536975.1050500@web.de> References: <4B536975.1050500@web.de> Message-ID: <79d7c4981001180400of87251dq207a671e70e30e25@mail.gmail.com> Hello G?nther, > I know how to use Takusen with a *single* connection, but I cannot figure > out how to read from one database while inserting to another. At present it's not possible. The lats time you asked about it, Oleg and I tried a design where the DBM monad becomes a DBMT monad transformer. This permits multiple connections, but the resulting user-land code didn't work as well as I wanted. If you like I can try to tidy it up and send you the darcs patch. Alistair From gue.schmidt at web.de Mon Jan 18 07:28:57 2010 From: gue.schmidt at web.de (=?UTF-8?B?R8O8bnRoZXIgU2NobWlkdA==?=) Date: Mon Jan 18 07:01:18 2010 Subject: [Haskell-cafe] Takusen - reading from one db inserting into another In-Reply-To: <79d7c4981001180400of87251dq207a671e70e30e25@mail.gmail.com> References: <4B536975.1050500@web.de> <79d7c4981001180400of87251dq207a671e70e30e25@mail.gmail.com> Message-ID: <4B545409.4020508@web.de> Hello Alistair, sorry for asking twice, I had forgotten that. I took some time to try to figure out how to do it and always concluded from my understanding of Takusen that it shouldn't be possible. At least it seems I got that right, which is good by itself :) . Thank you for your troubles but do not worry about the patch, I have switched back to using HDBC meanwhile. HDBC-ODBC has a slight problem with Access, I couldn't insert Doubles, well I could but the decimal separator got swallowed, and I worked around it by using pr-efilled SQL-statement strings instead of bound/prepared ones. G?nther Am 18.01.10 13:00, schrieb Alistair Bayley: > Hello G?nther, > > >> I know how to use Takusen with a *single* connection, but I cannot figure >> out how to read from one database while inserting to another. >> > At present it's not possible. The lats time you asked about it, Oleg > and I tried a design where the DBM monad becomes a DBMT monad > transformer. This permits multiple connections, but the resulting > user-land code didn't work as well as I wanted. If you like I can try > to tidy it up and send you the darcs patch. > > Alistair > From miaubiz at gmail.com Mon Jan 18 09:19:12 2010 From: miaubiz at gmail.com (miaubiz) Date: Mon Jan 18 08:51:31 2010 Subject: [Haskell-cafe] ANN: atom-0.1.3 In-Reply-To: <594c1e831001171356w21df7c3bl51204d3be6b7fd0@mail.gmail.com> References: <594c1e830912030352sfe4714ag10a582e3f1bd416d@mail.gmail.com> <27198213.post@talk.nabble.com> <594c1e831001171356w21df7c3bl51204d3be6b7fd0@mail.gmail.com> Message-ID: <27211086.post@talk.nabble.com> Tom Hawkins-2 wrote: > > If you are using the latest version of Atom, asserts are checked > between the execution of every rule. The way you've coded it, it may > appear as if the assertions are checked along with the associated > rules, but this is not the case. And not only are the assertions not > checked with the rules, they don't follow the period or phase > constraints either. So what you have is essentially 2 assertions that > are being checked at every time instance and between every atom state > update. > how should I feed test data into my system? I am having quite a bit of trouble with testing an atom with hysteresis because I always end up having an assertion fire before and after my test data is updated. I have essentially the following code: inputs = [1, 2, 3, 4, 5] expected = [6, 7, 8, 9, 10] output <- word16' "output" input <- word16' "input" input <== inputs !. clock doStuff assert "fiveIsAdded" $ (value output) ==. (expected !. clock) doStuff atom "addFive" $ period 1 $ do output <== (value input 5) + 5 ... the only way I am able to write assertions is to duplicate the logic of hysteresis into the assertions, which is not a reasonable way to go for me. Tom Hawkins-2 wrote: > >> because covered is the second word of the line from the log, the name of >> cover must be a single word. assertions and atoms can contain spaces as >> far >> as I can tell. > > No, they really shouldn't. I've been meaning to add some checks to > enforce some naming rules, but haven't gotten around to it. > good to know. thanks for the heads up. br, miau -- View this message in context: http://old.nabble.com/ANN%3A-atom-0.1.3-tp26624813p27211086.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From bertram.felgenhauer at googlemail.com Mon Jan 18 09:34:12 2010 From: bertram.felgenhauer at googlemail.com (Bertram Felgenhauer) Date: Mon Jan 18 09:06:36 2010 Subject: [Haskell-cafe] parallel matrix multiply (dph, par/pseq) In-Reply-To: <4B539EA4.2020804@imn.htwk-leipzig.de> References: <4B539EA4.2020804@imn.htwk-leipzig.de> Message-ID: <20100118143412.GD2170@24f89f8c-e6a1-4e75-85ee-bb8a3743bb9f> Johannes Waldmann wrote: > Hello. > > How can I multiply matrices (of Doubles) > with dph (-0.4.0)? (ghc-6.12.1) - I was trying > > type Vector = [:Double:] > type Matrix = [:Vector:] > > times :: Matrix -> Matrix -> Matrix > times a b = > mapP > ( \ row -> mapP ( \ col -> sumP ( zipWithP (*) row col ) ) > ( transposeP b ) > ) a > > but there is no such thing as transposeP. It's possible to implement transposeP as follows, {-# LANGUAGE PArr #-} ... import qualified Data.Array.Parallel.Prelude.Int as I transposeP :: Matrix -> Matrix transposeP a = let h = lengthP a w = lengthP (a !: 0) rh = I.enumFromToP 0 (h I.- 1) -- or [: 0 .. h I.- 1 :] rw = I.enumFromToP 0 (w I.- 1) -- or [: 0 .. w I.- 1 :] in if h == 0 then [: :] else mapP (\y -> mapP (\x -> a !: x !: y) rh) rw Maybe there is a better way? Bertram From yairchu at gmail.com Mon Jan 18 09:48:29 2010 From: yairchu at gmail.com (yairchu@gmail.com) Date: Mon Jan 18 09:20:47 2010 Subject: [Haskell-cafe] A numpy equivalent for Haskell Message-ID: Hi Cafe, I've created a numpy equivalent for Haskell. (Numpy is a python library for multi-dimensional arrays and operations on them) Code at http://github.com/yairchu/numkell (not yet on hackage because it needs better names) A numkell array is a pair of a function from integer inputs and a range for its inputs (size). This allows for easy memoizing into in-memory arrays, and additionally, numkell arrays also support useful operations like numpy's newaxis and folding axes away. As the "Array" name was already taken, numkell's array is currently called "Funk" (name suggestions very appreciated). An example: Given an bunch of vectors as a 2d array, compute the distance between each pair of vectors {-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, TypeOperators #-} import Data.HList import Data.NumKell import Data.Typeable newtype PersonIdx = PersonIdx Int deriving (Enum, Eq, Integral, Num, Ord, Real, Show, Typeable) newtype FeatureIdx = FeatureIdx Int deriving (Enum, Eq, Integral, Num, Ord, Real, Show, Typeable) let personProps = fFromList [[5,3,2],[4,8,1],[2,6,9],[5,3,0]] :: Funk (HJust PersonIdx :*: HJust FeatureIdx :*: HNil) Double > personProps FeatureIdx 0 1 2 PersonIdx + - - - 0 | 5.0 3.0 2.0 1 | 4.0 8.0 1.0 2 | 2.0 6.0 9.0 3 | 5.0 3.0 0.0 > sumAxes (fmap (** 2) (liftF2 (-) (personProps !/ (SNewAxis .*. HNil)) (personProps !/ (SAll .*. SNewAxis .*. HNil)))) (TFalse .*. TFalse .*. TTrue .*. HNil) PersonIdx 0 1 2 3 PersonIdx + - - - - 0 | 0.0 27.0 67.0 4.0 1 | 27.0 0.0 72.0 27.0 2 | 67.0 72.0 0.0 99.0 3 | 4.0 27.0 99.0 0.0 In Python the last line looks shorter: >>> ((personProps[newaxis] - personProps[:,newAxis]) ** 2).sum(2) Mostly due to Python's slicing syntax sugar. Still, numkell has one large benefit over numpy (apart from being for Haskell): With numpy this example creates a temporary 3d array in memory. In numkell the array is not allocated in memory unless "fMemo" is called. If anyone has comments, suggestions, naming suggestions, complaints, etc, I would very much like to hear. cheers, Yair From ivan.miljenovic at gmail.com Mon Jan 18 09:56:21 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Mon Jan 18 09:28:44 2010 Subject: [Haskell-cafe] A numpy equivalent for Haskell In-Reply-To: (yairchu@gmail.com's message of "Mon, 18 Jan 2010 06:48:29 -0800 (PST)") References: Message-ID: <87k4vfxy0a.fsf@gmail.com> Did you know about hmatrix (available on Hackage) before you wrote this? "yairchu@gmail.com" writes: > Hi Cafe, > > I've created a numpy equivalent for Haskell. (Numpy is a python > library for multi-dimensional arrays and operations on them) > > Code at http://github.com/yairchu/numkell > (not yet on hackage because it needs better names) > > A numkell array is a pair of a function from integer inputs and a > range for its inputs (size). > This allows for easy memoizing into in-memory arrays, and > additionally, numkell arrays also support useful operations like > numpy's newaxis and folding axes away. > As the "Array" name was already taken, numkell's array is currently > called "Funk" (name suggestions very appreciated). > > An example: > Given an bunch of vectors as a 2d array, compute the distance between > each pair of vectors > > {-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, > TypeOperators #-} > > import Data.HList > import Data.NumKell > import Data.Typeable > > newtype PersonIdx = PersonIdx Int > deriving (Enum, Eq, Integral, Num, Ord, Real, Show, Typeable) > > newtype FeatureIdx = FeatureIdx Int > deriving (Enum, Eq, Integral, Num, Ord, Real, Show, Typeable) > > let personProps = fFromList [[5,3,2],[4,8,1],[2,6,9],[5,3,0]] :: Funk > (HJust PersonIdx :*: HJust FeatureIdx :*: HNil) Double > >> personProps > FeatureIdx 0 1 2 > PersonIdx + - - - > 0 | 5.0 3.0 2.0 > 1 | 4.0 8.0 1.0 > 2 | 2.0 6.0 9.0 > 3 | 5.0 3.0 0.0 > >> sumAxes (fmap (** 2) (liftF2 (-) (personProps !/ (SNewAxis .*. HNil)) (personProps !/ (SAll .*. SNewAxis .*. HNil)))) (TFalse .*. TFalse .*. TTrue .*. HNil) > > PersonIdx 0 1 2 3 > PersonIdx + - - - - > 0 | 0.0 27.0 67.0 4.0 > 1 | 27.0 0.0 72.0 27.0 > 2 | 67.0 72.0 0.0 99.0 > 3 | 4.0 27.0 99.0 0.0 > > In Python the last line looks shorter: > >>>> ((personProps[newaxis] - personProps[:,newAxis]) ** 2).sum(2) > > Mostly due to Python's slicing syntax sugar. > Still, numkell has one large benefit over numpy (apart from being for > Haskell): With numpy this example creates a temporary 3d array in > memory. In numkell the array is not allocated in memory unless "fMemo" > is called. > > If anyone has comments, suggestions, naming suggestions, complaints, > etc, I would very much like to hear. > > cheers, > Yair > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From yairchu at gmail.com Mon Jan 18 10:29:33 2010 From: yairchu at gmail.com (Yair Chuchem) Date: Mon Jan 18 10:02:11 2010 Subject: [Haskell-cafe] A numpy equivalent for Haskell In-Reply-To: <87k4vfxy0a.fsf@gmail.com> References: <87k4vfxy0a.fsf@gmail.com> Message-ID: <2ae470101001180729sb18550bv1d18d7f47d8b9ca2@mail.gmail.com> On Mon, Jan 18, 2010 at 4:56 PM, Ivan Lazar Miljenovic wrote: > Did you know about hmatrix (available on Hackage) before you wrote this? yes. hmatrix is equivalent to other parts of numpy. iirc hmatrix is a wrapper for algorithms from GSL+BLAS+LAPACK. numkell is only equivalent to numpy's core array type & functionality, without numpy's included linalg algorithms (which in Python are especially needed since coding them in Python will result in very slow code) hTensor seems to be more similar to numkell, as it also provides a multi-dimensional array type. however, if I understand correctly, hTensor is quite different. * numkell array's axes are part of their types. in hTensor those are only known in run-time. so numkell is more type-safe imho. * numkell's array zips are lazy/not-memoized by default. I may be wrong on this, but it seems that hTensor always creates in-memory arrays. > "yairchu@gmail.com" writes: > >> Hi Cafe, >> >> I've created a numpy equivalent for Haskell. (Numpy is a python >> library for multi-dimensional arrays and operations on them) >> >> Code at http://github.com/yairchu/numkell >> (not yet on hackage because it needs better names) >> >> A numkell array is a pair of a function from integer inputs and a >> range for its inputs (size). >> This allows for easy memoizing into in-memory arrays, and >> additionally, numkell arrays also support useful operations like >> numpy's newaxis and folding axes away. >> As the "Array" name was already taken, numkell's array is currently >> called "Funk" (name suggestions very appreciated). >> >> An example: >> Given an bunch of vectors as a 2d array, compute the distance between >> each pair of vectors >> >> {-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, >> TypeOperators #-} >> >> import Data.HList >> import Data.NumKell >> import Data.Typeable >> >> newtype PersonIdx = PersonIdx Int >> ? deriving (Enum, Eq, Integral, Num, Ord, Real, Show, Typeable) >> >> newtype FeatureIdx = FeatureIdx Int >> ? deriving (Enum, Eq, Integral, Num, Ord, Real, Show, Typeable) >> >> let personProps = fFromList [[5,3,2],[4,8,1],[2,6,9],[5,3,0]] :: Funk >> (HJust PersonIdx :*: HJust FeatureIdx :*: HNil) Double >> >>> personProps >> ? ? ? ? ? FeatureIdx ? 0 ? 1 ? 2 >> PersonIdx ? ? ? ? ?+ ? - ? - ? - >> ? ? ? ? 0 ? ? ? ? ?| 5.0 3.0 2.0 >> ? ? ? ? 1 ? ? ? ? ?| 4.0 8.0 1.0 >> ? ? ? ? 2 ? ? ? ? ?| 2.0 6.0 9.0 >> ? ? ? ? 3 ? ? ? ? ?| 5.0 3.0 0.0 >> >>> sumAxes (fmap (** 2) (liftF2 (-) (personProps !/ (SNewAxis .*. HNil)) (personProps !/ (SAll .*. SNewAxis .*. HNil)))) (TFalse .*. TFalse .*. TTrue .*. HNil) >> >> ? ? ? ? ? PersonIdx ? ?0 ? ?1 ? ?2 ? ?3 >> PersonIdx ? ? ? ? + ? ?- ? ?- ? ?- ? ?- >> ? ? ? ? 0 ? ? ? ? | ?0.0 27.0 67.0 ?4.0 >> ? ? ? ? 1 ? ? ? ? | 27.0 ?0.0 72.0 27.0 >> ? ? ? ? 2 ? ? ? ? | 67.0 72.0 ?0.0 99.0 >> ? ? ? ? 3 ? ? ? ? | ?4.0 27.0 99.0 ?0.0 >> >> In Python the last line looks shorter: >> >>>>> ((personProps[newaxis] - personProps[:,newAxis]) ** 2).sum(2) >> >> Mostly due to Python's slicing syntax sugar. >> Still, numkell has one large benefit over numpy (apart from being for >> Haskell): With numpy this example creates a temporary 3d array in >> memory. In numkell the array is not allocated in memory unless "fMemo" >> is called. >> >> If anyone has comments, suggestions, naming suggestions, complaints, >> etc, I would very much like to hear. >> >> cheers, >> Yair >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- > Ivan Lazar Miljenovic > Ivan.Miljenovic@gmail.com > IvanMiljenovic.wordpress.com > From tomahawkins at gmail.com Mon Jan 18 10:31:47 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Mon Jan 18 10:04:05 2010 Subject: [Haskell-cafe] ANN: atom-0.1.3 In-Reply-To: <27211086.post@talk.nabble.com> References: <594c1e830912030352sfe4714ag10a582e3f1bd416d@mail.gmail.com> <27198213.post@talk.nabble.com> <594c1e831001171356w21df7c3bl51204d3be6b7fd0@mail.gmail.com> <27211086.post@talk.nabble.com> Message-ID: <594c1e831001180731r67fac0f2keae7ebbc06d2b0f0@mail.gmail.com> On Mon, Jan 18, 2010 at 3:19 PM, miaubiz wrote: > > how should I feed test data into my system? > > I am having quite a bit of trouble with testing an atom with hysteresis > because I always end up having an assertion fire before and after my test > data is updated. Would you explain what you are trying to do a bet more clearly? > > I have essentially the following code: > > inputs = [1, 2, 3, 4, 5] > expected = [6, 7, 8, 9, 10] I'm assuming you mean: inputs <- array [1,2,3,4,5] > > output <- word16' "output" > input <- word16' "input" > > input <== inputs !. clock There are a few potential problems with this statement. First, 'input' in an external variable -- which is fine, just be sure nothing is being assigned to it in the external c code. Note, if 'input' is not referenced by external code, then 'word16 "input" 0' would be a better variable declaration. The second problem is a bit more serious. By using the 'clock' as an array index, it will eventually go outside the bounds of the array. Beware: Atom provides no array checks, such as index-out-of-bounds, or assigning the same array location multiple times within the same atomic action. > doStuff > assert "fiveIsAdded" $ (value output) ==. (expected !. clock) Keep in mind than multiple rules will fire in one 'clock' cycle, and assertions are checked between the execution of each rule. In this case, the assertion will be checked before the top level rule that contains the assignment 'input <== inputs !. clock', and before the "addFive" rule. In both cases 'clock' will have the same value, which will probably lead to an assertion violation. > > doStuff > ?atom "addFive" $ period 1 $ do > ? ?output <== (value input 5) + 5 This last statement should yield a type violation. "(value input 5)". If your intention is to copy an array, and add 5 to each element, here is some code they may be what you're looking for: inputs <- array "inputs" [0, 1, 2, 3, 4] outputs <- array "outputs" [0, 0, 0, 0, 0] index <- word8 "index" 0 atom "copyElement" $ do cond $ (value index) <. 5 -- Only copy elements if the index is within the bounds of the array. outputs ! (value index) <== inputs !. (value index) + 5 incr index Another rule could then reset the index when new data is available to be copied. This will then wakeup the copyElement rule to start the copy process again. atom "restartCopy" $ do cond newDataReady index <== 0 From will_n48 at yahoo.com Mon Jan 18 11:07:46 2010 From: will_n48 at yahoo.com (Will Ness) Date: Mon Jan 18 10:40:30 2010 Subject: [Haskell-cafe] Re: Why no merge and listDiff? References: <61f84eff1001171254pddefd6eo57943727b01d7cb2@mail.gmail.com> Message-ID: Derek Elkins gmail.com> writes: > > On Sun, Jan 17, 2010 at 2:22 PM, Will Ness yahoo.com> wrote: > > Hello cafe, > > > > I wonder, if we have List.insert and List.union, why no List.merge (:: Ord a => > > [a] -> [a] -> [a]) and no List.minus ? These seem to be pretty general > > operations. > > Presumably by List.minus you mean the (\\) function in Data.List. You > probably also want to look at the package data-ordlist on hackage > (http://hackage.haskell.org/packages/archive/data-ordlist/0.0.1/doc/html/Data- OrdList.html) > which represents sets and bags as ordered lists and has all of the > operations you mention. thanks for the pointers! > > Brief look into haskell-prime-report/list.html reveals nothing. > > > > Could we please have them? > > The trend is to remove things from "standard" libraries and to push > them more to 3rd party libraries hosted on hackage. understood. > > On the wider perspective, is their a way to declare an /ordered/ list on the > > type level (e.g. [1,2,3] would be one, but not [2,3,1])? Non-decreasing lists? > > Cyclical, or of certain length? What are such types called? > > There are a few ways to encode such things. The most direct route is > to use dependent types as Miguel mentioned, but Haskell has no support > for those. See languages like Agda or Coq. Another approach is to > use a type that specifically represents what you want and nothing > else. For example, a list of a set length is just a tuple. It is > easy to make a type that represents cyclic lists. Finally, the most > general method is to use an abstract data type to maintain the > invariant. It is trivial to handle ordered/non-decreasing lists in > this way. One note about the dependent types route is that the > ability to assert arbitrary properties comes with it the > responsibility to prove them later on. So you can make a function > which only accepts ordered lists, but then the users need to pass in a > proof that their lists are ordered when they use such functions and > these proofs can be a significant burden. Presumably a system would be able to prove - to know - by itself that [1..n] is an ordered list, to start with. The idea is to have a way of maintaining - and refining - our knowledge about objects we work on/with. I've also found out about refinement types, but the wikipedia page is _very_ sketchy. Presumably each function definition would automatically produce a part of proof for the values it produces, given the compliance of its inputs to their preconditions. A program built as a chain of such fuctions would automatically have its proof calculated for it. The goal, to illustrate it by way of example, is to be able to compile/simplify the expression ( x = sum $ take n $ cycle $ [1..m] ) into a straightforward math formula with some quotRem call in it. I think this would naturally extend to the constraint programming. All I have is some vague notions for now. :) From miaubiz at gmail.com Mon Jan 18 11:12:33 2010 From: miaubiz at gmail.com (miaubiz) Date: Mon Jan 18 10:44:51 2010 Subject: [Haskell-cafe] ANN: atom-0.1.3 In-Reply-To: <594c1e831001180731r67fac0f2keae7ebbc06d2b0f0@mail.gmail.com> References: <594c1e830912030352sfe4714ag10a582e3f1bd416d@mail.gmail.com> <27198213.post@talk.nabble.com> <594c1e831001171356w21df7c3bl51204d3be6b7fd0@mail.gmail.com> <27211086.post@talk.nabble.com> <594c1e831001180731r67fac0f2keae7ebbc06d2b0f0@mail.gmail.com> Message-ID: <27212766.post@talk.nabble.com> Tom Hawkins-2 wrote: > > Would you explain what you are trying to do a bet more clearly? > Certainly. I am writing an autonomous rover. To choose the direction to drive towards, the car compares the direction it wants to go with the direction it is actually facing. To avoid continuously zigzagging I have hysteresis set around the target direction. 1. I have a set of test inputs 2. I want to run my atoms 3. I want to verify that the state of my atom matches a specific state after each iteration t2 = defaultTest { testbench = steeringVsBearing ,declCode = header fakeHeaders ,cycles = (length testData) } steeringVsBearing :: Atom () -- this is only a test steeringVsBearing = do steering <- word8' "steering" targetHeadings <- array "targetHeadings" ([target | (target, _, _) <- testData]) actualHeadings <- array "actualHeadings" ([actual | (_, actual, _) <- testData]) expectedSteerings <- array "expectedSteerings" ([steerings |(_, _, steerings) <- testData]) targetHeading <== targets !. clock compass <== actuals !. clock navigate --this is my production atom assert "steeringWorks" $ (value steering) ==. (expectedSteerings !. clock) navigate = do steering <- word8' "steering" period 1 $ atom "figureOutWhichWayToGo" $ do --calculate steering based on target heading and actual heading --blah blah steering' <- do return $ mux l1 (mux r1 75 90) 105 steering <== steering' Tom Hawkins-2 wrote: > >> output <- word16' "output" >> input <- word16' "input" >> >> input <== inputs !. clock > > There are a few potential problems with this statement. First, > 'input' in an external variable -- which is fine, just be sure nothing > is being assigned to it in the external c code. Note, if 'input' is > not referenced by external code, then 'word16 "input" 0' would be a > better variable declaration. > I used an external variable because I wanted to reference it both in steeringVsBearing which is a test function, and the actual function navigate. Tom Hawkins-2 wrote: > > The second problem is a bit more serious. By using the 'clock' as an > array index, it will eventually go outside the bounds of the array. > Beware: Atom provides no array checks, such as index-out-of-bounds, or > assigning the same array location multiple times within the same > atomic action. > ok. I am using clock as an index in the test function only. Tom Hawkins-2 wrote: > >> doStuff >> assert "fiveIsAdded" $ (value output) ==. (expected !. clock) > > Keep in mind than multiple rules will fire in one 'clock' cycle, and > assertions are checked between the execution of each rule. In this > case, the assertion will be checked before the top level rule that > contains the assignment 'input <== inputs !. clock', and before the > "addFive" rule. In both cases 'clock' will have the same value, which > will probably lead to an assertion violation. > I am unable to come up with any assertions that would be valid all the time, which would allow me to feed test data into my atoms and then verifying them against some known inputs. I have some other asserts that I find helpful, such as (minus the spaces): assert "target is closer than 1800 to actual" (target' - actual' <=. 1800) assert "target is closer than 1800 to actual'" (actual' - target' <=. 1800) but checking that the steering is valid is more difficult because it depends on the previous state of steering due to hysteresis. I don't want to replicate the logic of hysteresis in the assertion: assert "steeringWorks" $ mux (previousSteering `lt_` 90) mux (currentSteering `gt_` 90) etc etc etc. Tom Hawkins-2 wrote: > >> >> doStuff >> ?atom "addFive" $ period 1 $ do >> ? ?output <== (value input 5) + 5 > > This last statement should yield a type violation. "(value input 5)". > that was a typo on my part. I assume I am totally off on my testing attempt, and if you could point me in the right direction I would greatly appreciate it. Br, Miau -- View this message in context: http://old.nabble.com/ANN%3A-atom-0.1.3-tp26624813p27212766.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From waldmann at imn.htwk-leipzig.de Mon Jan 18 11:43:39 2010 From: waldmann at imn.htwk-leipzig.de (Johannes Waldmann) Date: Mon Jan 18 11:16:11 2010 Subject: [Haskell-cafe] ghc "make install" question Message-ID: <4B548FBB.90604@imn.htwk-leipzig.de> Hi. How can I get "make install" from a ghc (snapshot) source dir to install binaries $prefix/bin/ghc{,i,-pkg}-$version but *not* overwrite the un-versioned symlinks? Thanks - J.W. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 260 bytes Desc: OpenPGP digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100118/a297ebe6/signature.bin From bertram.felgenhauer at googlemail.com Mon Jan 18 13:04:54 2010 From: bertram.felgenhauer at googlemail.com (Bertram Felgenhauer) Date: Mon Jan 18 12:37:17 2010 Subject: [Haskell-cafe] unexpected behavior / bug in try . System.FilePath.Find.findWithHandler In-Reply-To: <910ddf451001051240h65986bd8od3835a19af3c06d5@mail.gmail.com> References: <910ddf451001051240h65986bd8od3835a19af3c06d5@mail.gmail.com> Message-ID: <20100118180454.GF2170@24f89f8c-e6a1-4e75-85ee-bb8a3743bb9f> A late reply - but as far as I can see, this has gone unanswered so far. Thomas Hartman wrote: > Currently try . System.FilePath.Find.findWithHandler (from the FileManip package, I guess) > will return an exception wrapped in Right, which seems Wrong. For sure > it will just get ignored if wrapped in an ErrorT computation and I > suspect this could lead to other glitchy/unexpected behavior when used > in sysadmin scripts. The short answer is that lazy IO and exceptions don't mix. As the documentation says, findWithHandler returns a list lazily. Lazy IO is (usually) implemented using unsafeInterleaveIO. The 'try' in 'try . System.FilePath.Find.findWithHandler' has no effect after the findWithHandler function returns - which happens immediately after testing whether the given root path is a directory. Now when an error occurs - that happens when the code examines the resulting list from findWithHandler - your exception handler (abort) is executed by findWithHandler, which in your case will raise another exception. This exception will be raised in the context of the code processing the list - and there is no 'try' in effect there. You can avoid that problem by either making IO strict, or by providing a handler that does not raise any exceptions. > Possible fix: you get the expected behavior if you remove > unsafeInterleaveIO from System.FilePath.Find.findWithHandlers Right. That will make findWithHandlers use strict IO, and exceptions will work as expected. On the downside, you'll now read in the whole directory tree into memory before processing it. Do we have an Iterat(or|ee) implementation of directory traversal? Bertram From djf at gmx.ch Mon Jan 18 13:09:23 2010 From: djf at gmx.ch (david fries) Date: Mon Jan 18 12:43:43 2010 Subject: [Haskell-cafe] Newbie question about Parsec Message-ID: <1263838163.1333.7.camel@sphinx.doesntexist.org> Hey everybody I've been playing around with Parsec a little bit lately. I like it a lot, but now I've hit a bit of a challenge. Suppose I have to parse a variable length string representing a time interval. Depending on how many fields there are, the time is either interpreted as seconds, minutes and seconds or hours, minutes and seconds. For example: "... 31 ..." would be parsed as 31 seconds. "... 05:31 ..." would be parsed as 5 minutes and 31 seconds. "... 01:05:31 ..." would be parsed as 1 hour, 5 minutes and 31 seconds. I've come up with the following solution using optionMaybe to deal with the problem: data ElapsedTime = ElapsedTime { hours :: Int, minutes :: Int, seconds :: Int } deriving (Show, Eq, Ord) p_elapsed_time :: CharParser () ElapsedTime p_elapsed_time = toElapsedTime <$> (optionMaybe p_Int) <*> (optionMaybe (char ':' *> p_Int)) <*> (optionMaybe (char ':' *> p_Int <* skipSpaces)) where toElapsedTime Nothing Nothing Nothing = ElapsedTime 0 0 0 toElapsedTime (Just s) Nothing Nothing = ElapsedTime 0 0 s toElapsedTime (Just m) (Just s) Nothing = ElapsedTime 0 m s toElapsedTime (Just h) (Just m) (Just s) = ElapsedTime h m s Where p_Int simply parses a sequence of digits as an Int and skipSpaces does just that. This works correctly, but it also feels kinda clumsy. For one the compiler rightly complains about non-exhaustive pattern matches in the definition of the toElapsedTime function, although I believe that's negligible in that particular case. Is there a better i.e. more elegant way to tackle such a problem? regards, david From daniel.is.fischer at web.de Mon Jan 18 13:41:32 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Jan 18 13:22:10 2010 Subject: [Haskell-cafe] Newbie question about Parsec In-Reply-To: <1263838163.1333.7.camel@sphinx.doesntexist.org> References: <1263838163.1333.7.camel@sphinx.doesntexist.org> Message-ID: <201001181941.32485.daniel.is.fischer@web.de> Am Montag 18 Januar 2010 19:09:23 schrieb david fries: > Hey everybody > > I've been playing around with Parsec a little bit lately. I like it a > lot, but now I've hit a bit of a challenge. Suppose I have to parse a > variable length string representing a time interval. Depending on how > many fields there are, the time is either interpreted as seconds, > minutes and seconds or hours, minutes and seconds. > > For example: > > "... 31 ..." would be parsed as 31 seconds. > "... 05:31 ..." would be parsed as 5 minutes and 31 seconds. > "... 01:05:31 ..." would be parsed as 1 hour, 5 minutes and 31 seconds. > > I've come up with the following solution using optionMaybe to deal with > the problem: > > data ElapsedTime = ElapsedTime { > hours :: Int, > minutes :: Int, > seconds :: Int > } deriving (Show, Eq, Ord) > > p_elapsed_time :: CharParser () ElapsedTime > p_elapsed_time = toElapsedTime <$> (optionMaybe p_Int) > <*> (optionMaybe (char ':' *> p_Int)) > <*> (optionMaybe (char ':' *> p_Int <* > skipSpaces)) > where toElapsedTime Nothing Nothing Nothing = ElapsedTime 0 0 0 > toElapsedTime (Just s) Nothing Nothing = ElapsedTime 0 0 s > toElapsedTime (Just m) (Just s) Nothing = ElapsedTime 0 m s > toElapsedTime (Just h) (Just m) (Just s) = ElapsedTime h m s > p_elapsed_time = toElapsedTime <$> sepBy p_int (char ':') where toElapsedTime (h:m:s:_) = ElapsedTime h m s toElapsedTime [m,s] = ElapsedTime 0 m s toElapsedTime [s] = ElapsedTime 0 0 s toElapsedTime [] = ElapsedTime 0 0 0 You can replace the first pattern for toElapsedTime with [h,m,s] and add a failure case if sepBy p_int (char ':') parses more than three ints (or write a combinator that parses up to n results of p separated by sep). Or p_elapsed_time = do s <- p_int et <- cont_elapsed_time (ElapsedTime 0 0 s) cont_elapsed_time et@(ElapsedTime h m s) = do char ':' n <- p_int cont_elapsed_time (ElapsedTime m s n) <|> return et > > Where p_Int simply parses a sequence of digits as an Int and skipSpaces > does just that. > > This works correctly, but it also feels kinda clumsy. For one the > compiler rightly complains about non-exhaustive pattern matches in the > definition of the toElapsedTime function, although I believe that's > negligible in that particular case. > Is there a better i.e. more elegant way to tackle such a problem? > > regards, > david From nowgate at yahoo.com Mon Jan 18 13:50:15 2010 From: nowgate at yahoo.com (michael rice) Date: Mon Jan 18 13:22:36 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager Message-ID: <873821.89999.qm@web31102.mail.mud.yahoo.com> I downloaded XMonad from the Fedora 12 repository and would like to see it in action. What must I do to get it working from the Gnome desktop environment? Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100118/dc4bcfe3/attachment.html From ivan.miljenovic at gmail.com Mon Jan 18 13:57:59 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Mon Jan 18 13:30:22 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager In-Reply-To: <873821.89999.qm@web31102.mail.mud.yahoo.com> (michael rice's message of "Mon, 18 Jan 2010 10:50:15 -0800 (PST)") References: <873821.89999.qm@web31102.mail.mud.yahoo.com> Message-ID: <87vdez2qbs.fsf@gmail.com> michael rice writes: > I downloaded XMonad from the Fedora 12 repository and would like to see it in action. > > What must I do to get it working from the Gnome desktop environment? See the associated documentation at http://www.haskell.org/haskellwiki/Xmonad -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From haskell at gimbo.org.uk Mon Jan 18 14:35:31 2010 From: haskell at gimbo.org.uk (Andy Gimblett) Date: Mon Jan 18 14:07:55 2010 Subject: [Haskell-cafe] Broken registration link on hackage trac Message-ID: <341D8D6D-5533-43EF-A91D-3EE72DE0D8AB@gimbo.org.uk> Hi all, I want to register an account on hackage's trac instance, but the "register an account" link on the start page: http://hackage.haskell.org/trac/hackage/wiki/WikiStart is broken. I'm guessing someone here knows what it should be and has registered already and thus can fix it. :-) Cheers, -Andy -- Andy Gimblett http://gimbo.org.uk/ From ndmitchell at gmail.com Mon Jan 18 14:56:00 2010 From: ndmitchell at gmail.com (Neil Mitchell) Date: Mon Jan 18 14:28:18 2010 Subject: [Haskell-cafe] Poor man's generic programming In-Reply-To: <4B5218CE.5090902@henning-thielemann.de> References: <4B5218CE.5090902@henning-thielemann.de> Message-ID: <404396ef1001181156u7a805a1avf264ad4a54c8ceb7@mail.gmail.com> Hi Henning, Uniplate might be the answer you are looking for - http://community.haskell.org/~ndm/uniplate Uniplate is simple (only multi parameter type classes, and even then only in a very simple usage), fast (one of the fastest generics libraries) and concise (probably the most concise generics library). It's also not as powerful as most of the other generics libraries, but I find it does about 98% of the generics tasks I need. Uniplate is used extensively in virtually all my tools, for example HLint. As an example, I guess your function returns all the Int's embedded within a data type, at any level? If so, uniplate already has the universeBi method which does that for you, and doesn't require you to do anything. Thanks, Neil 2010/1/16 Henning Thielemann : > Is any of the existing Generics packages able to work without compiler extensions, that is Haskell 98? > I mean, it is ok if the developer of the generic parts of a library needs compiler extensions or extra tools, but the user who calls 'cabal install' shall not need them and the developer, who does not touch generic definitions, should not need them as well. > > I think this could be done with pragmas in the following way: > > class C a where > ?f :: a -> [Int] > ?{-# GENERICDEFAULT > ?f {| Unit |} Unit = [] > ?#-} > > {-# GENERATEDINSTANCEBEGIN Automatically generated - Do not edit! #-} > instance C () where > ?f () = [] > {-# GENERATEDINSTANCEEND Automatically generated - Do not edit! #-} > > Now, by running a tool, the part between the GENERATEDINSTANCE pragmas can generated or updated. > Everything outside the pragmas can be Haskell 98. > > It does not only avoid extensions of the building compiler, but also extensions of a programmer's brain. Because for programmers it is often easier to understand a set of instances and see the common patterns, than to understand generic code that builds the instances. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From gcross at phys.washington.edu Mon Jan 18 15:04:02 2010 From: gcross at phys.washington.edu (Gregory Crosswhite) Date: Mon Jan 18 14:41:06 2010 Subject: [Haskell-cafe] Windows emulator for testing purposes Message-ID: <9C5EA495-FF4E-47F9-A067-2EC3D1642797@phys.washington.edu> Hey everyone! I have a Linux machine and a OSX machine, and I am developing packages that I would like to upload to Hackage one day. Do you have any recommendations for a free/open source solution that would let me emulate a Windows environment for testing purposes? Cheers, Greg From rk at trie.org Mon Jan 18 15:12:59 2010 From: rk at trie.org (Rahul Kapoor) Date: Mon Jan 18 14:45:17 2010 Subject: [Haskell-cafe] Windows emulator for testing purposes In-Reply-To: <9C5EA495-FF4E-47F9-A067-2EC3D1642797@phys.washington.edu> References: <9C5EA495-FF4E-47F9-A067-2EC3D1642797@phys.washington.edu> Message-ID: >?Do you have any recommendations for a free/open source solution that would let me emulate a Windows >environment for testing purposes? Sun's Virtual Box? - http://www.virtualbox.org/ You would still need a Windows license though. Cheers, Rahul From allbery at ece.cmu.edu Mon Jan 18 15:16:36 2010 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Mon Jan 18 14:49:08 2010 Subject: [Haskell-cafe] Windows emulator for testing purposes In-Reply-To: References: <9C5EA495-FF4E-47F9-A067-2EC3D1642797@phys.washington.edu> Message-ID: <44526663-5E35-445F-9ED6-3EE84437E2F4@ece.cmu.edu> On Jan 18, 2010, at 15:12 , Rahul Kapoor wrote: >> Do you have any recommendations for a free/open source solution >> that would let me emulate a Windows >> environment for testing purposes? > > Sun's Virtual Box? - http://www.virtualbox.org/ > You would still need a Windows license though. I wonder if Wine would be good enough for testing. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100118/5d30cd03/PGP.bin From gcross at phys.washington.edu Mon Jan 18 15:19:23 2010 From: gcross at phys.washington.edu (Gregory Crosswhite) Date: Mon Jan 18 14:52:19 2010 Subject: [Haskell-cafe] Windows emulator for testing purposes In-Reply-To: References: <9C5EA495-FF4E-47F9-A067-2EC3D1642797@phys.washington.edu> Message-ID: <61329881-CCFB-4FBA-8784-02135B41A8F6@phys.washington.edu> Does anyone have experience with ReactOS? Cheers, Greg On Jan 18, 2010, at 12:12 PM, Rahul Kapoor wrote: >> Do you have any recommendations for a free/open source solution that would let me emulate a Windows >> environment for testing purposes? > > Sun's Virtual Box? - http://www.virtualbox.org/ > > You would still need a Windows license though. > > Cheers, > Rahul From ivan.miljenovic at gmail.com Mon Jan 18 15:27:59 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Mon Jan 18 15:00:21 2010 Subject: [Haskell-cafe] Windows emulator for testing purposes In-Reply-To: <44526663-5E35-445F-9ED6-3EE84437E2F4@ece.cmu.edu> (Brandon S. Allbery's message of "Mon, 18 Jan 2010 15:16:36 -0500") References: <9C5EA495-FF4E-47F9-A067-2EC3D1642797@phys.washington.edu> <44526663-5E35-445F-9ED6-3EE84437E2F4@ece.cmu.edu> Message-ID: <87y6jvf99s.fsf@gmail.com> "Brandon S. Allbery KF8NH" writes: > I wonder if Wine would be good enough for testing. If memory serves me correctly, I have heard about people installing the Windows version of GHC and using it under Wine for testing purposes... -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From nowgate at yahoo.com Mon Jan 18 15:28:20 2010 From: nowgate at yahoo.com (michael rice) Date: Mon Jan 18 15:00:40 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager In-Reply-To: <87vdez2qbs.fsf@gmail.com> Message-ID: <788800.50544.qm@web31103.mail.mud.yahoo.com> I'd already found a lot of these links and tried some of their suggestions, without any success. Does anyone who posts here actually use it (what platform)? Michael --- On Mon, 1/18/10, Ivan Lazar Miljenovic wrote: From: Ivan Lazar Miljenovic Subject: Re: [Haskell-cafe] Having a look at XMonad window manager To: "michael rice" Cc: haskell-cafe@haskell.org Date: Monday, January 18, 2010, 1:57 PM michael rice writes: > I downloaded XMonad from the Fedora 12 repository and would like to see it in action. > > What must I do to get it working from the Gnome desktop environment? See the associated documentation at http://www.haskell.org/haskellwiki/Xmonad -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100118/7a58298d/attachment.html From dons at galois.com Mon Jan 18 15:30:55 2010 From: dons at galois.com (Don Stewart) Date: Mon Jan 18 15:03:14 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager In-Reply-To: <788800.50544.qm@web31103.mail.mud.yahoo.com> References: <87vdez2qbs.fsf@gmail.com> <788800.50544.qm@web31103.mail.mud.yahoo.com> Message-ID: <20100118203055.GB7777@whirlpool.galois.com> nowgate: > I'd already found a lot of these links and tried some of their suggestions, > without any success. Does anyone who posts here actually use it (what > platform)? What's the problem exactly? -- Don From paul at cogito.org.uk Mon Jan 18 15:33:25 2010 From: paul at cogito.org.uk (Paul Johnson) Date: Mon Jan 18 15:05:45 2010 Subject: [Haskell-cafe] Please help me debug my arrow Message-ID: <4B54C595.6000105@cogito.org.uk> Hi, I'm trying to write an arrow for a real-time stream processor. I'm basing it on the SP type in Hughes paper on Generalising Monads to Arrows (http://www.cs.chalmers.se/~rjmh/Papers/arrows.pdf) section 6. I've extended this with a notion of time by making each step a function of time. But I can't get the compose operator to work. The arrow itself is defined in http://haskell.pastebin.com/m49944f64 with the (.) function highlighted. Some simple tests are in http://haskell.pastebin.com/m6d90f27 with the problematic call highlighted. When run it produces an infinite list of puts, which causes the SimulateRTSP interpreter function to diverge. But I've run the expansions by hand, and they seem to work (see the test case file at the bottom). I'm going nuts looking at this. Can anyone see what I'm doing wrong? Thanks, Paul. From ivan.miljenovic at gmail.com Mon Jan 18 15:37:47 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Mon Jan 18 15:10:08 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager In-Reply-To: <788800.50544.qm@web31103.mail.mud.yahoo.com> (michael rice's message of "Mon, 18 Jan 2010 12:28:20 -0800 (PST)") References: <788800.50544.qm@web31103.mail.mud.yahoo.com> Message-ID: <87tyujf8tg.fsf@gmail.com> michael rice writes: > I'd already found a lot of these links and tried some of their > suggestions, without any success. Does anyone who posts here actually > use it (what platform)? Note that XMonad has its own dedicated mailing list as well... > > Michael > > --- On Mon, 1/18/10, Ivan Lazar Miljenovic wrote: > > From: Ivan Lazar Miljenovic > Subject: Re: [Haskell-cafe] Having a look at XMonad window manager > To: "michael rice" > Cc: haskell-cafe@haskell.org > Date: Monday, January 18, 2010, 1:57 PM > > michael rice writes: > >> I downloaded XMonad from the Fedora 12 repository and would like to see it in action. >> >> What must I do to get it working from the Gnome desktop environment? > > See the associated documentation at http://www.haskell.org/haskellwiki/Xmonad -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From nowgate at yahoo.com Mon Jan 18 16:07:00 2010 From: nowgate at yahoo.com (michael rice) Date: Mon Jan 18 15:39:17 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager In-Reply-To: <20100118203055.GB7777@whirlpool.galois.com> Message-ID: <193154.48824.qm@web31102.mail.mud.yahoo.com> Well, for starters the Fedora entry for installing XMonad is blank/empty: http://www.haskell.org/haskellwiki/Xmonad/Installing_xmonad#Fedora Some things I've done: I set up a .xmonad directory in my home directory with this xmonad.hs [michael@localhost ~]$ cat ~/.xmonad/xmonad.hs ??? -- ??? -- An example, simple ~/.xmonad/xmonad.hs file. ??? -- It overrides a few basic settings, reusing all the other defaults. ??? -- ??? import XMonad ??? main = xmonad $ defaultConfig ??????? { borderWidth??????? = 2 ??????? , terminal?????????? = "urxvt" ??????? , normalBorderColor? = "#cccccc" ??????? , focusedBorderColor = "#cd8b00" } [michael@localhost ~]$ I set up a .xsession directory in my home directory with this in it [michael@localhost ~]$ cat .xsession export WINDOW_MANAGER="/usr/bin/xmonad" exec gnome-session [michael@localhost ~]$ Because supposedly X doesn't even check .xsession file without having xorg-x11-xinit-session installed, I also downloaded that. I set up a XMonad.desktop file in /usr/share/applications directory [michael@localhost ~]$ cat /usr/share/applications/Xmonad.desktop [Desktop Entry] Type=Application Encoding=UTF-8 Name=Xmonad # change this path according to your xmonad binary Exec=/usr/bin/xmonad NoDisplay=true X-GNOME-WMName=Xmonad X-GNOME-Bugzilla-Bugzilla=XMonad X-GNOME-Bugzilla-Product=xmonad X-GNOME-Bugzilla-Component=general X-GNOME-Autostart-Phase=WindowManager X-GNOME-Provides=windowmanager X-GNOME-Autostart-Notify=true [michael@localhost ~]$ I added /usr/bin/xmonad to startup applications. All these things were suggested. Michael --- On Mon, 1/18/10, Don Stewart wrote: From: Don Stewart Subject: Re: [Haskell-cafe] Having a look at XMonad window manager To: "michael rice" Cc: "Ivan Lazar Miljenovic" , haskell-cafe@haskell.org Date: Monday, January 18, 2010, 3:30 PM nowgate: > I'd already found a lot of these links and tried some of their suggestions, > without any success. Does anyone who posts here actually use it (what > platform)? What's the problem exactly? -- Don -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100118/971c7c5a/attachment.html From bulat.ziganshin at gmail.com Mon Jan 18 16:15:36 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Mon Jan 18 15:48:05 2010 Subject: [Haskell-cafe] Poor man's generic programming In-Reply-To: <404396ef1001181156u7a805a1avf264ad4a54c8ceb7@mail.gmail.com> References: <4B5218CE.5090902@henning-thielemann.de> <404396ef1001181156u7a805a1avf264ad4a54c8ceb7@mail.gmail.com> Message-ID: <1288671433.20100119001536@gmail.com> Hello Neil, Monday, January 18, 2010, 10:56:00 PM, you wrote: > Uniplate might be the answer you are looking for - > http://community.haskell.org/~ndm/uniplate it's brilliant! some people has the talent to discover complex things and you have the talent to make complex things simple. it's first and only generics library that i can easily learn and remember can you give a permission to translate http://community.haskell.org/~ndm/darcs/uniplate/uniplate.htm to Russian for http://fprog.ru/ online functional programming journal? -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From andrewcoppin at btinternet.com Mon Jan 18 16:19:43 2010 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Mon Jan 18 15:51:54 2010 Subject: [Haskell-cafe] Mini-announce: A few package updates Message-ID: <4B54D06F.3080407@btinternet.com> In case somebody else on this planet besides me is using these... I've just updated my handful of packages on Hackage so they should now build with GHC 6.12.1. (In most cases, just tweaks to the package dependancies.) I have also changed the documentation for AC-EasyRaster-GTK, to hopefully make it clearer that all the event-related stuff is ONLY necessary if you want to display your images in a GTK window. Oh, and I discovered that I fail basic linear algebra; the AC-Vector package had a bug in vcross, which is fixed in 1.2.2 (but exists in all prior versions). AC-Vector gets a minor version bump because I renamed some stuff; nothing really "exciting" is different. PS. Apparently AC-VanillaArray causes GHC 6.12.1 to panic during compilation... I'll have to investigate that. Still, it does play with GHC.Prim, so that's probably got something to do with it. From ivan.miljenovic at gmail.com Mon Jan 18 16:26:22 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Mon Jan 18 15:58:45 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager In-Reply-To: <193154.48824.qm@web31102.mail.mud.yahoo.com> (michael rice's message of "Mon, 18 Jan 2010 13:07:00 -0800 (PST)") References: <193154.48824.qm@web31102.mail.mud.yahoo.com> Message-ID: <87ockrf6kh.fsf@gmail.com> Oh, is Fedora still using a version of GDM that doesn't let you use a custom .Xsession (or even remember that you want to use something that isn't called "Gnome")? michael rice writes: > Well, for starters the Fedora entry for installing XMonad is blank/empty: > http://www.haskell.org/haskellwiki/Xmonad/Installing_xmonad#Fedora > > Some things I've done: > > I set up a .xmonad directory in my home directory with this xmonad.hs > > [michael@localhost ~]$ cat ~/.xmonad/xmonad.hs > ??? -- > ??? -- An example, simple ~/.xmonad/xmonad.hs file. > ??? -- It overrides a few basic settings, reusing all the other defaults. > ??? -- > > ??? import XMonad > > ??? main = xmonad $ defaultConfig > ??????? { borderWidth??????? = 2 > ??????? , terminal?????????? = "urxvt" > ??????? , normalBorderColor? = "#cccccc" > ??????? , focusedBorderColor = "#cd8b00" } > > [michael@localhost ~]$ > > I set up a .xsession directory in my home directory with this in it > > [michael@localhost ~]$ cat .xsession > export WINDOW_MANAGER="/usr/bin/xmonad" > exec gnome-session > > [michael@localhost ~]$ > > Because supposedly X doesn't even check .xsession file without having xorg-x11-xinit-session installed, I also downloaded that. > > I set up a XMonad.desktop file in /usr/share/applications directory > > [michael@localhost ~]$ cat /usr/share/applications/Xmonad.desktop > [Desktop Entry] > Type=Application > Encoding=UTF-8 > Name=Xmonad > # change this path according to your xmonad binary > Exec=/usr/bin/xmonad > NoDisplay=true > X-GNOME-WMName=Xmonad > X-GNOME-Bugzilla-Bugzilla=XMonad > X-GNOME-Bugzilla-Product=xmonad > X-GNOME-Bugzilla-Component=general > X-GNOME-Autostart-Phase=WindowManager > X-GNOME-Provides=windowmanager > X-GNOME-Autostart-Notify=true > [michael@localhost ~]$ > > I added /usr/bin/xmonad to startup applications. > > All these things were suggested. > > Michael > > --- On Mon, 1/18/10, Don Stewart wrote: > > From: Don Stewart > Subject: Re: [Haskell-cafe] Having a look at XMonad window manager > To: "michael rice" > Cc: "Ivan Lazar Miljenovic" , haskell-cafe@haskell.org > Date: Monday, January 18, 2010, 3:30 PM > > nowgate: >> I'd already found a lot of these links and tried some of their suggestions, >> without any success. Does anyone who posts here actually use it (what >> platform)? > > What's the problem exactly? > > -- Don > > > > -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From nowgate at yahoo.com Mon Jan 18 16:40:42 2010 From: nowgate at yahoo.com (michael rice) Date: Mon Jan 18 16:12:59 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager In-Reply-To: <87ockrf6kh.fsf@gmail.com> Message-ID: <510545.11108.qm@web31105.mail.mud.yahoo.com> Perhaps. Is there a Linux distro that's more XMonad friendly? Michael --- On Mon, 1/18/10, Ivan Lazar Miljenovic wrote: From: Ivan Lazar Miljenovic Subject: Re: [Haskell-cafe] Having a look at XMonad window manager To: "michael rice" Cc: "Don Stewart" , haskell-cafe@haskell.org Date: Monday, January 18, 2010, 4:26 PM Oh, is Fedora still using a version of GDM that doesn't let you use a custom .Xsession (or even remember that you want to use something that isn't called "Gnome")? michael rice writes: > Well, for starters the Fedora entry for installing XMonad is blank/empty: > http://www.haskell.org/haskellwiki/Xmonad/Installing_xmonad#Fedora > > Some things I've done: > > I set up a .xmonad directory in my home directory with this xmonad.hs > > [michael@localhost ~]$ cat ~/.xmonad/xmonad.hs > ??? -- > ??? -- An example, simple ~/.xmonad/xmonad.hs file. > ??? -- It overrides a few basic settings, reusing all the other defaults. > ??? -- > > ??? import XMonad > > ??? main = xmonad $ defaultConfig > ??????? { borderWidth??????? = 2 > ??????? , terminal?????????? = "urxvt" > ??????? , normalBorderColor? = "#cccccc" > ??????? , focusedBorderColor = "#cd8b00" } > > [michael@localhost ~]$ > > I set up a .xsession directory in my home directory with this in it > > [michael@localhost ~]$ cat .xsession > export WINDOW_MANAGER="/usr/bin/xmonad" > exec gnome-session > > [michael@localhost ~]$ > > Because supposedly X doesn't even check .xsession file without having xorg-x11-xinit-session installed, I also downloaded that. > > I set up a XMonad.desktop file in /usr/share/applications directory > > [michael@localhost ~]$ cat /usr/share/applications/Xmonad.desktop > [Desktop Entry] > Type=Application > Encoding=UTF-8 > Name=Xmonad > # change this path according to your xmonad binary > Exec=/usr/bin/xmonad > NoDisplay=true > X-GNOME-WMName=Xmonad > X-GNOME-Bugzilla-Bugzilla=XMonad > X-GNOME-Bugzilla-Product=xmonad > X-GNOME-Bugzilla-Component=general > X-GNOME-Autostart-Phase=WindowManager > X-GNOME-Provides=windowmanager > X-GNOME-Autostart-Notify=true > [michael@localhost ~]$ > > I added /usr/bin/xmonad to startup applications. > > All these things were suggested. > > Michael > > --- On Mon, 1/18/10, Don Stewart wrote: > > From: Don Stewart > Subject: Re: [Haskell-cafe] Having a look at XMonad window manager > To: "michael rice" > Cc: "Ivan Lazar Miljenovic" , haskell-cafe@haskell.org > Date: Monday, January 18, 2010, 3:30 PM > > nowgate: >> I'd already found a lot of these links and tried some of their suggestions, >> without any success. Does anyone who posts here actually use it (what >> platform)? > > What's the problem exactly? > > -- Don > > > >? ? ??? -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100118/91b90e73/attachment.html From jeffzaroyko at gmail.com Mon Jan 18 16:49:51 2010 From: jeffzaroyko at gmail.com (Jeff Zaroyko) Date: Mon Jan 18 16:22:10 2010 Subject: [Haskell-cafe] Windows emulator for testing purposes In-Reply-To: <87y6jvf99s.fsf@gmail.com> References: <9C5EA495-FF4E-47F9-A067-2EC3D1642797@phys.washington.edu> <44526663-5E35-445F-9ED6-3EE84437E2F4@ece.cmu.edu> <87y6jvf99s.fsf@gmail.com> Message-ID: On Tue, Jan 19, 2010 at 7:27 AM, Ivan Lazar Miljenovic wrote: > "Brandon S. Allbery KF8NH" writes: >> I wonder if Wine would be good enough for testing. > > If memory serves me correctly, I have heard about people installing the > Windows version of GHC and using it under Wine for testing purposes... > > -- > Ivan Lazar Miljenovic > Ivan.Miljenovic@gmail.com > IvanMiljenovic.wordpress.com It does work, just make sure you're using a sufficiently new version of Wine, git or a development version from http://winehq.org/download Older versions had a bug which broke cabal install, but I submitted a patch for that. What doesn't work is the installer for cygwin if you require that, otherwise msys-git works fine for providing a bash to run configure scripts, so long as you install mingw and update your path, things will work pretty much the same as Windows. http://www.haskell.org/haskellwiki/GHC_under_WINE -Jeff From stephen.tetley at gmail.com Mon Jan 18 16:52:29 2010 From: stephen.tetley at gmail.com (Stephen Tetley) Date: Mon Jan 18 16:24:50 2010 Subject: [Haskell-cafe] Windows emulator for testing purposes In-Reply-To: <9C5EA495-FF4E-47F9-A067-2EC3D1642797@phys.washington.edu> References: <9C5EA495-FF4E-47F9-A067-2EC3D1642797@phys.washington.edu> Message-ID: <5fdc56d71001181352j7ad33c8fu847fb6233ebf195f@mail.gmail.com> Hello Gregory If the packages are FFI-free they "should just work" (ahem, perhaps with some caveats about e.g. file paths - if they have data files included). If they have FFI dependencies then a Windows emulator is going to have to emulate Unix in turn (either via MinGW or Cygwin). It might be more productive to simply label them as "Untested under Windows" and make a reference to the FFI dependencies. Best wishes Stephen From uzytkownik2 at gmail.com Mon Jan 18 17:16:35 2010 From: uzytkownik2 at gmail.com (Maciej Piechotka) Date: Mon Jan 18 16:49:17 2010 Subject: [Haskell-cafe] Re: Windows emulator for testing purposes In-Reply-To: <9C5EA495-FF4E-47F9-A067-2EC3D1642797@phys.washington.edu> References: <9C5EA495-FF4E-47F9-A067-2EC3D1642797@phys.washington.edu> Message-ID: <1263852995.28729.45.camel@picard> On Mon, 2010-01-18 at 12:04 -0800, Gregory Crosswhite wrote: > Hey everyone! > > I have a Linux machine and a OSX machine, and I am developing packages that I would like to upload to Hackage one day. Do you have any recommendations for a free/open source solution that would let me emulate a Windows environment for testing purposes? > > Cheers, > Greg Wine is not emulator - but depending on the task it may suit you. You can even just link against winelib. If you have a license (IANAL but AFAIR is counting as separate copy. Judging by your email you are in some educational institution - check if you have access to MSDNAA [and license allows you to use it]) you can set up any x86 emulator or have dual boot. Regards From jmillikin at gmail.com Mon Jan 18 17:53:08 2010 From: jmillikin at gmail.com (John Millikin) Date: Mon Jan 18 17:25:46 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager In-Reply-To: <510545.11108.qm@web31105.mail.mud.yahoo.com> References: <87ockrf6kh.fsf@gmail.com> <510545.11108.qm@web31105.mail.mud.yahoo.com> Message-ID: <3283f7fe1001181453p6897544ew4d70f97d22a9025a@mail.gmail.com> I've been quite happy with Ubuntu's xmonad package, though I run it within a GNOME session. Have you tried the instructions on the XMonad wiki for inter-operating with GNOME? http://www.haskell.org/haskellwiki/Xmonad/Using_xmonad_in_Gnome On Mon, Jan 18, 2010 at 13:40, michael rice wrote: > > Perhaps. Is there a Linux distro that's more XMonad friendly? > > Michael > > --- On Mon, 1/18/10, Ivan Lazar Miljenovic wrote: > > From: Ivan Lazar Miljenovic > Subject: Re: [Haskell-cafe] Having a look at XMonad window manager > To: "michael rice" > Cc: "Don Stewart" , haskell-cafe@haskell.org > Date: Monday, January 18, 2010, 4:26 PM > > Oh, is Fedora still using a version of GDM that doesn't let you use a > custom .Xsession (or even remember that you want to use something that > isn't called "Gnome")? > > michael rice writes: > > > Well, for starters the Fedora entry for installing XMonad is blank/empty: > > http://www.haskell.org/haskellwiki/Xmonad/Installing_xmonad#Fedora > > > > Some things I've done: > > > > I set up a .xmonad directory in my home directory with this xmonad.hs > > > > [michael@localhost ~]$ cat ~/.xmonad/xmonad.hs > > ??? -- > > ??? -- An example, simple ~/.xmonad/xmonad.hs file. > > ??? -- It overrides a few basic settings, reusing all the other defaults. > > ??? -- > > > > ??? import XMonad > > > > ??? main = xmonad $ defaultConfig > > ??????? { borderWidth??????? = 2 > > ??????? , terminal?????????? = "urxvt" > > ??????? , normalBorderColor? = "#cccccc" > > ??????? , focusedBorderColor = "#cd8b00" } > > > > [michael@localhost ~]$ > > > > I set up a .xsession directory in my home directory with this in it > > > > [michael@localhost ~]$ cat .xsession > > export WINDOW_MANAGER="/usr/bin/xmonad" > > exec gnome-session > > > > [michael@localhost ~]$ > > > > Because supposedly X doesn't even check .xsession file without having xorg-x11-xinit-session installed, I also downloaded that. > > > > I set up a XMonad.desktop file in /usr/share/applications directory > > > > [michael@localhost ~]$ cat /usr/share/applications/Xmonad.desktop > > [Desktop Entry] > > Type=Application > > Encoding=UTF-8 > > Name=Xmonad > > # change this path according to your xmonad binary > > Exec=/usr/bin/xmonad > > NoDisplay=true > > X-GNOME-WMName=Xmonad > > X-GNOME-Bugzilla-Bugzilla=XMonad > > X-GNOME-Bugzilla-Product=xmonad > > X-GNOME-Bugzilla-Component=general > > X-GNOME-Autostart-Phase=WindowManager > > X-GNOME-Provides=windowmanager > > X-GNOME-Autostart-Notify=true > > [michael@localhost ~]$ > > > > I added /usr/bin/xmonad to startup applications. > > > > All these things were suggested. > > > > Michael > > > > --- On Mon, 1/18/10, Don Stewart wrote: > > > > From: Don Stewart > > Subject: Re: [Haskell-cafe] Having a look at XMonad window manager > > To: "michael rice" > > Cc: "Ivan Lazar Miljenovic" , haskell-cafe@haskell.org > > Date: Monday, January 18, 2010, 3:30 PM > > > > nowgate: > >> I'd already found a lot of these links and tried some of their suggestions, > >> without any success. Does anyone who posts here actually use it (what > >> platform)? > > > > What's the problem exactly? > > > > -- Don > > > > > > > > > > -- > Ivan Lazar Miljenovic > Ivan.Miljenovic@gmail.com > IvanMiljenovic.wordpress.com > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From igloo at earth.li Mon Jan 18 18:17:20 2010 From: igloo at earth.li (Ian Lynagh) Date: Mon Jan 18 17:49:38 2010 Subject: [Haskell-cafe] Broken registration link on hackage trac In-Reply-To: <341D8D6D-5533-43EF-A91D-3EE72DE0D8AB@gimbo.org.uk> References: <341D8D6D-5533-43EF-A91D-3EE72DE0D8AB@gimbo.org.uk> Message-ID: <20100118231720.GA24820@matrix.chaos.earth.li> On Mon, Jan 18, 2010 at 07:35:31PM +0000, Andy Gimblett wrote: > > I want to register an account on hackage's trac instance, but the > "register an account" link on the start page: > > http://hackage.haskell.org/trac/hackage/wiki/WikiStart > > is broken. Fixed - thanks for the report. Thanks Ian From gwern0 at gmail.com Mon Jan 18 18:20:11 2010 From: gwern0 at gmail.com (Gwern Branwen) Date: Mon Jan 18 17:52:28 2010 Subject: [Haskell-cafe] Broken registration link on hackage trac In-Reply-To: <20100118231720.GA24820@matrix.chaos.earth.li> References: <341D8D6D-5533-43EF-A91D-3EE72DE0D8AB@gimbo.org.uk> <20100118231720.GA24820@matrix.chaos.earth.li> Message-ID: On Mon, Jan 18, 2010 at 6:17 PM, Ian Lynagh wrote: > On Mon, Jan 18, 2010 at 07:35:31PM +0000, Andy Gimblett wrote: >> >> I want to register an account on hackage's trac instance, but the >> "register an account" link on the start page: >> >> http://hackage.haskell.org/trac/hackage/wiki/WikiStart >> >> is broken. > > Fixed - thanks for the report. > > > Thanks > Ian While we're fixing things, has anyone else noticed that the QuickCheck mailing list seems to be broken? -- gwern From greg at gregorycollins.net Mon Jan 18 18:22:52 2010 From: greg at gregorycollins.net (Gregory Collins) Date: Mon Jan 18 17:55:11 2010 Subject: [Haskell-cafe] Iteratee wrapper for attoparsec In-Reply-To: <9979e72e1001111448w123e38c1i90ae4276ea800ae3@mail.gmail.com> (John Lato's message of "Mon, 11 Jan 2010 22:48:55 +0000") References: <4B4B949A.5050309@web.de> <9979e72e1001111448w123e38c1i90ae4276ea800ae3@mail.gmail.com> Message-ID: <87y6jvdmlv.fsf@gregorycollins.net> John Lato writes: > I don't know if I'd call it a hybrid, however there is a way to embed > Parsec parsers (v.3 only) in iteratee. The necessary code is > available at: > > http://inmachina.net/~jwlato/haskell/ParsecIteratee.hs This post inspired me to write an iteratee wrapper for attoparsec. The attoparsec library has an incremental parser; this means that we don't have to use John's lookahead buffer trick, restoring the iteratee constant-space guarantee. The downside: I don't think the attoparsec incremental parser is capable of maintaining the source position for error reporting. ------------------------------------------------------------------------------ {-# LANGUAGE OverloadedStrings #-} module Data.Attoparsec.Iteratee (parserToIteratee) where ------------------------------------------------------------------------------ import qualified Data.Attoparsec.Incremental as Atto import Data.Attoparsec.Incremental hiding (Result(..)) import qualified Data.ByteString as S import qualified Data.ByteString.Lazy as L import Data.Iteratee import Data.Iteratee.WrappedByteString import Data.Monoid import Data.Word (Word8) import Prelude hiding (takeWhile) -- for the examples at the bottom only import Control.Monad.Identity import Data.Char import Data.ByteString.Internal (w2c) -- The principle is general enough to work for any 'StreamChunk' type (with -- appropriate wrapping/unwrapping inserted), but I'm working with -- "WrappedByteString Word8", sorry type Stream = StreamG WrappedByteString Word8 type Iteratee m a = IterateeG WrappedByteString Word8 m a type Enumerator m a = Iteratee m a -> m (Iteratee m a) -- | Convert an attoparsec 'Parser' into an 'Iteratee'. parserToIteratee :: (Monad m) => Parser a a -> Iteratee m a parserToIteratee p = IterateeG $ \s -> let r = case s of (EOF Nothing) -> Atto.parse p "" (EOF (Just (Err e))) -> Atto.Failed e (EOF (Just _)) -> Atto.Failed "seek not permitted" (Chunk s') -> Atto.parse p $ fromWrap s' in return $ Cont (runChunk r) Nothing where runChunk (Atto.Failed m) = throwErr $ Err m runChunk (Atto.Done rest r) = IterateeG $ \s -> return $ Done r (addToChunk rest s) runChunk oldr@(Atto.Partial f) = IterateeG $ \s -> case s of (EOF Nothing) -> enforceDone f (EOF (Just e)) -> return $ Cont (throwErr e) (Just e) (Chunk s') -> let x = fromWrap s' k = if L.null x then oldr else f x in return $ Cont (runChunk k) Nothing -- you end an incremental parser by passing it the empty string enforceDone f = return $ case f "" of (Atto.Failed m ) -> Cont (throwErr $ Err m) (Just $ Err m) (Atto.Done rest r) -> Done r $ Chunk (toWrap rest) (Atto.Partial _ ) -> Cont (throwErr eoi) (Just eoi) where eoi = Err "premature end of input" -- | lazy bytestring -> wrapped bytestring toWrap :: L.ByteString -> WrappedByteString Word8 toWrap = WrapBS . S.concat . L.toChunks -- | wrapped bytestring -> lazy bytestring fromWrap :: WrappedByteString Word8 -> L.ByteString fromWrap = L.fromChunks . (:[]) . unWrap -- | tack a lazy bytestring onto the front of an iteratee 'Stream' addToChunk :: L.ByteString -> Stream -> Stream addToChunk s (EOF Nothing) = Chunk $ toWrap s addToChunk _ x@(EOF _) = x addToChunk s (Chunk w) = Chunk $ toWrap s `mappend` w ------------------------------------------------------------------------------ -- And a quick example sp :: Parser r () sp = () <$ takeWhile (isSpace . w2c) digits :: Parser r String digits = many1 (w2c <$> satisfy (isDigit . w2c)) number :: Parser r Int number = read <$> digits numberList :: Parser r [Int] numberList = liftA2 (:) number (many (sp *> number)) ensureEOF :: Parser r () ensureEOF = endOfInput <|> reportError where reportError = do ch <- anyWord8 let msg = concat [ "unexpected character '" , [w2c ch] , "'" ] fail msg numberListIter :: (Monad m) => Iteratee m [Int] numberListIter = parserToIteratee $ numberList <* ensureEOF -- | Turn a strict bytestring into an enumerator enumBS :: (Monad m) => S.ByteString -> Enumerator m a enumBS bs = enumPure1Chunk $ WrapBS bs _example :: [Int] _example = runIdentity (enumerate numberListIter >>= run) where -- example, the source could be any enumerator enumerate = enumBS "1000 2000 3000 4000 5000 6000 7000" _exampleWithError :: Either ErrMsg [Int] _exampleWithError = runIdentity (enumerate numberListIter >>= run . checkErr) where enumerate = enumBS "1000 2000 3000 4000 5000 6000 7000q" -- > *Data.Attoparsec.Iteratee> _example -- > [1000,2000,3000,4000,5000,6000,7000] -- > *Data.Attoparsec.Iteratee> _exampleWithError -- > Left (Err "unexpected character 'q'") ------------------------------------------------------------------------------ G. -- Gregory Collins From gue.schmidt at web.de Mon Jan 18 19:15:54 2010 From: gue.schmidt at web.de (=?ISO-8859-1?Q?G=FCnther_Schmidt?=) Date: Mon Jan 18 18:48:35 2010 Subject: [Haskell-cafe] Re: Windows emulator for testing purposes In-Reply-To: <9C5EA495-FF4E-47F9-A067-2EC3D1642797@phys.washington.edu> References: <9C5EA495-FF4E-47F9-A067-2EC3D1642797@phys.washington.edu> Message-ID: <4B54F9BA.5030205@web.de> Hi, this is my configuration: My iMac and right next to it an x86 with 8GB RAM running OpenSolaris, because of its ZFS. On the OpenSolaris box are about 20 VMs with XP mostly installed, run by VirtualBox in headless mode. I connect to those machines from my iMac via Remote Desktop (available for Mac from Microsoft). Thanks to the RAM I can run up to 3 VMs simultaneously. Once you installed your 1st WinXP into a Virtual Machine and have it activated take a ZFS snapshot of the Virtual disk image and then make ZFS clones from that snapshot. Use those disk images then to install software as you like. They will not cost you any additional disk space initially, thanks to ZFS. All of my devel work is done in those VMS. I suggest you do not bother with wine. G?nther Am 18.01.10 21:04, schrieb Gregory Crosswhite: > Hey everyone! > > I have a Linux machine and a OSX machine, and I am developing packages that I would like to upload to Hackage one day. Do you have any recommendations for a free/open source solution that would let me emulate a Windows environment for testing purposes? > > Cheers, > Greg From schlepptop at henning-thielemann.de Mon Jan 18 19:38:11 2010 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Mon Jan 18 19:10:35 2010 Subject: [Haskell-cafe] Poor man's generic programming In-Reply-To: <404396ef1001181156u7a805a1avf264ad4a54c8ceb7@mail.gmail.com> References: <4B5218CE.5090902@henning-thielemann.de> <404396ef1001181156u7a805a1avf264ad4a54c8ceb7@mail.gmail.com> Message-ID: <4B54FEF3.1080902@henning-thielemann.de> Neil Mitchell schrieb: > Hi Henning, > > Uniplate might be the answer you are looking for - > http://community.haskell.org/~ndm/uniplate > Thanks for the pointer! > Uniplate is simple (only multi parameter type classes, and even then > only in a very simple usage), fast (one of the fastest generics > libraries) and concise (probably the most concise generics library). > It's also not as powerful as most of the other generics libraries, but > I find it does about 98% of the generics tasks I need. Uniplate is > used extensively in virtually all my tools, for example HLint. > Must a package import Uniplate, if it uses Uniplate generics, or is it a preprocessor like I sketched? > As an example, I guess your function returns all the Int's embedded > within a data type, at any level? I abstracted the Bin example from GHC's generic extension introduction: http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-classes.html From wren at freegeek.org Mon Jan 18 21:33:21 2010 From: wren at freegeek.org (wren ng thornton) Date: Mon Jan 18 20:58:49 2010 Subject: [Haskell-cafe] FFI, C/C++ and undefined references In-Reply-To: <5fdc56d71001141255q62763b31je5d1ac544bcd9224@mail.gmail.com> References: <27139612.post@talk.nabble.com> <61E9624C-CB47-469C-BC29-2FA4A670D845@cs.york.ac.uk> <27156254.post@talk.nabble.com> <27167019.post@talk.nabble.com> <1695352408.20100114233628@gmail.com> <5fdc56d71001141255q62763b31je5d1ac544bcd9224@mail.gmail.com> Message-ID: <4B5519F1.9060403@freegeek.org> Stephen Tetley wrote: > Also binding to a C library is easier than binding to a C++ one, if > you can think of another library rather than SRILM that will meet your > needs... Alas, SRILM really is the standard tool for this so there aren't other (worthwhile) options AFAIK. But it's pretty standard for people to bind to SRILM as though it were C, since C bindings are standardized and C++ is a nightmare. I haven't done the gory details myself but I sat next to someone who did. -- Live well, ~wren From gcross at phys.washington.edu Mon Jan 18 21:59:56 2010 From: gcross at phys.washington.edu (Gregory Crosswhite) Date: Mon Jan 18 21:32:18 2010 Subject: [Haskell-cafe] Windows emulator for testing purposes In-Reply-To: <5fdc56d71001181352j7ad33c8fu847fb6233ebf195f@mail.gmail.com> References: <9C5EA495-FF4E-47F9-A067-2EC3D1642797@phys.washington.edu> <5fdc56d71001181352j7ad33c8fu847fb6233ebf195f@mail.gmail.com> Message-ID: <5AA96048-F42A-426B-A384-3016DC896E35@phys.washington.edu> So, part of the problem is that I am using my own build system (Blueprint) rather than Cabal, which I would like to test someday to make sure it works under windows; problems like screwing up the file paths are exactly the kind of thing that I worry about happening. :-) And part of the reason that I developed and am using my own build system is because I am mixing Fortran and Haskell code, which is something that Cabal does not support in any meaningful use of the word "support" --- i.e., I don't count writing a parallel configuration and build system for the Fortran code and grafting it onto Cabal using a complicated assortment of hooks as being a meaningful sense of this word. :-) Cheers, Greg On Jan 18, 2010, at 1:52 PM, Stephen Tetley wrote: > Hello Gregory > > If the packages are FFI-free they "should just work" (ahem, perhaps > with some caveats about e.g. file paths - if they have data files > included). > > If they have FFI dependencies then a Windows emulator is going to have > to emulate Unix in turn (either via MinGW or Cygwin). It might be more > productive to simply label them as "Untested under Windows" and make a > reference to the FFI dependencies. > > Best wishes > > Stephen > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From aslatter at gmail.com Mon Jan 18 23:39:52 2010 From: aslatter at gmail.com (Antoine Latter) Date: Mon Jan 18 23:12:10 2010 Subject: [Haskell-cafe] Declarative binary protocols Message-ID: <694519c51001182039t3a4b7bdfp3dba83d837a3cd15@mail.gmail.com> Cafe, We have some fantastic tools for binary parsing in packages like binary and cereal (and presumably attoparsec, which I've not used). But they don't quite scratch an itch I have when writing implementations of binary communication protocols. A good example of my problem is in my implementation of the memcached binary wire protocol: http://hackage.haskell.org/package/starling What I've tried to do is divide up the library into a declarative protocol description and an imperative machine to sit on a handle and link together a server response with the source request. In the declarative core all of the types which come off of the wire have an associated Data.Binary.Get action - but this isn't quite good enough. Data.Binary works on ByteStrings, but I have a handle. I don't want to use hGetContents because I have trouble working out when lazy IO is and is not correct. I can't use hGet because I don't know how much to get until I'm in the middle of the Get action. How do other folks solve this issue? What I've done is broken down and included (getResponse :: Handle -> IO Response) in my core protocol description module, which gets a fixed-length header from which we can figure out how much else to get to form the complete response. But it would be nice to have something cleaner. One thing I've thought of is generalizing Data.Binary.Get to operate over either ByteStrings or Handles. But then I would be doing reads from the handle every couple of bytes. To avoid that I could extend the monad to include declarations of how many bytes the parser will require, which may be declared mutliple times throughout the parser. This felt a bit weird to me, though. Thanks, Antoine Declarative core module: http://hackage.haskell.org/packages/archive/starling/0.1.1/doc/html/Network-Starling-Core.html IO-centric module: http://hackage.haskell.org/packages/archive/starling/0.1.1/doc/html/Network-Starling-Connection.html From mvanier42 at gmail.com Tue Jan 19 00:19:11 2010 From: mvanier42 at gmail.com (Michael Vanier) Date: Mon Jan 18 23:51:31 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager In-Reply-To: <3283f7fe1001181453p6897544ew4d70f97d22a9025a@mail.gmail.com> References: <87ockrf6kh.fsf@gmail.com> <510545.11108.qm@web31105.mail.mud.yahoo.com> <3283f7fe1001181453p6897544ew4d70f97d22a9025a@mail.gmail.com> Message-ID: <4B5540CF.7030708@cs.caltech.edu> For a completely different approach, I've had good success running xmonad from either Ubuntu minimal (which is a bare-bones version of Ubuntu that few people realize exists) or Arch Linux. In either case you have to spend more time setting up the system, but the results IMO are worth it. I don't use gdm but use a customized .xinitrc script which I invoke myself through startx. Mike John Millikin wrote: > I've been quite happy with Ubuntu's xmonad package, though I run it > within a GNOME session. > > Have you tried the instructions on the XMonad wiki for inter-operating > with GNOME? http://www.haskell.org/haskellwiki/Xmonad/Using_xmonad_in_Gnome > > On Mon, Jan 18, 2010 at 13:40, michael rice wrote: > >> Perhaps. Is there a Linux distro that's more XMonad friendly? >> >> Michael >> >> --- On Mon, 1/18/10, Ivan Lazar Miljenovic wrote: >> >> From: Ivan Lazar Miljenovic >> Subject: Re: [Haskell-cafe] Having a look at XMonad window manager >> To: "michael rice" >> Cc: "Don Stewart" , haskell-cafe@haskell.org >> Date: Monday, January 18, 2010, 4:26 PM >> >> Oh, is Fedora still using a version of GDM that doesn't let you use a >> custom .Xsession (or even remember that you want to use something that >> isn't called "Gnome")? >> >> michael rice writes: >> >> >>> Well, for starters the Fedora entry for installing XMonad is blank/empty: >>> http://www.haskell.org/haskellwiki/Xmonad/Installing_xmonad#Fedora >>> >>> Some things I've done: >>> >>> I set up a .xmonad directory in my home directory with this xmonad.hs >>> >>> [michael@localhost ~]$ cat ~/.xmonad/xmonad.hs >>> -- >>> -- An example, simple ~/.xmonad/xmonad.hs file. >>> -- It overrides a few basic settings, reusing all the other defaults. >>> -- >>> >>> import XMonad >>> >>> main = xmonad $ defaultConfig >>> { borderWidth = 2 >>> , terminal = "urxvt" >>> , normalBorderColor = "#cccccc" >>> , focusedBorderColor = "#cd8b00" } >>> >>> [michael@localhost ~]$ >>> >>> I set up a .xsession directory in my home directory with this in it >>> >>> [michael@localhost ~]$ cat .xsession >>> export WINDOW_MANAGER="/usr/bin/xmonad" >>> exec gnome-session >>> >>> [michael@localhost ~]$ >>> >>> Because supposedly X doesn't even check .xsession file without having xorg-x11-xinit-session installed, I also downloaded that. >>> >>> I set up a XMonad.desktop file in /usr/share/applications directory >>> >>> [michael@localhost ~]$ cat /usr/share/applications/Xmonad.desktop >>> [Desktop Entry] >>> Type=Application >>> Encoding=UTF-8 >>> Name=Xmonad >>> # change this path according to your xmonad binary >>> Exec=/usr/bin/xmonad >>> NoDisplay=true >>> X-GNOME-WMName=Xmonad >>> X-GNOME-Bugzilla-Bugzilla=XMonad >>> X-GNOME-Bugzilla-Product=xmonad >>> X-GNOME-Bugzilla-Component=general >>> X-GNOME-Autostart-Phase=WindowManager >>> X-GNOME-Provides=windowmanager >>> X-GNOME-Autostart-Notify=true >>> [michael@localhost ~]$ >>> >>> I added /usr/bin/xmonad to startup applications. >>> >>> All these things were suggested. >>> >>> Michael >>> >>> --- On Mon, 1/18/10, Don Stewart wrote: >>> >>> From: Don Stewart >>> Subject: Re: [Haskell-cafe] Having a look at XMonad window manager >>> To: "michael rice" >>> Cc: "Ivan Lazar Miljenovic" , haskell-cafe@haskell.org >>> Date: Monday, January 18, 2010, 3:30 PM >>> >>> nowgate: >>> >>>> I'd already found a lot of these links and tried some of their suggestions, >>>> without any success. Does anyone who posts here actually use it (what >>>> platform)? >>>> >>> What's the problem exactly? >>> >>> -- Don >>> >>> >>> >>> >>> >> -- >> Ivan Lazar Miljenovic >> Ivan.Miljenovic@gmail.com >> IvanMiljenovic.wordpress.com >> >> >> _______________________________________________ >> 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 > From aslatter at gmail.com Tue Jan 19 00:25:54 2010 From: aslatter at gmail.com (Antoine Latter) Date: Mon Jan 18 23:58:11 2010 Subject: [Haskell-cafe] Re: Declarative binary protocols In-Reply-To: <694519c51001182039t3a4b7bdfp3dba83d837a3cd15@mail.gmail.com> References: <694519c51001182039t3a4b7bdfp3dba83d837a3cd15@mail.gmail.com> Message-ID: <694519c51001182125u39d948c3x8617be4aaad8889d@mail.gmail.com> On Mon, Jan 18, 2010 at 10:39 PM, Antoine Latter wrote: > Cafe, > > We have some fantastic tools for binary parsing in packages like > binary and cereal (and presumably attoparsec, which I've not used). > But they don't quite scratch an itch I have when writing > implementations of binary communication protocols. > > A good example of my problem is in my implementation of the memcached > binary wire protocol: http://hackage.haskell.org/package/starling > > What I've tried to do is divide up the library into a declarative > protocol description and an imperative machine to sit on a handle and > link together a server response with the source request. > > In the declarative core all of the types which come off of the wire > have an associated Data.Binary.Get action - but this isn't quite good > enough. Data.Binary works on ByteStrings, but I have a handle. I don't > want to use hGetContents because I have trouble working out when lazy > IO is and is not correct. I can't use hGet because I don't know how > much to get until I'm in the middle of the Get action. > Now that I've posted I've come up with a solution. I will start with binary-strict:Data.Binary.Strict.IncrementalGet[1] It currently defines >>>>> data Result a = Failed String | Finished ByteString a | Partial (ByteString -> Result a) <<<<< Which I will change to: >>>>> data Result a = Failed String | Finished ByteString a | Partial Int (ByteString -> Result a) <<<<< Where the p type includes some information as to why the result is partial. This means that I will change the current function: suspend :: Get r () to: require :: Int -> Get r () We will then only return the 'Partial' result on a call to 'require'. Any other attempts to read beyond the so-far fetched byte-string will result in failure. I'll then have a function of type: runFromHandle :: Handle -> Get r r -> IO r Which leaves the handle in a usable state and never seeks ahead in the handle, and also a function: runFromBytes :: ByteString -> Get r r -> {- some sensible return type -} The idea is that the partial return type is hidden from the users of the library, but we take advantage of it to read from the handle in a sensible way. This is all based on a quick read-through of binary-strict. But it fits how I think about a lot of the binary protocols I write: getResponse = do require 256 x <- getX len <- getWord16be y <- getY z <- getZ require (fromIntegral len * 8) a <- getA b <- getB return $ Response x y z a b c The only weird part is that I only ever intend to write the "require" statements at the top-level - maybe 'getA' and the like can be written in some restricted version of the Get monad which doesn't permit 'require' declarations. Any comments? Is there an easier way to do this? Antoine [1] http://hackage.haskell.org/packages/archive/binary-strict/0.4.6/doc/html/Data-Binary-Strict-IncrementalGet.html From tomahawkins at gmail.com Tue Jan 19 01:37:42 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Tue Jan 19 01:09:58 2010 Subject: [Haskell-cafe] ANN: afv-0.0.3 Message-ID: <594c1e831001182237j98b6df5sa8ce67f2c3aafa00@mail.gmail.com> This release of AFV adds counter example generation for both concrete bounded violations or for inconclusive results when the induction fails to converge. I also put Linux and Windows binaries here: http://tomahawkins.org/. http://hackage.haskell.org/package/afv -Tom From jjoshua2 at gmail.com Tue Jan 19 03:56:49 2010 From: jjoshua2 at gmail.com (jjoshua) Date: Tue Jan 19 03:29:05 2010 Subject: [Haskell-cafe] sorting and merging in haskell Message-ID: <27222668.post@talk.nabble.com> So I defined a type called term which is a coefficient and degree of x. int a int b. I want to write a method/methods in haskell to sort them and combine ones with same degree. I think I need to combine somehow, and then use sortby method? I'm just learning haskell, but I now java and c# pretty well and I'm having a hard term converting to functional thinking. its of type [(Int a Int b)] and if b1< b2 put tuple 1 before tuple2, else if = combine by adding a1 to a2, else place 2 before 1. I know how to do it logically, just not the syntax I guess. Thanks so much guys! -- View this message in context: http://old.nabble.com/sorting-and-merging-in-haskell-tp27222668p27222668.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From ekirpichov at gmail.com Tue Jan 19 04:28:40 2010 From: ekirpichov at gmail.com (Eugene Kirpichov) Date: Tue Jan 19 04:00:56 2010 Subject: [Haskell-cafe] sorting and merging in haskell In-Reply-To: <27222668.post@talk.nabble.com> References: <27222668.post@talk.nabble.com> Message-ID: <5e0214851001190128w6735e1c1me991a87e0cfcb69d@mail.gmail.com> Use the 'sortBy' and 'group' functions from Data.List. The rest is quite easy. Or you might use a Data.Map (degree => coefficient), particularly the fromListWith function. 2010/1/19 jjoshua : > > So I defined a type called term which is a coefficient and degree of x. int a > int b. > I want to write a method/methods in haskell to sort them and combine ones > with same degree. I think I need to combine somehow, and then use sortby > method? I'm just learning haskell, but I now java and c# pretty well and I'm > having a hard term converting to functional thinking. > its of type [(Int a Int b)] and if b1< b2 put tuple 1 before tuple2, else if > = combine by adding a1 to a2, else place 2 before 1. I know how to do it > logically, just not the syntax I guess. > Thanks so much guys! > -- > View this message in context: http://old.nabble.com/sorting-and-merging-in-haskell-tp27222668p27222668.html > 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 > -- Eugene Kirpichov Web IR developer, market.yandex.ru From martijn at van.steenbergen.nl Tue Jan 19 05:50:55 2010 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Tue Jan 19 05:23:20 2010 Subject: [Haskell-cafe] Re: Declarative binary protocols In-Reply-To: <694519c51001182125u39d948c3x8617be4aaad8889d@mail.gmail.com> References: <694519c51001182039t3a4b7bdfp3dba83d837a3cd15@mail.gmail.com> <694519c51001182125u39d948c3x8617be4aaad8889d@mail.gmail.com> Message-ID: <4B558E8F.2040208@van.steenbergen.nl> Antoine Latter wrote: > getResponse = do > require 256 > x <- getX > len <- getWord16be > y <- getY > z <- getZ > require (fromIntegral len * 8) > a <- getA > b <- getB > return $ Response x y z a b c This looks like code that could be written in applicative style, in which case you could analyze the parser and automatically compute how many bytes are needed, removing the need for explicit calls to require. Groetjes, Martijn. From waldmann at imn.htwk-leipzig.de Tue Jan 19 06:08:27 2010 From: waldmann at imn.htwk-leipzig.de (Johannes Waldmann) Date: Tue Jan 19 05:41:10 2010 Subject: [Haskell-cafe] Re: parallel matrix multiply (dph, par/pseq) References: <4B539EA4.2020804@imn.htwk-leipzig.de> <351ff25e1001180235x37ed3f68ifef5a92627e29d71@mail.gmail.com> Message-ID: > ... use Array (Int,Int) Double, as it accesses its elements in O(1). thanks for the comments. I don't need O(dim^0) element access - I need O(dim^reasonable) addition and multiplication. Modelling a matrix as [[Element]] should be nearly fine (for sequential execution), I think these are quadratic/cubic: a * b = zipWith (zipWith (+)) a b a * b = for a $ \ row -> for ( transpose b ) $ \ col -> sum $ zipWith (*) row col The only problem with this code is that 'transpose b' (assuming the compiler lifts it to outer scope) allocates memory that later becomes garbage, but not immediately, since it is needed several times. ( in the above, for = flip map , which is missing from the standard libs? by analogy to forM = flip mapM ) Best regards, J.W. From johan.tibell at gmail.com Tue Jan 19 07:13:28 2010 From: johan.tibell at gmail.com (Johan Tibell) Date: Tue Jan 19 06:46:04 2010 Subject: [Haskell-cafe] ZuriHac registration deadline on February 14, 2010 Message-ID: <90889fe71001190413n12ff6639ufecf820e16879eb0@mail.gmail.com> Hi all, Due to budget and security constraints, we need to know the final number of attendees a bit in advance. We've therefore set a registration deadline on February 14, 2010. To register please follow the instructions on the registration page: http://www.haskell.org/haskellwiki/ZuriHac/Register Cheers, Johan & Christophe From doaitse at swierstra.net Tue Jan 19 09:44:43 2010 From: doaitse at swierstra.net (S. Doaitse Swierstra) Date: Tue Jan 19 09:17:07 2010 Subject: [Haskell-cafe] Parsers for Text Adventures In-Reply-To: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> References: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> Message-ID: How about using one of the existing libraries, in this case uu- parsinglib: module Parse where import Text.ParserCombinators.UU.Parsing import Text.ParserCombinators.UU.Examples data Verb = Go | Get | Jump | Climb | Give deriving (Show) pCommand :: Pars String pCommand = foldr (<|>) pFail (map str2com [(Go, "G0"), (Get, "Get"), (Jump, "Jump"), (Give, "Climb"), (Climb, "Give")]) str2com (comm, str) = show comm <$ pToken str and then (the show is for demonstration purposes only; not the swap in the last two elements in the list) *Parse> :load "../Test.hs" [1 of 1] Compiling Parse ( ../Test.hs, interpreted ) Ok, modules loaded: Parse. *Parse> test pCommand "Go" ("Go",[]) *Parse> test pCommand "G0" ("Go",[ Deleted '0' at position 1 expecting 'o', Inserted 'o' at position 2 expecting 'o']) *Parse> test pCommand "o" ("Go",[ Inserted 'G' at position 0 expecting one of ['G', 'G', 'J', 'C', 'G']]) *Parse> test pCommand "Clim" ("Give",[ Inserted 'b' at position 4 expecting 'b']) *Parse> On 17 jan 2010, at 14:30, Mark Spezzano wrote: > Hi, > > I am writing a Text Adventure game in Haskell (like Zork) > > I have all of the basic parser stuff written as described in > Hutton's Programming in Haskell and his associated papers. (I'm > trying to avoid using 3rd party libraries, so that I can learn this > myself) > > Everything that I have works (so far...) except for the following > problem: > > I want to define a grammar using a series of Verbs like this: > > data Verb = Go | Get | Jump | Climb | Give etc, etc deriving (Show, > Read) > > and then have my parser "get" one of these Verb tokens if possible; > otherwise it should do something (?) else like give an error message > stating "I don't know that command" > > Now, Hutton gives examples of parsing strings into string whereas I > want to parse Strings into my Verbs > > So, if the user types "get sword" then it will tokenise "get" as > type Verb's data constructor Get and perhaps "sword" into a Noun > called Sword > > My parser is defined like this: > > newtype Parser a = Parser (String -> [(a, String)]) > > So I CAN give it a Verb type > > but this is where I run into a problem.... > > I've written a Parser called keyword > > keyword :: Parser Verb > keyword = do x <- many1 letter > return (read x) > > (read this as "take-at-least-one-alphabetic-letter-and-convert-to-a- > Verb-type") > > which DOES work provided that the user types in one of my Verbs. If > they don't, well, the whole thing fails with an Exception and halts > processing, returning to GHCi prompt. > > Question: Am I going about this the right way? I want to put > together lots of "data" types like Verb and Noun etc so that I can > build a kind of "BNF grammar". > > Question: If I am going about this the right way then what do I > about the "read x" bit failing when the user stops typing in a > recognised keyword. I could catch the exception, but typing an > incorrect sentence is just a typo, not really appropriate for an > exception, I shouldn't think. If it IS appropriate to do this in > Haskell, then how do I catch this exception and continue processing. > > I thought that exceptions should be for exceptional circumstances, > and it would seem that I might be misusing them in this context. > > Thanks > > Mark Spezzano > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From chaddai.fouche at gmail.com Tue Jan 19 10:18:46 2010 From: chaddai.fouche at gmail.com (=?UTF-8?B?Q2hhZGRhw68gRm91Y2jDqQ==?=) Date: Tue Jan 19 09:51:02 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager In-Reply-To: <3283f7fe1001181453p6897544ew4d70f97d22a9025a@mail.gmail.com> References: <87ockrf6kh.fsf@gmail.com> <510545.11108.qm@web31105.mail.mud.yahoo.com> <3283f7fe1001181453p6897544ew4d70f97d22a9025a@mail.gmail.com> Message-ID: On Mon, Jan 18, 2010 at 11:53 PM, John Millikin wrote: > I've been quite happy with Ubuntu's xmonad package, though I run it > within a GNOME session. > > Have you tried the instructions on the XMonad wiki for inter-operating > with GNOME? http://www.haskell.org/haskellwiki/Xmonad/Using_xmonad_in_Gnome I myself had such a setup (Xmonad in Gnome on Ubuntu) for more than a year and it really was quite good. XMonad works quite well with KDE/Gnome or other major desktops. -- Jeda? From nowgate at yahoo.com Tue Jan 19 10:24:05 2010 From: nowgate at yahoo.com (michael rice) Date: Tue Jan 19 09:56:21 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager In-Reply-To: Message-ID: <867005.22829.qm@web31103.mail.mud.yahoo.com> How did you configure it? Are you still using it? Michael --- On Tue, 1/19/10, Chadda? Fouch? wrote: From: Chadda? Fouch? Subject: Re: [Haskell-cafe] Having a look at XMonad window manager To: "John Millikin" Cc: "michael rice" , haskell-cafe@haskell.org Date: Tuesday, January 19, 2010, 10:18 AM On Mon, Jan 18, 2010 at 11:53 PM, John Millikin wrote: > I've been quite happy with Ubuntu's xmonad package, though I run it > within a GNOME session. > > Have you tried the instructions on the XMonad wiki for inter-operating > with GNOME? http://www.haskell.org/haskellwiki/Xmonad/Using_xmonad_in_Gnome I myself had such a setup (Xmonad in Gnome on Ubuntu) for more than a year and it really was quite good. XMonad works quite well with KDE/Gnome or other major desktops. -- Jeda? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100119/883ee2cb/attachment.html From doaitse at swierstra.net Tue Jan 19 11:31:02 2010 From: doaitse at swierstra.net (S.Doaitse Swierstra) Date: Tue Jan 19 11:03:24 2010 Subject: [Haskell-cafe] Parsers for Text Adventures; small typo corrected in example In-Reply-To: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> References: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> Message-ID: How about using one of the existing libraries, in this case uu- parsinglib: module Parse where import Text.ParserCombinators.UU.Parsing import Text.ParserCombinators.UU.Examples data Verb = Go | Get | Jump | Climb | Give deriving (Show) pCommand :: Pars String pCommand = foldr (<|>) pFail (map str2com [(Go, "Go"), (Get, "Get"), (Jump, "Jump"), (Give, "Climb"), (Climb, "Give")]) str2com (comm, str) = show comm <$ pToken str and then (the show is for demonstration purposes only; not the swap in the last two elements in the list) *Parse> :load "../Test.hs" [1 of 1] Compiling Parse ( ../Test.hs, interpreted ) Ok, modules loaded: Parse. *Parse> test pCommand "Go" ("Go",[]) *Parse> test pCommand "G0" ("Go",[ Deleted '0' at position 1 expecting 'o', Inserted 'o' at position 2 expecting 'o']) *Parse> test pCommand "o" ("Go",[ Inserted 'G' at position 0 expecting one of ['G', 'G', 'J', 'C', 'G']]) *Parse> test pCommand "Clim" ("Give",[ Inserted 'b' at position 4 expecting 'b']) *Parse> On 17 jan 2010, at 14:30, Mark Spezzano wrote: > Hi, > > I am writing a Text Adventure game in Haskell (like Zork) > > I have all of the basic parser stuff written as described in > Hutton's Programming in Haskell and his associated papers. (I'm > trying to avoid using 3rd party libraries, so that I can learn this > myself) > > Everything that I have works (so far...) except for the following > problem: > > I want to define a grammar using a series of Verbs like this: > > data Verb = Go | Get | Jump | Climb | Give etc, etc deriving (Show, > Read) > > and then have my parser "get" one of these Verb tokens if possible; > otherwise it should do something (?) else like give an error message > stating "I don't know that command" > > Now, Hutton gives examples of parsing strings into string whereas I > want to parse Strings into my Verbs > > So, if the user types "get sword" then it will tokenise "get" as > type Verb's data constructor Get and perhaps "sword" into a Noun > called Sword > > My parser is defined like this: > > newtype Parser a = Parser (String -> [(a, String)]) > > So I CAN give it a Verb type > > but this is where I run into a problem.... > > I've written a Parser called keyword > > keyword :: Parser Verb > keyword = do x <- many1 letter > return (read x) > > (read this as "take-at-least-one-alphabetic-letter-and-convert-to-a- > Verb-type") > > which DOES work provided that the user types in one of my Verbs. If > they don't, well, the whole thing fails with an Exception and halts > processing, returning to GHCi prompt. > > Question: Am I going about this the right way? I want to put > together lots of "data" types like Verb and Noun etc so that I can > build a kind of "BNF grammar". > > Question: If I am going about this the right way then what do I > about the "read x" bit failing when the user stops typing in a > recognised keyword. I could catch the exception, but typing an > incorrect sentence is just a typo, not really appropriate for an > exception, I shouldn't think. If it IS appropriate to do this in > Haskell, then how do I catch this exception and continue processing. > > I thought that exceptions should be for exceptional circumstances, > and it would seem that I might be misusing them in this context. > > Thanks > > Mark Spezzano > > _______________________________________________ > 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 From ekirpichov at gmail.com Tue Jan 19 12:25:28 2010 From: ekirpichov at gmail.com (Eugene Kirpichov) Date: Tue Jan 19 11:57:43 2010 Subject: [Haskell-cafe] #haskell stopped being logged on tunes.org Message-ID: <5e0214851001190925x13d29b4ube27905e85161161@mail.gmail.com> Hello. The #haskell channel stopped being logged because now it accepts only someone who has IDENTIFY'd. For the last 3 days essentially nothing has been recorded. I am not even sure whether this should be fixed on the tunes.org site or on #haskell's, but something has to be done, and I plea those with sufficient power for that to do it :) -- Eugene Kirpichov Web IR developer, market.yandex.ru From bugfact at gmail.com Tue Jan 19 13:21:39 2010 From: bugfact at gmail.com (Peter Verswyvelen) Date: Tue Jan 19 12:53:55 2010 Subject: [Haskell-cafe] Parsers for Text Adventures; small typo corrected in example In-Reply-To: References: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> Message-ID: The original author said he did not want to use existing parser libraries, but write it himself for learning. After I read "introduction to functional programming" from Bird, I closed the book, and re-wrote the parser from scratch again, and seeing how all these pieces come together was such a wonderful experience that I would recommend everyone to this once instead of immediately using an existing library :-) It seems Marks parser definition lacks error information. It's been a while since I played with Haskell, but if I recall correctly, you could define a parser with backtracking that carries errors as: type Error = String newtype Parser a = Parser (String -> Either Error [(a, String)]) or was it newtype Parser a = Parser (String -> [(Either Error a, String)]) in any case, when combining parsers using >>=, the errors must be propagated. As you can see, I forgot the correct solution myself, so now I would indeed use a library, since I know I could do it once ;) On Tue, Jan 19, 2010 at 5:31 PM, S.Doaitse Swierstra wrote: > How about using one of the existing libraries, in this case uu-parsinglib: > > module Parse where > > import Text.ParserCombinators.UU.Parsing > import Text.ParserCombinators.UU.Examples > > data Verb = Go | Get | Jump | Climb | Give deriving (Show) > > pCommand :: Pars String > pCommand = foldr (<|>) pFail (map str2com [(Go, "Go"), (Get, "Get"), (Jump, > "Jump"), (Give, "Climb"), (Climb, "Give")]) > > str2com (comm, str) = show comm <$ pToken str > > > and then (the show is for demonstration purposes only; not the swap in the > last two elements in the list) > > *Parse> :load "../Test.hs" > [1 of 1] Compiling Parse ? ? ? ? ? ?( ../Test.hs, interpreted ) > Ok, modules loaded: Parse. > *Parse> test pCommand "Go" > ("Go",[]) > *Parse> test pCommand "G0" > ("Go",[ > Deleted ?'0' at position 1 expecting 'o', > Inserted 'o' at position 2 expecting 'o']) > *Parse> test pCommand "o" > ("Go",[ > Inserted 'G' at position 0 expecting one of ['G', 'G', 'J', 'C', 'G']]) > *Parse> test pCommand "Clim" > ("Give",[ > Inserted 'b' at position 4 expecting 'b']) > *Parse> > > > On 17 jan 2010, at 14:30, Mark Spezzano wrote: > >> Hi, >> >> I am writing a Text Adventure game in Haskell (like Zork) >> >> I have all of the basic parser stuff written as described in Hutton's >> Programming in Haskell and his associated papers. (I'm trying to avoid using >> 3rd party libraries, so that I can learn this myself) >> >> Everything that I have works (so far...) except for the following problem: >> >> I want to define a grammar using a series of Verbs like this: >> >> data Verb = Go | Get | Jump | Climb | Give etc, etc deriving (Show, Read) >> >> and then have my parser "get" one of these Verb tokens if possible; >> otherwise it should do something (?) else like give an error message stating >> "I don't know that command" >> >> Now, Hutton gives examples of parsing strings into string whereas I want >> to parse Strings into my Verbs >> >> So, if the user types "get sword" then it will tokenise "get" as type >> Verb's data constructor Get and perhaps "sword" into a Noun called Sword >> >> My parser is defined like this: >> >> newtype Parser a = Parser (String -> [(a, String)]) >> >> So I CAN give it a Verb type >> >> but this is where I run into a problem.... >> >> I've written a Parser called keyword >> >> keyword :: Parser Verb >> keyword = do x <- many1 letter >> ? ? ? ? ? ? ? ? ? ? ? ?return (read x) >> >> (read this as >> "take-at-least-one-alphabetic-letter-and-convert-to-a-Verb-type") >> >> which DOES work provided that the user types in one of my Verbs. If they >> don't, well, the whole thing fails with an Exception and halts processing, >> returning to GHCi prompt. >> >> Question: Am I going about this the right way? I want to put together lots >> of "data" types like Verb and Noun etc so that I can build a kind of "BNF >> grammar". >> >> Question: If I am going about this the right way then what do I about the >> "read x" bit failing when the user stops typing in a recognised keyword. I >> could catch the exception, but typing an incorrect sentence is just a typo, >> not really appropriate for an exception, I shouldn't think. If it IS >> appropriate to do this in Haskell, then how do I catch this exception and >> continue processing. >> >> I thought that exceptions should be for exceptional circumstances, and it >> would seem that I might be misusing them in this context. >> >> Thanks >> >> Mark Spezzano >> >> _______________________________________________ >> 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 mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From ivan.miljenovic at gmail.com Tue Jan 19 13:26:29 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Tue Jan 19 12:58:50 2010 Subject: [Haskell-cafe] #haskell stopped being logged on tunes.org In-Reply-To: <5e0214851001190925x13d29b4ube27905e85161161@mail.gmail.com> (Eugene Kirpichov's message of "Tue, 19 Jan 2010 20:25:28 +0300") References: <5e0214851001190925x13d29b4ube27905e85161161@mail.gmail.com> Message-ID: <878wburlwq.fsf@gmail.com> Eugene Kirpichov writes: > I am not even sure whether this should be fixed on the tunes.org site > or on #haskell's, but something has to be done, How about getting everyone to register and be identified? *ducks* -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From ozgurakgun at gmail.com Tue Jan 19 13:46:58 2010 From: ozgurakgun at gmail.com (Ozgur Akgun) Date: Tue Jan 19 13:19:15 2010 Subject: [Haskell-cafe] cabal install glfw Message-ID: <7be1feae1001191046y5245aeacm5ef8433e49669302@mail.gmail.com> Dear Cafe and Paul, I am constantly having problems with cabal install in Snow Leopard. Some I solve, some I cannot unfortunately. When I run sudo cabal install glfw -v2 in Snow Leopard, I get the following. glfw/lib/macosx/macosx_enable.c:1:0: error: bad value (apple) for -march= switch glfw/lib/macosx/macosx_enable.c:1:0: error: bad value (apple) for -mtune= switch cabal: Error: some packages failed to install: GLFW-0.4.1 failed during the building phase. The exception was: exit: ExitFailure 1 Regards, -- Ozgur Akgun -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100119/c96cfcbe/attachment.html From ndmitchell at gmail.com Tue Jan 19 14:09:41 2010 From: ndmitchell at gmail.com (Neil Mitchell) Date: Tue Jan 19 13:41:55 2010 Subject: [Haskell-cafe] Poor man's generic programming In-Reply-To: <4B54FEF3.1080902@henning-thielemann.de> References: <4B5218CE.5090902@henning-thielemann.de> <404396ef1001181156u7a805a1avf264ad4a54c8ceb7@mail.gmail.com> <4B54FEF3.1080902@henning-thielemann.de> Message-ID: <404396ef1001191109r7daed15fo4fb933cd967673cb@mail.gmail.com> Hi Henning, >> Uniplate is simple (only multi parameter type classes, and even then >> only in a very simple usage), fast (one of the fastest generics >> libraries) and concise (probably the most concise generics library). >> It's also not as powerful as most of the other generics libraries, but >> I find it does about 98% of the generics tasks I need. Uniplate is >> used extensively in virtually all my tools, for example HLint. >> > > Must a package import Uniplate, if it uses Uniplate generics, or is it a > preprocessor like I sketched? Uniplate is a library, not a preprocessor. To depend on uniplate simply add it to your cabal file, and import the correct module. There is no preprocessor, and there are no wacky extensions. If you restrict yourself to some part of the library it's even totally Haskell 98, but none of it's not Haskell 2011. >> As an example, I guess your function returns all the Int's embedded >> within a data type, at any level? > > I abstracted the Bin example from GHC's generic extension introduction: That's one thing Uniplate can't do. But if you want a preprocessor to generate Binary instances can I recommend Derive (http://community.haskell.org/~ndm/derive). Thanks, Neil From ndmitchell at gmail.com Tue Jan 19 14:15:15 2010 From: ndmitchell at gmail.com (Neil Mitchell) Date: Tue Jan 19 13:47:32 2010 Subject: [Haskell-cafe] Poor man's generic programming In-Reply-To: <1288671433.20100119001536@gmail.com> References: <4B5218CE.5090902@henning-thielemann.de> <404396ef1001181156u7a805a1avf264ad4a54c8ceb7@mail.gmail.com> <1288671433.20100119001536@gmail.com> Message-ID: <404396ef1001191115r48790232y42165bfc622b5897@mail.gmail.com> Hi Bulat, >> Uniplate might be the answer you are looking for - >> http://community.haskell.org/~ndm/uniplate > > it's brilliant! some people has the talent to discover complex things > and you have the talent to make complex things simple. it's first and only > generics library that i can easily learn and remember I'm very glad you like it :-) > can you give a permission to translate http://community.haskell.org/~ndm/darcs/uniplate/uniplate.htm > to Russian for http://fprog.ru/ online functional programming journal? Yes, that sounds great. However, I'm currently not a particular fan of the manual in it's current state - it isn't that well written and some bits need expanding. How about I revamp it, then let you know? I can probably do it within the next few weeks. Thanks, Neil From kowey at darcs.net Tue Jan 19 14:32:17 2010 From: kowey at darcs.net (Eric Y. Kow) Date: Tue Jan 19 14:04:36 2010 Subject: [Haskell-cafe] Re: Darcs fundraising 2010 - send us to ZuriHac! (only $1333 more by 15 Feb) In-Reply-To: <20100109203923.GC967@dewdrop.local> References: <20100109203923.GC967@dewdrop.local> Message-ID: <20100119193216.GA265@dewdrop.local> Hi everybody, I'm just writing to thank everybody for your donations so far to the Darcs 2010 travel fund, and to give a little progress update. Thanks to your generous contributions, we've managed to raise $667, putting us 1/3 of the way there! We only have $1333 to go, that's a little over three hundred to meet last year's target and a thousand more to make our 2010 objectives. If you're still thinking of helping out, now is a good time! :-) Otherwise, stay tuned at http://darcs.net/donations.html for our progress. Eric PS. If you could send me an email when you make a donation, I can provide a daily update on our fundraising status. Donating by Google Checkout ---------------------------------------------------------------------- Donating via Google Checkout puts more of your donation to work, since Google charges no Checkout fees to 501(c)(3) organizations. Please visit http://darcs.net/donations.html for more details. Donating by check (USA) ---------------------------------------------------------------------- The next best option is to donate by check if you have a US bank account. Checks should be made payable to "Software Freedom Conservancy, Inc.", with "Directed donation: Darcs" in the memo. They can be mailed to Software Freedom Conservancy 1995 BROADWAY FL 17 NEW YORK NY 10023-5882 USA Donating by Paypal ---------------------------------------------------------------------- Please visit http://darcs.net/donations.html for more details. -- Eric Kow PGP Key ID: 08AC04F9 -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 195 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100119/6045d1a2/attachment.bin From bulat.ziganshin at gmail.com Tue Jan 19 14:48:41 2010 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Tue Jan 19 14:21:19 2010 Subject: [Haskell-cafe] Poor man's generic programming In-Reply-To: <404396ef1001191115r48790232y42165bfc622b5897@mail.gmail.com> References: <4B5218CE.5090902@henning-thielemann.de> <404396ef1001181156u7a805a1avf264ad4a54c8ceb7@mail.gmail.com> <1288671433.20100119001536@gmail.com> <404396ef1001191115r48790232y42165bfc622b5897@mail.gmail.com> Message-ID: <1376467600.20100119224841@gmail.com> Hello Neil, Tuesday, January 19, 2010, 10:15:15 PM, you wrote: >> can you give a permission to translate http://community.haskell.org/~ndm/darcs/uniplate/uniplate.htm >> to Russian for http://fprog.ru/ online functional programming journal? > Yes, that sounds great. However, I'm currently not a particular fan of > the manual in it's current state - it isn't that well written and some > bits need expanding. How about I revamp it, then let you know? I can > probably do it within the next few weeks. it would be even better. i just finished reading your paper - tutorial doesn't emphasize some details i've found there, in particular restrictions of Uniplate and how these are particularly overcomed by BiPlate. i.e. it may be derived from tutorial but wasn't obvious for me before i've read the paper -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From ninegua at gmail.com Tue Jan 19 14:49:07 2010 From: ninegua at gmail.com (Paul L) Date: Tue Jan 19 14:21:26 2010 Subject: [Haskell-cafe] cabal install glfw In-Reply-To: <7be1feae1001191046y5245aeacm5ef8433e49669302@mail.gmail.com> References: <7be1feae1001191046y5245aeacm5ef8433e49669302@mail.gmail.com> Message-ID: <856033f21001191149i1817cc0dmf01acfe303bb3c74@mail.gmail.com> The problem you mentioned has long been fixed in the darcs version, but then there is also another problem: you need GHC 6.12 in order to compile GLFW for Snow Leopard. Here is a detail description of why prior versions of GHC fails to work: http://hackage.haskell.org/trac/ghc/ticket/3522 I've just made a new release and bumped GLFW to 0.4.2, you may try it with GHC 6.12 on Snow Leopard and see if it now works. On 1/19/10, Ozgur Akgun wrote: > Dear Cafe and Paul, > > I am constantly having problems with cabal install in Snow Leopard. Some I > solve, some I cannot unfortunately. > > When I run > > sudo cabal install glfw -v2 > > in Snow Leopard, I get the following. > > glfw/lib/macosx/macosx_enable.c:1:0: > error: bad value (apple) for -march= switch > > glfw/lib/macosx/macosx_enable.c:1:0: > error: bad value (apple) for -mtune= switch > cabal: Error: some packages failed to install: > GLFW-0.4.1 failed during the building phase. The exception was: > exit: ExitFailure 1 > > > Regards, > > -- > Ozgur Akgun > -- Regards, Paul Liu Yale Haskell Group http://www.haskell.org/yale From schlepptop at henning-thielemann.de Tue Jan 19 15:07:04 2010 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Tue Jan 19 14:38:32 2010 Subject: [Haskell-cafe] ANNOUNCE: Functional Programming Bibliography In-Reply-To: <58925be01001141654oacf7928w7300d084fbcc0b0e@mail.gmail.com> References: <58925be01001141303l3d7a55e4u7d10d54c363e352a@mail.gmail.com> <4335a3261001141311s167d1e17pf3550bfcb758877a@mail.gmail.com> <4335a3261001141312s3eaf6ee9l3e95f04ec909d205@mail.gmail.com> <58925be01001141654oacf7928w7300d084fbcc0b0e@mail.gmail.com> Message-ID: <4B5610E8.5070701@henning-thielemann.de> James Russell schrieb: > > Not much to it, really. It's a LAMH thing, if you will. > > The Haskell part just runs as a CGI app, > and uses the HDBC, HDBC-mysql, cgi, and xhtml > packages, and is just a few hundred lines, including all > the html templates which I create with the xhtml package. > > As for the bibliography stuff, > right now I actually maintain a master .bib file > and use bibTeX along with a set of custom .bst files > to munge everything up to be imported into MySQL. Interesting. Some time ago I managed a preprints list using a self-made Haskell program, where all entries where stored in a BibTeX file. http://www.math.uni-bremen.de/zetem/DFG-Schwerpunkt/preprints/ Recently I have extracted its BibTeX parsing and generating to: http://hackage.haskell.org/package/bibtex From jmillikin at gmail.com Tue Jan 19 16:00:07 2010 From: jmillikin at gmail.com (John Millikin) Date: Tue Jan 19 15:32:42 2010 Subject: [Haskell-cafe] Non-ASCII characters in .cabal files break Haddock? Message-ID: <3283f7fe1001191300w75444273yc4a9140b151bc220@mail.gmail.com> I recently uploaded a package to Hackage[1], which contains a non-ASCII character in the .cabal file. That file is encoded with UTF-8, and it displays fine in Vim, Firefox, and even the Hackage package landing page. However, Haddock is failing to build it[2] -- apparently it can't handle UTF-8 encoded text properly. In documentation sections, Haddock supports special syntax for escaping non-ASCII. Is there any equivalent syntax for Cabal files? [1] http://hackage.haskell.org/package/natural-sort' [2] http://hackage.haskell.org/packages/archive/natural-sort/0.1/logs/failure/ghc-6.12 From doaitse at swierstra.net Tue Jan 19 17:12:48 2010 From: doaitse at swierstra.net (S. Doaitse Swierstra) Date: Tue Jan 19 16:45:03 2010 Subject: [Haskell-cafe] Parsers for Text Adventures; in one line In-Reply-To: References: <9999F83C-7274-426A-BA10-4A027B2B1A1A@chariot.net.au> Message-ID: <0E53F7AE-EA0F-459A-AFF4-76B1F8DD1814@swierstra.net> When cycling home I realised it could even be shorter: module Parse where import Text.ParserCombinators.UU.Parsing import Text.ParserCombinators.UU.Examples data Verb = Go | Get | Jump | Climb | Give deriving (Show) pCommand :: Pars Verb pCommand = foldr (\ c r -> c <$ pToken (show c) <|> r) pFail [Go , Get , Jump , Climb , Give] *Parse> test pCommand "Go" Loading package syb ... linking ... done. Loading package base-3.0.3.1 ... linking ... done. Loading package array-0.2.0.0 ... linking ... done. Loading package filepath-1.1.0.2 ... linking ... done. Loading package old-locale-1.0.0.1 ... linking ... done. Loading package old-time-1.0.0.2 ... linking ... done. Loading package unix-2.3.2.0 ... linking ... done. Loading package directory-1.0.0.3 ... linking ... done. Loading package process-1.0.1.1 ... linking ... done. Loading package random-1.0.0.1 ... linking ... done. Loading package haskell98 ... linking ... done. Loading package uu-parsinglib-2.3.1 ... linking ... done. (Go,[]) se> *Parse> test pCommand "Clim" (Climb,[ Inserted 'b' at position 4 expecting 'b']) *Parse> On 19 jan 2010, at 17:31, S.Doaitse Swierstra wrote: > How about using one of the existing libraries, in this case uu- > parsinglib: > > module Parse where > > import Text.ParserCombinators.UU.Parsing > import Text.ParserCombinators.UU.Examples > > data Verb = Go | Get | Jump | Climb | Give deriving (Show) > > pCommand :: Pars String > pCommand = foldr (<|>) pFail (map str2com [(Go, "Go"), (Get, "Get"), > (Jump, "Jump"), (Give, "Climb"), (Climb, "Give")]) > > str2com (comm, str) = show comm <$ pToken str > > > and then (the show is for demonstration purposes only; not the swap > in the last two elements in the list) > > *Parse> :load "../Test.hs" > [1 of 1] Compiling Parse ( ../Test.hs, interpreted ) > Ok, modules loaded: Parse. > *Parse> test pCommand "Go" > ("Go",[]) > *Parse> test pCommand "G0" > ("Go",[ > Deleted '0' at position 1 expecting 'o', > Inserted 'o' at position 2 expecting 'o']) > *Parse> test pCommand "o" > ("Go",[ > Inserted 'G' at position 0 expecting one of ['G', 'G', 'J', 'C', > 'G']]) > *Parse> test pCommand "Clim" > ("Give",[ > Inserted 'b' at position 4 expecting 'b']) > *Parse> > > > On 17 jan 2010, at 14:30, Mark Spezzano wrote: > >> Hi, >> >> I am writing a Text Adventure game in Haskell (like Zork) >> >> I have all of the basic parser stuff written as described in >> Hutton's Programming in Haskell and his associated papers. (I'm >> trying to avoid using 3rd party libraries, so that I can learn this >> myself) >> >> Everything that I have works (so far...) except for the following >> problem: >> >> I want to define a grammar using a series of Verbs like this: >> >> data Verb = Go | Get | Jump | Climb | Give etc, etc deriving (Show, >> Read) >> >> and then have my parser "get" one of these Verb tokens if possible; >> otherwise it should do something (?) else like give an error >> message stating "I don't know that command" >> >> Now, Hutton gives examples of parsing strings into string whereas I >> want to parse Strings into my Verbs >> >> So, if the user types "get sword" then it will tokenise "get" as >> type Verb's data constructor Get and perhaps "sword" into a Noun >> called Sword >> >> My parser is defined like this: >> >> newtype Parser a = Parser (String -> [(a, String)]) >> >> So I CAN give it a Verb type >> >> but this is where I run into a problem.... >> >> I've written a Parser called keyword >> >> keyword :: Parser Verb >> keyword = do x <- many1 letter >> return (read x) >> >> (read this as "take-at-least-one-alphabetic-letter-and-convert-to-a- >> Verb-type") >> >> which DOES work provided that the user types in one of my Verbs. If >> they don't, well, the whole thing fails with an Exception and halts >> processing, returning to GHCi prompt. >> >> Question: Am I going about this the right way? I want to put >> together lots of "data" types like Verb and Noun etc so that I can >> build a kind of "BNF grammar". >> >> Question: If I am going about this the right way then what do I >> about the "read x" bit failing when the user stops typing in a >> recognised keyword. I could catch the exception, but typing an >> incorrect sentence is just a typo, not really appropriate for an >> exception, I shouldn't think. If it IS appropriate to do this in >> Haskell, then how do I catch this exception and continue processing. >> >> I thought that exceptions should be for exceptional circumstances, >> and it would seem that I might be misusing them in this context. >> >> Thanks >> >> Mark Spezzano >> >> _______________________________________________ >> 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 mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From tomahawkins at gmail.com Tue Jan 19 17:13:16 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Tue Jan 19 16:45:36 2010 Subject: [Haskell-cafe] Re: Atom bug(?) In-Reply-To: <80786448-AB13-4DD4-9201-7A990E5B3C19@gmail.com> References: <80786448-AB13-4DD4-9201-7A990E5B3C19@gmail.com> Message-ID: <594c1e831001191413n4a4e72c1v16c086aa1dadaa66@mail.gmail.com> On Tue, Jan 19, 2010 at 10:42 PM, Lee Pike wrote: > Tom, > > Is this a bug? ?The following program compiles, but the rule is scheduled at > period 1 (rather than 0). ?I wouldn't have thought to have an assignment > outside of an atom until another engineer here wrote it. ?In any event, I > would have expected that the rule should have period 3. > > Lee > > example :: Atom () > example = period 3 $ do > > ?a <- word32 "a" 0 > > ?a <== 21 The top-most rule is implied with the compile command. This makes it appear as if the assignment doesn't belong to a rule, when if fact it belongs to the implicit top level rule. The top level rule always has a period of 1. Period constraints are only applied to sub-rules, not the current rule. This prevents ambiguous situations, such as: atom "something" $ do period 1 (a <== 1) -- Does 'something' execute every 1 or ... period 2 (b <== 2) -- 2 cycles? So in your example, 'period 3' has no sub rules that it applies to. -Tom From leepike at gmail.com Tue Jan 19 17:50:45 2010 From: leepike at gmail.com (Lee Pike) Date: Tue Jan 19 17:23:02 2010 Subject: [Haskell-cafe] Re: Atom bug(?) In-Reply-To: <594c1e831001191413n4a4e72c1v16c086aa1dadaa66@mail.gmail.com> References: <80786448-AB13-4DD4-9201-7A990E5B3C19@gmail.com> <594c1e831001191413n4a4e72c1v16c086aa1dadaa66@mail.gmail.com> Message-ID: <85149F0E-E524-46F6-9422-A3DEE46DCF3F@gmail.com> Tom, Ah, right. > The top-most rule is implied with the compile command. This makes it > appear as if the assignment doesn't belong to a rule, when if fact it > belongs to the implicit top level rule. The top level rule always has > a period of 1. > > Period constraints are only applied to sub-rules, not the current > rule. So to get the behavior I was expecting, I can name everything explicitly. Then the assignment will inherit the period: > example :: Atom () > -- example = period 3 $ do > example = period 3 $ atom "ex" $ do > > a <- word32 "a" 0 > > a <== 21 Lee From doaitse at swierstra.net Tue Jan 19 18:26:18 2010 From: doaitse at swierstra.net (S. Doaitse Swierstra) Date: Tue Jan 19 17:58:34 2010 Subject: [Haskell-cafe] Parsers (Parsec and Iteratee-based Parsers) In-Reply-To: <4B4BAF95.7030108@web.de> References: <4B4B949A.5050309@web.de> <9979e72e1001111448w123e38c1i90ae4276ea800ae3@mail.gmail.com> <4B4BAF95.7030108@web.de> Message-ID: <60C202B9-EA4A-48C8-ABD2-38E10D32BD5D@swierstra.net> On 12 jan 2010, at 00:09, G?nther Schmidt wrote: > Hi John, > > thanks for responding. As I said I've been using Parsec quite a lot, > but wonder if there is a different approach possible/feasible to > parsing. Parsec (2x) isn't an "online" parser, ie, it doesn't > produce a result before the whole parse is completed. > > There is AFAIK one alternative, the uulib, but at first glance it > seemed very elaborate, so I wonder if Oleg's Iteratee offers > something simpler. There is the new uu-parsinglib package, which is simpler and documented (and being worked upon). Doaitse > > I am not in particular looking for some sort of parsec-iteratee- > hybrid, I'd be quite happy with something entirely based on > Iteratee. In the Iteratee package there are 2 sample parsers, one > for TIFF and one for WAVE files. I wish I could say that the > accompanying documentation is sufficient for me to get the idea, > alas it's not. > > G?nther > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From ravi_n at alum.mit.edu Wed Jan 20 00:14:43 2010 From: ravi_n at alum.mit.edu (Ravi Nanavati) Date: Tue Jan 19 23:46:57 2010 Subject: [Haskell-cafe] Fwd: [BostonHaskell] Next meeting: January 21st at MIT (**NEW ROOM** 32G-449) In-Reply-To: <161d443c1001192113x3edd666cqf1e5309bad591681@mail.gmail.com> References: <161d443c1001192113x3edd666cqf1e5309bad591681@mail.gmail.com> Message-ID: <161d443c1001192114r2b70a6afoda88964695918fdb@mail.gmail.com> ---------- Forwarded message ---------- From: Ravi Nanavati Date: Wed, Jan 20, 2010 at 12:13 AM Subject: Next meeting: January 21st at MIT (**NEW ROOM** 32G-449) To: bostonhaskell@googlegroups.com I'm pleased to announce the January meeting of the Boston Area Haskell Users' Group. The meeting has been scheduled for Thursday, January 21st from 7pm to 9pm. Like recent meetings, it will be at MIT. However, it will be in the Patil/Kiva conference room, NOT the CSAIL reading room. That room is 32G-449 (i.e. a room on the 4th floor of the Gates Tower of MIT's Stata Center at 32 Vassar St in Cambridge, MA). My apologies for the late notice - I've been busy recently. This month, Paul Chiusano and Runar Bjarnason will be presenting "Scala for Haskell Programmers". Scala is a statically-typed functional language that targets the JVM and it has a type system that, in its own way, is as unique as Haskell's. This presentation will take up the bulk of the meeting, but if anyone wants to give a Lightning Talk, there is room for that. The January attendance poll is at: http://doodle.com/xnwcec4w4hbh6y65 As always, responding to this poll will help with two things: 1. Getting an idea of what fraction of the Boston-area Haskell community can and can't attend this meeting (to help with future scheduling). 2. Giving me an estimated count of attendees, since I have talked my wife into baking some more goodies and bringing drinks again. By the way, if someone is willing to edit the HaskellWiki page, post to reddit or otherwise publicize the meeting please just go ahead and do that (especially as I'm sending this out on the later side). If you have any questions about the meeting please send them to them BostonHaskell mailing list: bostonhaskell@googlegroups.com or contact me directly. I look forward to seeing many Boston-area Haskellers at the January meeting! Thank you, ?- Ravi Nanavati From ketil at malde.org Wed Jan 20 01:20:07 2010 From: ketil at malde.org (Ketil Malde) Date: Wed Jan 20 00:52:22 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager In-Reply-To: <510545.11108.qm@web31105.mail.mud.yahoo.com> (michael rice's message of "Mon, 18 Jan 2010 13:40:42 -0800 (PST)") References: <510545.11108.qm@web31105.mail.mud.yahoo.com> Message-ID: <878wbt5mco.fsf@malde.org> michael rice writes: > Perhaps. Is there a Linux distro that's more XMonad friendly? I use Ubuntu, in the GDM login screen, I get a drop down menu that includes Xmonad as an option. Even if Fedora doesn't have this, it probably has a "Failsafe" option that will just give you an xterm, from which you can run xmonad manually? -k -- If I haven't seen further, it is by standing in the footprints of giants From Andrejs.Sisojevs at nextmail.ru Wed Jan 20 06:06:07 2010 From: Andrejs.Sisojevs at nextmail.ru (Andrey Sisoyev) Date: Wed Jan 20 05:38:20 2010 Subject: [Haskell-cafe] ANNOUNCE: Cardinality-0.1 Message-ID: <27239964.post@talk.nabble.com> Hi everybody! I developed a new package that you may find handy, when transforming containers. With this package we now have unified ways to make safe transforms "from a -> Maybe (to a)" and "from -> Maybe to" between simple containers like [], Maybe, Identity, Map. Test set that returns all True: ((sContTransT []) :: Maybe (Maybe Int)) == Just Nothing ((sContTrans ()) :: Maybe (Maybe Int)) == Just Nothing ((sContTransT [1]) :: (Maybe (Maybe Int))) == Just (Just 1) ((sContTransT [1, 2]) :: (Maybe (Maybe Int))) == Nothing ((sContTransT $ Just "Hello") :: (Maybe (Identity String))) == Just (Identity "Hello") ((sContTransT ["Hello"]) :: Maybe (Identity String)) == Just (Identity "Hello") ((sContTransT (EmptySet :: EmptySet String)) :: (Maybe [String])) == Just [] ((sContTransT "Hello") :: Maybe (EmptySet Char)) == Nothing ((sContTransT ("key", "elem")) :: Maybe (Map String String)) == Just (singleton "key" "elem") ((sContTrans [("key1", "elem1"), ("key2", "elem2")]) :: Maybe (Map String String)) == Just (fromList [("key1", "elem1"), ("key2", "elem2")]) ((sContTrans (EmptySet :: EmptySet (String, String))) :: Maybe (Map String String)) == Just empty ((sContTrans []) :: Maybe ()) == Just () ((sContTrans (NEL 'H' "i!")) :: Maybe String) == Just "Hi!" -- Data.NeverEmptyList ((sContTrans ()) :: Maybe String) == Just "" ((sContTrans "") :: Maybe (Identity Char)) == Nothing ((sContTrans "Hi!") :: Maybe ()) == Nothing Package is to be found here: http://hackage.haskell.org/package/Cardinality It dances around cardinality - a measure of of the number of elements of the set (container); and cardinality constraint of the container. Cardinality constraints: ** (): 0 elements ** Identity a: 1 element ** (Maybe a): 0..1 elements ** [a]: 0..Infinity elements ** Map k e: 0..Infinity elements ** (a,a,a): 3 elements I also introduced 2 containers (which I found strange not to be in the Prelude): ** data EmptySet a = EmptySet -- (0 elements) ** data NeverEmptyList a = NEL a [a] -- (1..Infinity elements) The package provides all sorts of transformation instances between this types (except for tuples, 3ples, 4ples... I didn't make all transforms fo them - only "list -> (N)ple" and opposites) I tried also to deal with transforms like "container a -> a", "a -> container a" using OverlappingInstances. But failed to approve them - probably due to the lack of experience with this extension. I found them introducing too much unwanted complexity into the reasoning about types. It was the last straw to me, when GHC started to proving me, that unity is not less general then any type variable "a", and demanding tribute of IncoherentInstances. ----------------------------------- Any feedback is appreciated. Best regards, Andrey. -- View this message in context: http://old.nabble.com/ANNOUNCE%3A-Cardinality-0.1-tp27239964p27239964.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From ozgurakgun at gmail.com Wed Jan 20 06:16:56 2010 From: ozgurakgun at gmail.com (Ozgur Akgun) Date: Wed Jan 20 05:49:10 2010 Subject: [Haskell-cafe] cabal install glfw In-Reply-To: <856033f21001191149i1817cc0dmf01acfe303bb3c74@mail.gmail.com> References: <7be1feae1001191046y5245aeacm5ef8433e49669302@mail.gmail.com> <856033f21001191149i1817cc0dmf01acfe303bb3c74@mail.gmail.com> Message-ID: <7be1feae1001200316u4e2f0dacxee1e10dab76f33ae@mail.gmail.com> Sorry, I cannot install GHC 6.12 right now, so I won't be able to try it. Thanks anyway. 2010/1/19 Paul L > The problem you mentioned has long been fixed in the darcs version, > but then there is also another problem: you need GHC 6.12 in order to > compile GLFW for Snow Leopard. Here is a detail description of why > prior versions of GHC fails to work: > http://hackage.haskell.org/trac/ghc/ticket/3522 > > I've just made a new release and bumped GLFW to 0.4.2, you may try it > with GHC 6.12 on Snow Leopard and see if it now works. > > > On 1/19/10, Ozgur Akgun wrote: > > Dear Cafe and Paul, > > > > I am constantly having problems with cabal install in Snow Leopard. Some > I > > solve, some I cannot unfortunately. > > > > When I run > > > > sudo cabal install glfw -v2 > > > > in Snow Leopard, I get the following. > > > > glfw/lib/macosx/macosx_enable.c:1:0: > > error: bad value (apple) for -march= switch > > > > glfw/lib/macosx/macosx_enable.c:1:0: > > error: bad value (apple) for -mtune= switch > > cabal: Error: some packages failed to install: > > GLFW-0.4.1 failed during the building phase. The exception was: > > exit: ExitFailure 1 > > > > > > Regards, > > > > -- > > Ozgur Akgun > > > > > -- > Regards, > Paul Liu > > Yale Haskell Group > http://www.haskell.org/yale > -- Ozgur Akgun -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100120/2ecb94e3/attachment.html From Alistair.Bayley at invesco.com Wed Jan 20 06:20:43 2010 From: Alistair.Bayley at invesco.com (Bayley, Alistair) Date: Wed Jan 20 05:53:02 2010 Subject: [Haskell-cafe] Non-ASCII characters in .cabal files break Haddock? In-Reply-To: <3283f7fe1001191300w75444273yc4a9140b151bc220@mail.gmail.com> References: <3283f7fe1001191300w75444273yc4a9140b151bc220@mail.gmail.com> Message-ID: <125EACD0CAE4D24ABDB4D148C4593DA911026688@GBLONXMB02.corp.amvescap.net> > I recently uploaded a package to Hackage[1], which contains a > non-ASCII character in the .cabal file. That file is encoded with > UTF-8, and it displays fine in Vim, Firefox, and even the Hackage > package landing page. However, Haddock is failing to build it[2] -- > apparently it can't handle UTF-8 encoded text properly. > > In documentation sections, Haddock supports special syntax for > escaping non-ASCII. Is there any equivalent syntax for Cabal files? What happens if you use the Haddock syntax in the cabal file (description field)? It's not even certain that Haddock is choking on UTF8 - it might be some other encoding. The description from the cabal file is written to a temp file, and this is passed to haddock with the --prologue option. In your log output we can see: /usr/local/bin/haddock --use-contents=/package/natural-sort-0.1 --prologue=dist/doc/html/natural-sort/haddock-prolog17177.txt ... haddock: internal Haddock or GHC error: dist/doc/html/natural-sort/haddock-prolog17177.txt: hGetContents: invalid argument (Invalid or incomplete multibyte or wide character) So it is actually hGetContents that is choking on the haddock-prolog17177.txt file. That might well depend on the default encoding for the shell that runs the build. What happens on your own machine? Alistair ***************************************************************** Confidentiality Note: The information contained in this message, and any attachments, may contain confidential and/or privileged material. It is intended solely for the person(s) or entity to which it is addressed. Any review, retransmission, dissemination, or taking of any action in reliance upon this information by persons or entities other than the intended recipient(s) is prohibited. If you received this in error, please contact the sender and delete the material from any computer. ***************************************************************** From vandijk.roel at gmail.com Wed Jan 20 06:20:55 2010 From: vandijk.roel at gmail.com (Roel van Dijk) Date: Wed Jan 20 05:53:10 2010 Subject: [Haskell-cafe] Conditional code for Haddock Message-ID: I want to generate documentation for the following code snippet: > import qualified Data.ByteString as BS ( ByteString, length ) > > -- | Foo 'BS.empty' equals 0 > foo ? BS.ByteString ? Int > foo = BS.length Because I do not explicitly import BS.empty haddock will not generate a nice link. I can fix it by adding: > import qualified Data.ByteString as BS ( empty ) But now the compiler rightly warns me: > Warning: Imported from `Data.ByteString' but not used: `BS.empty' There is a ticket related to this problem [1], but I do not think making haddock 'magically' find BS.empty is the right answer. What I would like to do is: > #ifdef __DOC__ > import qualified Data.ByteString as BS ( empty ) > #endif Because I use additional symbols in my comments it feels natural to also have special imports for them. I know that cabal used to define the __HADDOCK__ macro. Is it possible to manually define a preprocessor macro when haddock is run? Perhaps an equivalent to ghc-options: haddock-options? Ideally I want only have to add the following to my .cabal file: > haddock-options: -D__DOC__ Regards, Roel van Dijk 1 - http://trac.haskell.org/haddock/ticket/78 From daniel.is.fischer at web.de Wed Jan 20 06:42:13 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Jan 20 06:16:11 2010 Subject: [Haskell-cafe] Conditional code for Haddock In-Reply-To: References: Message-ID: <201001201242.14133.daniel.is.fischer@web.de> Am Mittwoch 20 Januar 2010 12:20:55 schrieb Roel van Dijk: > I want to generate documentation for the following code snippet: > > import qualified Data.ByteString as BS ( ByteString, length ) > > > > -- | Foo 'BS.empty' equals 0 > > foo ? BS.ByteString ? Int > > foo = BS.length > > Because I do not explicitly import BS.empty haddock will not generate > a nice link. > > I can fix it by adding: > > import qualified Data.ByteString as BS ( empty ) > > But now the compiler rightly warns me: > > Warning: Imported from `Data.ByteString' but not used: `BS.empty' > > There is a ticket related to this problem [1], but I do not think making > haddock 'magically' find BS.empty is the right answer. What I would like > to > > do is: > > #ifdef __DOC__ > > import qualified Data.ByteString as BS ( empty ) > > #endif > > Because I use additional symbols in my comments it feels natural to also > have special imports for them. > > I know that cabal used to define the __HADDOCK__ macro. Is it possible > to manually define a preprocessor macro when haddock is run? Perhaps an > equivalent to ghc-options: haddock-options? Doesn't haddock define __HADDOCK__ by itself? I would've thought import qualified Data.ByteString as Bs ( ByteString , length #ifdef __HADDOCK__ , empty #endif ) should work. > > Ideally I want only have to add the following to my .cabal file: > > haddock-options: -D__DOC__ > > Regards, > Roel van Dijk > > > 1 - http://trac.haskell.org/haddock/ticket/78 From leather at cs.uu.nl Wed Jan 20 06:57:34 2010 From: leather at cs.uu.nl (Sean Leather) Date: Wed Jan 20 06:30:07 2010 Subject: [Haskell-cafe] Conditional code for Haddock In-Reply-To: <201001201242.14133.daniel.is.fischer@web.de> References: <201001201242.14133.daniel.is.fischer@web.de> Message-ID: <3c6288ab1001200357q3a84815ar8ca6ee83666d63e1@mail.gmail.com> > Doesn't haddock define __HADDOCK__ by itself? > > I would've thought > > import qualified Data.ByteString as Bs > ( ByteString > , length > #ifdef __HADDOCK__ > , empty > #endif > ) > > should work. > I did some conditional Haddocking in EMGM. See, for example: http://hackage.haskell.org/packages/archive/emgm/0.3.1/doc/html/src/Generics-EMGM-Data-Bool.html Sean -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100120/915765ee/attachment.html From vandijk.roel at gmail.com Wed Jan 20 07:40:20 2010 From: vandijk.roel at gmail.com (Roel van Dijk) Date: Wed Jan 20 07:12:33 2010 Subject: [Haskell-cafe] Conditional code for Haddock In-Reply-To: <201001201242.14133.daniel.is.fischer@web.de> References: <201001201242.14133.daniel.is.fischer@web.de> Message-ID: > Doesn't haddock define __HADDOCK__ by itself? That appears to be a common misconception. The discussion on this ticket [1] indicates that haddock does *not* define __HADDOCK__. So I can not rely on it being defined. Therefore I would like to define it myself, but only in the case that haddock is being run on my code. 1 - http://trac.haskell.org/haddock/ticket/76 From ross at soi.city.ac.uk Wed Jan 20 09:15:42 2010 From: ross at soi.city.ac.uk (Ross Paterson) Date: Wed Jan 20 08:48:27 2010 Subject: [Haskell-cafe] Non-ASCII characters in .cabal files break Haddock? In-Reply-To: <3283f7fe1001191300w75444273yc4a9140b151bc220@mail.gmail.com> References: <3283f7fe1001191300w75444273yc4a9140b151bc220@mail.gmail.com> Message-ID: <20100120141542.GA11874@soi.city.ac.uk> On Tue, Jan 19, 2010 at 01:00:07PM -0800, John Millikin wrote: > I recently uploaded a package to Hackage[1], which contains a > non-ASCII character in the .cabal file. That file is encoded with > UTF-8, and it displays fine in Vim, Firefox, and even the Hackage > package landing page. However, Haddock is failing to build it[2] -- > apparently it can't handle UTF-8 encoded text properly. It seems that openTempFile writes the text without any encoding (#3832). Haddock quite reasonably fails because it expects encoded text. > In documentation sections, Haddock supports special syntax for > escaping non-ASCII. Is there any equivalent syntax for Cabal files? The Description field is haddock markup, so that should be a workaround. (or you could use more naive spelling) From nowgate at yahoo.com Wed Jan 20 09:42:44 2010 From: nowgate at yahoo.com (michael rice) Date: Wed Jan 20 09:14:56 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager In-Reply-To: <878wbt5mco.fsf@malde.org> Message-ID: <766698.12061.qm@web31108.mail.mud.yahoo.com> Hi Ketil, I was just looking around and found this: http://xwinman.org/ No mention of XMonad here, even under the "Other" category. I got it running but it became unresponsive as soon as I deleted a window, and instead of tiling newly opened windows it just displayed them in the top left corner, obscuring what was already there (possibly the way it's supposed to work?). But the XMonad video I watched on YouTube looked interesting enough to pursue it further, so I'm in research mode. Thanks, Michael --- On Wed, 1/20/10, Ketil Malde wrote: From: Ketil Malde Subject: Re: [Haskell-cafe] Having a look at XMonad window manager To: "michael rice" Cc: "Ivan Lazar Miljenovic" , haskell-cafe@haskell.org Date: Wednesday, January 20, 2010, 1:20 AM michael rice writes: > Perhaps. Is there a Linux distro that's more XMonad friendly? I use Ubuntu, in the GDM login screen, I get a drop down menu that includes Xmonad as an option.? Even if Fedora doesn't have this, it probably has a "Failsafe" option that will just give you an xterm, from which you can run xmonad manually? -k -- If I haven't seen further, it is by standing in the footprints of giants -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100120/97652dfd/attachment.html From briand at aracnet.com Wed Jan 20 10:15:07 2010 From: briand at aracnet.com (Brian Denheyer) Date: Wed Jan 20 09:47:20 2010 Subject: [Haskell-cafe] formatTime doesn't work with local time ?? Message-ID: <20100120071507.2648226f@windy.deldotd.com> My error: Couldn't match expected type `T.UTCTime' against inferred type `T.LocalTime' In the second argument of `formatTime', namely `date' In the expression: formatTime "%Y/%m/%e %k:%M:%S" date But the docs have LocalTime listed as one of the FormatTime instances: Instances FormatTime Day FormatTime UTCTime FormatTime TimeZone FormatTime TimeOfDay FormatTime ZonedTime FormatTime LocalTime ? Brian From vandijk.roel at gmail.com Wed Jan 20 10:17:30 2010 From: vandijk.roel at gmail.com (Roel van Dijk) Date: Wed Jan 20 09:49:43 2010 Subject: [Haskell-cafe] Conditional code for Haddock In-Reply-To: <3c6288ab1001200357q3a84815ar8ca6ee83666d63e1@mail.gmail.com> References: <201001201242.14133.daniel.is.fischer@web.de> <3c6288ab1001200357q3a84815ar8ca6ee83666d63e1@mail.gmail.com> Message-ID: On Wed, Jan 20, 2010 at 12:57 PM, Sean Leather wrote: > I did some conditional Haddocking in EMGM. See, for example: > http://hackage.haskell.org/packages/archive/emgm/0.3.1/doc/html/src/Generics-EMGM-Data-Bool.html At first I didn't see what you did differently. Until I checked your Setup.lhs. It does exactly what I want! Plus a few other things which I am going to borrow (runtests hook, nolib flag and hpc program coverage). Thank you. From will_n48 at yahoo.com Wed Jan 20 10:42:29 2010 From: will_n48 at yahoo.com (Will Ness) Date: Wed Jan 20 10:15:05 2010 Subject: [Haskell-cafe] Re: Why no merge and listDiff? References: <61f84eff1001171254pddefd6eo57943727b01d7cb2@mail.gmail.com> Message-ID: Derek Elkins gmail.com> writes: > > On Sun, Jan 17, 2010 at 2:22 PM, Will Ness yahoo.com> wrote: > > Hello cafe, > > > > I wonder, if we have List.insert and List.union, why no List.merge (:: Ord a => > > [a] -> [a] -> [a]) and no List.minus ? These seem to be pretty general > > operations. > > Presumably by List.minus you mean the (\\) function in Data.List. No, it has to search its second list over and over from the start, to be able to deal with unordered lists, so its performance can't be good. > You > probably also want to look at the package data-ordlist on hackage > (http://hackage.haskell.org/packages/archive/data-ordlist/0.0.1/doc/html/Data- OrdList.html) > which represents sets and bags as ordered lists and has all of the > operations you mention. I did, thanks again! Although, that package deals with non-decreasing lists, i.e. lists with multiples possibly. As such, its operations produce non- decreasing lists, i.e. possibly having multiples too. I meant strictly increasing ordered lists, without multiples, for which the two operations, 'merge' and 'minus', would also have to produce like lists, i.e strictly increasing, without multiples. I guess the first variety is more appropriate for bags, and the second one - for sets. The two would have to be de-conflated for that. (?) From briand at aracnet.com Wed Jan 20 10:42:56 2010 From: briand at aracnet.com (Brian Denheyer) Date: Wed Jan 20 10:15:13 2010 Subject: [Haskell-cafe] formatTime doesn't work with local time ?? In-Reply-To: <20100120071507.2648226f@windy.deldotd.com> References: <20100120071507.2648226f@windy.deldotd.com> Message-ID: <20100120074256.3061b16e@windy.deldotd.com> On Wed, 20 Jan 2010 07:15:07 -0800 Brian Denheyer wrote: > My error: > > Couldn't match expected type `T.UTCTime' > against inferred type `T.LocalTime' > In the second argument of `formatTime', namely `date' > In the expression: formatTime "%Y/%m/%e %k:%M:%S" date > Nevermind... I had defined : formatTime = T.formatTime defaultTimeLocale which used the T.formatTime for the UTCTime instance. The following T.formatTime defaultTimeLocale "%Y/%m/%e %k:%M:%S" date works just fine (date is Localtime) Brian From daniel.is.fischer at web.de Wed Jan 20 10:59:15 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Jan 20 10:33:13 2010 Subject: [Haskell-cafe] formatTime doesn't work with local time ?? In-Reply-To: <20100120074256.3061b16e@windy.deldotd.com> References: <20100120071507.2648226f@windy.deldotd.com> <20100120074256.3061b16e@windy.deldotd.com> Message-ID: <201001201659.15194.daniel.is.fischer@web.de> Am Mittwoch 20 Januar 2010 16:42:56 schrieb Brian Denheyer: > On Wed, 20 Jan 2010 07:15:07 -0800 > > Brian Denheyer wrote: > > My error: > > > > Couldn't match expected type `T.UTCTime' > > against inferred type `T.LocalTime' > > In the second argument of `formatTime', namely `date' > > In the expression: formatTime "%Y/%m/%e %k:%M:%S" date > > Nevermind... > > I had defined : > > formatTime = T.formatTime defaultTimeLocale > > which used the T.formatTime for the UTCTime instance. The following > > T.formatTime defaultTimeLocale "%Y/%m/%e %k:%M:%S" date > > works just fine (date is Localtime) > > Brian Monomorphism restriction, I presume? From leather at cs.uu.nl Wed Jan 20 11:39:39 2010 From: leather at cs.uu.nl (Sean Leather) Date: Wed Jan 20 11:12:15 2010 Subject: [Haskell-cafe] Conditional code for Haddock In-Reply-To: References: <201001201242.14133.daniel.is.fischer@web.de> <3c6288ab1001200357q3a84815ar8ca6ee83666d63e1@mail.gmail.com> Message-ID: <3c6288ab1001200839v649e549cx4a4d3f2841caa282@mail.gmail.com> On Wed, Jan 20, 2010 at 16:17, Roel van Dijk wrote: > On Wed, Jan 20, 2010 at 12:57 PM, Sean Leather wrote: > > I did some conditional Haddocking in EMGM. See, for example: > > > http://hackage.haskell.org/packages/archive/emgm/0.3.1/doc/html/src/Generics-EMGM-Data-Bool.html > > At first I didn't see what you did differently. Until I checked your > Setup.lhs. It does exactly what I want! Plus a few other things which > I am going to borrow (runtests hook, nolib flag and hpc program > coverage). > I'm glad somebody else can make use of that stuff. Regards, Sean -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100120/b3b0815b/attachment.html From nowgate at yahoo.com Wed Jan 20 12:15:44 2010 From: nowgate at yahoo.com (michael rice) Date: Wed Jan 20 11:47:56 2010 Subject: [Haskell-cafe] Having a look at XMonad window manager In-Reply-To: <766698.12061.qm@web31108.mail.mud.yahoo.com> Message-ID: <898485.76080.qm@web31102.mail.mud.yahoo.com> It seems I was doing MUCH more than I needed to do to have a look at XMonad in action. I went back and created a .xsession file with just one line: xmonad I then disabled Nautilus (unchecked show desktop) and started xmonad as follows killall metacity; xmonad & Everything now seems to work fine. Impressive app! Thanks all, Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100120/73f0a1bd/attachment.html From gue.schmidt at web.de Wed Jan 20 12:21:50 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Wed Jan 20 11:54:31 2010 Subject: [Haskell-cafe] HTML - based GUIs - follow up Message-ID: <4B573BAE.5010907@web.de> Hello, in my first post on this subject from 01-10-10 I asked for opinions on using HTML to create the gui part of a desktop app instead of using Gtkhs or WxHaskell. The responses were encouraging. It occurred to me that I might now even need to run an actual webserver (happs for instance) but that I could use either Webkit or a com interface to Internet Explorer to control the browser. When it opens, register event sinks and so on. Still that involves a lot of boilerplate code. I have seen examples of *formlets* and I'm impressed, the wiring is certainly taken care of. My question is: do formlets only work server based or is it also possible to use formlet sans happs? G?nther From colin at colina.demon.co.uk Wed Jan 20 12:30:11 2010 From: colin at colina.demon.co.uk (Colin Paul Adams) Date: Wed Jan 20 12:02:25 2010 Subject: [Haskell-cafe] HTML - based GUIs - follow up In-Reply-To: <4B573BAE.5010907@web.de> (=?utf-8?Q?=22G=C3=BCnther?= Schmidt"'s message of "Wed, 20 Jan 2010 18:21:50 +0100") References: <4B573BAE.5010907@web.de> Message-ID: >>>>> "G?nther" == G?nther Schmidt writes: G?nther> My question is: do formlets only work server based or is it G?nther> also possible to use formlet sans happs? Yes (I think) and yes. -- Colin Adams Preston Lancashire From Christian.Maeder at dfki.de Wed Jan 20 12:35:32 2010 From: Christian.Maeder at dfki.de (Christian Maeder) Date: Wed Jan 20 12:07:45 2010 Subject: [Haskell-cafe] Re: Why no merge and listDiff? In-Reply-To: References: <61f84eff1001171254pddefd6eo57943727b01d7cb2@mail.gmail.com> Message-ID: <4B573EE4.4010807@dfki.de> Will Ness schrieb: > I meant strictly increasing ordered lists, without multiples, for which the two > operations, 'merge' and 'minus', would also have to produce like lists, i.e > strictly increasing, without multiples. Why don't you use directly Data.Set? > I guess the first variety is more appropriate for bags, and the second one - > for sets. The two would have to be de-conflated for that. (?) There are also bags aka multisets: http://hackage.haskell.org/package/multiset Cheers Christian From tux_rocker at reinier.de Wed Jan 20 12:49:49 2010 From: tux_rocker at reinier.de (Reinier Lamers) Date: Wed Jan 20 12:22:16 2010 Subject: [Haskell-cafe] darcs 2.4 beta 2 release Message-ID: <201001201850.01280.tux_rocker@reinier.de> Hi all, The darcs team would like to announce the immediate availability of darcs 2.4 beta 2. darcs 2.4 will contain many improvements and bugfixes compared to darcs 2.3.1. Highlights are the fast index-based diffing which is now used by all darcs commands, and the experimental interactive hunk editing. This beta is your chance to test-drive these improvements and make darcs even better. The easiest way to install darcs is using the Haskell Platform [1]. If you have installed the Haskell Platform or cabal-install, you can install this beta release by doing: $ cabal update $ cabal install --reinstall darcs-beta Alternatively, you can download the tarball from http://darcs.net/releases/darcs-2.3.98.2.tar.gz , and build it by hand as explained in the README file. Interactive hunk editing ------------------------ The interactive hunk editing feature is included in this beta. However, be aware that we are not entirely sure that the user interface in this version is ready yet. You're welcome to try it out, but be prepared for a learning curve that's somewhat steeper than usual for darcs. To try out interactive hunk editing, press 'e' when you are prompted with a hunk patch by 'darcs record'. You will then be shown an editor screen in which you can edit the contents of the hunk as darcs should consider them to have been before and after the hunk patch you edit. You can edit the state you want to record between the last two "===" lines. You can find more information about the hunk editing feature on http://wiki.darcs.net/HunkEditor . Reporting bugs -------------- If you have an issue with darcs 2.4 beta 2, you can report it via the web on http://bugs.darcs.net/ . You can also report bugs by email to bugs@darcs.net. What's New ---------- A list of important changes since 2.3.1 is as follows (please let me know if there's something you miss!): * Use fast index-based diffing everywhere (Petr) * Interactive patch splitting (Ganesh) * An 'optimize --upgrade' option to convert to hashed format in-place (Eric) * Hunk matching (Kamil Dworakowski, tat.wright) * Progress reporting is no longer deceptive (Roman) * A 'remove --recursive' option to remove a directory tree from revision control (Roman) * 'show files' accepts arguments to show a subset of tracked files (Luca) * A '--remote-darcs' flag for pushing to a host where darcs isn't called darcs * Many miscellaneous Windows improvements (Salvatore, Petr and others) * 'darcs send' now mentions the repository name in the email body (Joachim) * Handle files with boring names in the repository correctly (Petr) * Fix parsing of .authorspellings file (Tom??) * Various sane new command-line option names (Florent) * Remove the '--checkpoint' option (Petr) * Use external libraries for all UTF-8 handling (Eric, Reinier) * Use the Haskell zlib package exclusively for compression (Petr) A list of issues resolved since 2.3.1: * 183: do not sort changes --summary output * 223: add --remote-darcs flag to specify name of remote darcs executable * 291: provide (basic) interactive patch splitting * 540: darcs remove --recursive * 835: 'show files' with arguments * 1122: get --complete should not offer to create a lazy repository * 1216: list Match section in ToC * 1224: refuse to convert a repo that's already in darcs-2 format * 1300: logfile deleted on unsucessful record * 1308: push should warn about unpulled patches *before* patch-selection * 1336: sane error message on --last "" (empty string to numbers parser) * 1362: mention repo name in mail send body * 1377: getProgname for local darcs instances * 1392: use parsec to parse .authorspelling * 1424: darcs get wrongly reports "using lazy repository" if you ctrl-c old-fashioned get * 1447: different online help for send/apply --cc * 1488: fix crash in whatsnew when invoked in non-tracked directory * 1548: show contents requires at least one argument * 1554: allow opt-out of -threaded (fix ARM builds) * 1563: official thank-you page * 1578: don't put newlines in the Haskeline prompts * 1583: on darcs get, suggest upgrading source repo to hashed * 1584: provide optimize --upgrade command * 1588: add --skip-conflicts option * 1594: define PREPROCHTML in makefile * 1620: make amend leave a log file when it should * 1636: hunk matching * 1643: optimize --upgrade should do optimize * 1652: suggest cabal update before cabal install * 1659: make restrictBoring take recorded state into account * 1677: create correct hashes for empty directories in index * 1681: preserve log on amend failure * 1709: fix short version of progress reporting * 1712: correctly report number of patches to pull * 1720: fix cabal haddock problem * 1731: fix performance regression in check and repair Kind Regards, the darcs release manager, Reinier Lamers [1]: You can download the Haskell platform from http://hackage.haskell.org/platform/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: This is a digitally signed message part. Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100120/0121ba83/attachment.bin From tomahawkins at gmail.com Wed Jan 20 13:09:12 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Wed Jan 20 12:41:29 2010 Subject: [Haskell-cafe] Extracting all pruned sub trees Message-ID: <594c1e831001201009g299f5116we81b8d255608b147@mail.gmail.com> I'm looking for an elegant way to generate a list of all pruned trees where each pruned tree has one of its leaves removed. Something like this: data Leaf = ... data Tree = Leaf Leaf | Branch [Tree] prunedSubTrees :: Tree -> [(Leaf, Tree)] -- [(the leaf removed, the pruned tree)] Any suggestions? From lemming at henning-thielemann.de Wed Jan 20 14:21:27 2010 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Wed Jan 20 13:53:43 2010 Subject: [Haskell-cafe] Lambda's In-Reply-To: References: Message-ID: On Thu, 31 Dec 2009, Henk-Jan van Tuyl wrote: > I love lambda's: > http://hawtness.com/2009/12/30/wtf-girl-photo-more-reasons-why-half-life-is-awesome/ cute ... I'm not sharing the collective rejection. A remark would be ok. Although I looked up the meaning of NSFW only after following your link. :-) From will_n48 at yahoo.com Wed Jan 20 14:34:15 2010 From: will_n48 at yahoo.com (Will Ness) Date: Wed Jan 20 14:07:09 2010 Subject: [Haskell-cafe] Re: Why no merge and listDiff? References: <61f84eff1001171254pddefd6eo57943727b01d7cb2@mail.gmail.com> <4B573EE4.4010807@dfki.de> Message-ID: Christian Maeder dfki.de> writes: > Will Ness schrieb: > > I meant strictly increasing ordered lists, without multiples, for which the two > > operations, 'merge' and 'minus', would also have to produce like lists, i.e > > strictly increasing, without multiples. > > Why don't you use directly Data.Set? It says it's based on size balanced Trees? I initially wondered why no such fundamental operations as merge and minus for _lists_, in the stadard libraries? Also, its to/from list conversions are O(n), so probably won't work for infinite lists. I was told the trend is to move specifics to hackage packages, but I wonder why shouldn't such fundamental operations be just included in standard Data.List? > > I guess the first variety is more appropriate for bags, and the second one > > - for sets. The two would have to be de-conflated for that. (?) > > There are also bags aka multisets: > http://hackage.haskell.org/package/multiset it's too seems to be based on trees. Data.Ordlist seems to be a good match, except for its conflation of ascending/non-decreasing lists under one "ordered" category (i.e. sets/bags distinction). From ndmitchell at gmail.com Wed Jan 20 14:55:38 2010 From: ndmitchell at gmail.com (Neil Mitchell) Date: Wed Jan 20 14:27:51 2010 Subject: [Haskell-cafe] Poor man's generic programming In-Reply-To: <1376467600.20100119224841@gmail.com> References: <4B5218CE.5090902@henning-thielemann.de> <404396ef1001181156u7a805a1avf264ad4a54c8ceb7@mail.gmail.com> <1288671433.20100119001536@gmail.com> <404396ef1001191115r48790232y42165bfc622b5897@mail.gmail.com> <1376467600.20100119224841@gmail.com> Message-ID: <404396ef1001201155o35e0a7delf69a1735ddf5323a@mail.gmail.com> Hi Bulat, The intention was always that the manual should be an up-to-date version that contains everything people need to use the library, but not the internal details. The paper was revised in to my thesis chapter, which is probably the best description of the internals of Uniplate. The thesis chapter is reasonably complete, but the manual isn't - I'll move some of the interesting material across - particularly on Biplate. Thanks, Neil 2010/1/19 Bulat Ziganshin : > Hello Neil, > > Tuesday, January 19, 2010, 10:15:15 PM, you wrote: > >>> can you give a permission to translate http://community.haskell.org/~ndm/darcs/uniplate/uniplate.htm >>> to Russian for http://fprog.ru/ online functional programming journal? > >> Yes, that sounds great. However, I'm currently not a particular fan of >> the manual in it's current state - it isn't that well written and some >> bits need expanding. How about I revamp it, then let you know? I can >> probably do it within the next few weeks. > > it would be even better. i just finished reading your paper - tutorial > doesn't emphasize some details i've found there, in particular > restrictions of Uniplate and how these are particularly overcomed by > BiPlate. i.e. it may be derived from tutorial but wasn't obvious for > me before i've read the paper > > > -- > Best regards, > ?Bulat ? ? ? ? ? ? ? ? ? ? ? ? ? ?mailto:Bulat.Ziganshin@gmail.com > > From paul at cogito.org.uk Wed Jan 20 17:32:22 2010 From: paul at cogito.org.uk (Paul Johnson) Date: Wed Jan 20 17:04:38 2010 Subject: [Haskell-cafe] Please help me debug my arrow In-Reply-To: <4B54C595.6000105@cogito.org.uk> References: <4B54C595.6000105@cogito.org.uk> Message-ID: <4B578476.4010502@cogito.org.uk> On 18/01/10 20:33, Paul Johnson wrote: > > I'm going nuts looking at this. Can anyone see what I'm doing wrong? > I found the problem eventually. Its a scoping problem with "rt1" in the (.) function when composeSP gets called recursively. From briand at aracnet.com Thu Jan 21 01:10:07 2010 From: briand at aracnet.com (Brian Denheyer) Date: Thu Jan 21 00:42:19 2010 Subject: [Haskell-cafe] hsql won't install due to system.time Message-ID: <20100120221007.75dfede9@windy.deldotd.com> Database/HaskellDB/HSQL.hs:25:7: Could not find module `System.Time': it is a member of the hidden package `old-time-1.0.0.3' it is a member of the hidden package `old-time-1.0.0.2' Use -v to see a list of the files searched for. old-time-1.0.0.2 is installed (via cabal). Suggestions on how to fix this or which haskell db (for sqlite3) package will actually install greatly appreciated. I get a lot of failures in hackages which involve that dreaded "hidden package" message. Anybody care to enlighten us mere mortals as to why it seems to occur so frequently (at least for me). Brian From malcolm.wallace at cs.york.ac.uk Thu Jan 21 04:01:01 2010 From: malcolm.wallace at cs.york.ac.uk (Malcolm Wallace) Date: Thu Jan 21 03:33:11 2010 Subject: [Haskell-cafe] hsql won't install due to system.time In-Reply-To: <20100120221007.75dfede9@windy.deldotd.com> References: <20100120221007.75dfede9@windy.deldotd.com> Message-ID: <2F6595B1-2A5E-4EA7-8BF2-8BE0D793B034@cs.york.ac.uk> On 21 Jan 2010, at 06:10, Brian Denheyer wrote: > Database/HaskellDB/HSQL.hs:25:7: > Could not find module `System.Time': > it is a member of the hidden package `old-time-1.0.0.3' > it is a member of the hidden package `old-time-1.0.0.2' > > Suggestions on how to fix this ... The easiest workaround is to change your local copy of the .cabal file for hsql, modifying the build-depends line to make a more precise dependency on old-time, e.g. build-depends: old-time-1.0.0.2 If you are using cabal install, then you may need to take a couple of extra steps in order to be able to edit the .cabal file, e.g. cabal fetch hsql cd hsql-1.7.1 cabal install Regards, Malcolm From RafaelGCPP.Linux at gmail.com Thu Jan 21 04:48:18 2010 From: RafaelGCPP.Linux at gmail.com (Rafael Gustavo da Cunha Pereira Pinto) Date: Thu Jan 21 04:20:31 2010 Subject: [Haskell-cafe] Haskell Platform Message-ID: <351ff25e1001210148i1f71a093n5fe8d615973ac2d0@mail.gmail.com> Hi folks, How are the efforts on Haskell Platform for GHC 6.12.1 going? I'm considering joining those brave heroes. Where can I apply? Rafael Gustavo da Cunha Pereira Pinto -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100121/1a98d39b/attachment.html From marco-oweber at gmx.de Thu Jan 21 05:36:42 2010 From: marco-oweber at gmx.de (Marc Weber) Date: Thu Jan 21 05:08:55 2010 Subject: [Haskell-cafe] hsql won't install due to system.time In-Reply-To: <20100120221007.75dfede9@windy.deldotd.com> References: <20100120221007.75dfede9@windy.deldotd.com> Message-ID: <1264070115-sup-444@nixos> Hi Brian hsql is compatibel with most recent ghc yet. You can get patches for the .cabal files here: http://github.com/MarcWeber/haskell-nix-overlay/tree/master/patches/ However the Exception handling has to be rewritten as well. I wanted to fix this issues for weeks - No time. Let me know if you start working on this. Marc Weber From gue.schmidt at web.de Thu Jan 21 08:22:47 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Thu Jan 21 07:55:27 2010 Subject: [Haskell-cafe] GUI: Custom widgets - wxHaskell or gtk2hs ? Message-ID: <4B585527.8050502@web.de> Hi, I need to create a custom widget and I wonder which of the above gui-toolkits makes that easier. G?nther From ozgurakgun at gmail.com Thu Jan 21 08:24:54 2010 From: ozgurakgun at gmail.com (Ozgur Akgun) Date: Thu Jan 21 07:57:05 2010 Subject: [Haskell-cafe] Haskell Platform In-Reply-To: <351ff25e1001210148i1f71a093n5fe8d615973ac2d0@mail.gmail.com> References: <351ff25e1001210148i1f71a093n5fe8d615973ac2d0@mail.gmail.com> Message-ID: <7be1feae1001210524u27d52088mf1e56b45d5679a80@mail.gmail.com> And for Mac as well, please :) 2010/1/21 Rafael Gustavo da Cunha Pereira Pinto > Hi folks, > > How are the efforts on Haskell Platform for GHC 6.12.1 going? > > I'm considering joining those brave heroes. Where can I apply? > > > Rafael Gustavo da Cunha Pereira Pinto > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- Ozgur Akgun -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100121/68511b31/attachment.html From alistair at abayley.org Thu Jan 21 08:33:38 2010 From: alistair at abayley.org (Alistair Bayley) Date: Thu Jan 21 08:05:47 2010 Subject: [Haskell-cafe] Haskell Platform In-Reply-To: <351ff25e1001210148i1f71a093n5fe8d615973ac2d0@mail.gmail.com> References: <351ff25e1001210148i1f71a093n5fe8d615973ac2d0@mail.gmail.com> Message-ID: <79d7c4981001210533k41cffd06t21d16141abbe3792@mail.gmail.com> > How are the efforts on Haskell Platform for GHC 6.12.1 going? > > I'm considering joining those brave heroes. Where can I apply? Joining the mailing list would be a good place to start: http://projects.haskell.org/cgi-bin/mailman/listinfo/haskell-platform Alistair From frank at geoinfo.tuwien.ac.at Thu Jan 21 08:51:20 2010 From: frank at geoinfo.tuwien.ac.at (Andrew U. Frank) Date: Thu Jan 21 08:23:33 2010 Subject: [Haskell-cafe] haddock - 'could not find link destination" Message-ID: <201001211451.20388.frank@geoinfo.tuwien.ac.at> i try to use haddock for documentation, but have no success. no output is produced. i assume i make some stupid mistake (not having used haddock before) help is appreciated! thank you andrew ------------------------------- i get the following error: $ haddock Hadtest2.hs Warning: Main: could not find link destinations for: GHC.Types.Int GHC.Base.String Hadtest2.hs is a simplistic test program with some parts copied from the haddock manual: module Main (square, this) where -- | a constant this :: String this = "this" -- |The 'square' function squares an integer. square :: Int -> Int square x = x * x main = do putStrLn $ "test " ++ show (square 4) return () -- -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100121/9f00e955/attachment.html From daniel.is.fischer at web.de Thu Jan 21 09:06:56 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Thu Jan 21 08:40:57 2010 Subject: [Haskell-cafe] haddock - 'could not find link destination" In-Reply-To: <201001211451.20388.frank@geoinfo.tuwien.ac.at> References: <201001211451.20388.frank@geoinfo.tuwien.ac.at> Message-ID: <201001211506.56916.daniel.is.fischer@web.de> Am Donnerstag 21 Januar 2010 14:51:20 schrieb Andrew U. Frank: > i try to use haddock for documentation, but have no success. no output > is produced. i assume i make some stupid mistake (not having used > haddock before) > > help is appreciated! thank you > andrew > ------------------------------- > > i get the following error: > > $ haddock Hadtest2.hs > Warning: Main: could not find link destinations for: > GHC.Types.Int GHC.Base.String > That is not an error, haddock just tells you that it doesn't know where the docs for base are. If you want to run haddock by hand, and that it links the docs, you must pass a lot of --read-interface=xxx.haddock flags on the command line. Also, to generate output, you have to tell it which sort of output, AFAIR, -h produces HTML, another option is --hoogle. But I find it easier to let Cabal deal with haddock, make a Cabal package, runghc ./Setup.hs configure --user --prefix=$HOME runghc ./Setup.hs haddock --hyperlink-source From briand at aracnet.com Thu Jan 21 09:51:13 2010 From: briand at aracnet.com (Brian Denheyer) Date: Thu Jan 21 09:23:23 2010 Subject: [Haskell-cafe] hsql won't install due to system.time In-Reply-To: <1264070115-sup-444@nixos> References: <20100120221007.75dfede9@windy.deldotd.com> <1264070115-sup-444@nixos> Message-ID: <20100121065113.71a62cd5@windy.deldotd.com> On Thu, 21 Jan 2010 11:36:42 +0100 Marc Weber wrote: > Hi Brian > > hsql is compatibel with most recent ghc yet. Well I am using 6.10.4, so should I use a patched version, or simply apply the fixes which Malcolm provided ? > > You can get patches for the .cabal files here: > http://github.com/MarcWeber/haskell-nix-overlay/tree/master/patches/ > > However the Exception handling has to be rewritten as well. > I wanted to fix this issues for weeks - No time. Are you waiting to get this done before releasing a new version to Hackage ? > > Let me know if you start working on this. You _really_ don't want me working on anything, trust me. Hopefully some fine Haskell hacker who would also like to use hsql will volunteer. Brian From chris at eidhof.nl Thu Jan 21 09:58:08 2010 From: chris at eidhof.nl (Chris Eidhof) Date: Thu Jan 21 09:30:18 2010 Subject: [Haskell-cafe] HTML - based GUIs - follow up In-Reply-To: References: <4B573BAE.5010907@web.de> Message-ID: Formlets themselves don't require a server. You can use them from the commandline. However, formlets do have a limitation: they are not interactive. I would really like a library that does something like formlets (compositional web forms) but with a FRP-style of writing. A contrived example: Suppose I have a page with a label that displays a number, and a slider. When I change the slider, the number in the label has to change accordingly. The example above is currently not possible with formlets. -chris On 20 jan 2010, at 18:30, Colin Paul Adams wrote: >>>>>> "G?nther" == G?nther Schmidt writes: > > G?nther> My question is: do formlets only work server based or is it > G?nther> also possible to use formlet sans happs? > > Yes (I think) and yes. > -- > Colin Adams > Preston Lancashire > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From marco-oweber at gmx.de Thu Jan 21 10:03:59 2010 From: marco-oweber at gmx.de (Marc Weber) Date: Thu Jan 21 09:36:11 2010 Subject: [Haskell-cafe] hsql won't install due to system.time In-Reply-To: <20100121065113.71a62cd5@windy.deldotd.com> References: <20100120221007.75dfede9@windy.deldotd.com> <1264070115-sup-444@nixos> <20100121065113.71a62cd5@windy.deldotd.com> Message-ID: <1264086024-sup-3360@nixos> Hi Brian > You _really_ don't want me working on anything, trust me. Hopefully > some fine Haskell hacker who would also like to use hsql will volunteer. You make me smile. I learned Haskell for the same reason. "Don't trust me but trust Haskell" *kidding* If you want to work on it I can help you getting started. We both will benefit. You can contact me on irc.freenode.net anytime (nick MarcWeber) Of course If you're interested only in running some small queries you should just use PHP or another language of your choice :) Of course if you have some patches try them first. That will be faster if that works Marc Weber From markl at glyphic.com Thu Jan 21 10:07:46 2010 From: markl at glyphic.com (Mark Lentczner) Date: Thu Jan 21 09:39:55 2010 Subject: [Haskell-cafe] Extracting all pruned sub trees In-Reply-To: <594c1e831001201009g299f5116we81b8d255608b147@mail.gmail.com> References: <594c1e831001201009g299f5116we81b8d255608b147@mail.gmail.com> Message-ID: On Jan 20, 2010, at 10:09 AM, Tom Hawkins wrote: > I'm looking for an elegant way to generate a list of all pruned trees > where each pruned tree has one of its leaves removed. This turned out to be a thornier problem than I thought! (pun intended) > -- | A simple Tree type. > data Tree a = Leaf a | Branches [Tree a] > deriving Show > > -- | Produce a list of all possible Trees that can result from pruning one Leaf > allPrunings :: Tree a -> [Tree a] > allPrunings (Leaf _) = [] > allPrunings (Branches ts) = Branches `fmap` pruneInTurn ts > where pruneInTurn (a:as) = pruneOneWith a as ++ map (a:) (pruneInTurn as) > pruneInTurn _ = [] > pruneOneWith (Leaf _) as = [ as ] > pruneOneWith a as = map (:as) (allPrunings a) The difficulty lies in the treatment of Branches vs Leaf: Pruning Branches laves a Tree who's head (well, "root") is of the same form, whereas pruning Leaf leaves nothing (no valid Tree). This gives rise for the need for the pruneOneWith function. A more complete module with a small parser for a string tree language, and a nice, input and pring all prunings function can be found here: http://bitbucket.org/mtnviewmark/haskell-playground/src/tip/cafe/TreePrune.hs Enjoy! - Mark Mark Lentczner http://www.ozonehouse.com/mark/ IRC: mtnviewmark From andrew.polonsky at gmail.com Thu Jan 21 12:12:57 2010 From: andrew.polonsky at gmail.com (Andrew Polonsky) Date: Thu Jan 21 11:45:06 2010 Subject: [Haskell-cafe] problems installing ghc-6.12.1-x86_64 Message-ID: <76f550871001210912t6d8430bds86d8298bead30883@mail.gmail.com> Dear all, Help!! I am trying to build 6.12 on a fresh 64-bit Ubuntu, with no GHC installed yet. The compiler itself builds happily, but when I try to "make install" the Haskell platform, I eventually get the error Setup: GLUT-2.1.1.2: dependency "OpenGL-2.2.1.1-b638210d1627880d532e3b035b53bcd2" doesn't exist (use --force to override) I can't even install cabal, because it requires having the ghc6 package, which is not installed. And bootstrapping cabal-install requires parsec and network, which also require ghc6. When I finally install ghc6 (why should I have to anyway?), it still thinks I am on 6.12, and ./bootstrap.sh can't find parsec with that number. Is there anyway to break out of this non-terminating reduction? Is YI solvable? :'"( Andrew From ivan.miljenovic at gmail.com Thu Jan 21 12:17:47 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Thu Jan 21 11:50:10 2010 Subject: [Haskell-cafe] problems installing ghc-6.12.1-x86_64 In-Reply-To: <76f550871001210912t6d8430bds86d8298bead30883@mail.gmail.com> (Andrew Polonsky's message of "Thu, 21 Jan 2010 18:12:57 +0100") References: <76f550871001210912t6d8430bds86d8298bead30883@mail.gmail.com> Message-ID: <87ljfridhg.fsf@gmail.com> Andrew Polonsky writes: > Help!! I am trying to build 6.12 on a fresh 64-bit Ubuntu, with no > GHC installed yet. The compiler itself builds happily, but when I try > to "make install" the Haskell platform, I eventually get the error The Haskell Platform is currently for GHC 6.10.4, not 6.12.1. Assuch, there's no guarantees. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From greg at gregorycollins.net Thu Jan 21 12:27:56 2010 From: greg at gregorycollins.net (Gregory Collins) Date: Thu Jan 21 12:00:09 2010 Subject: [Haskell-cafe] Iteratee wrapper for attoparsec In-Reply-To: <87y6jvdmlv.fsf@gregorycollins.net> (Gregory Collins's message of "Mon, 18 Jan 2010 18:22:52 -0500") References: <4B4B949A.5050309@web.de> <9979e72e1001111448w123e38c1i90ae4276ea800ae3@mail.gmail.com> <87y6jvdmlv.fsf@gregorycollins.net> Message-ID: <87r5pj1i77.fsf@gregorycollins.net> Gregory Collins writes: > John Lato writes: > >> I don't know if I'd call it a hybrid, however there is a way to embed >> Parsec parsers (v.3 only) in iteratee. The necessary code is >> available at: >> >> http://inmachina.net/~jwlato/haskell/ParsecIteratee.hs > > This post inspired me to write an iteratee wrapper for attoparsec. The > attoparsec library has an incremental parser; this means that we don't > have to use John's lookahead buffer trick, restoring the iteratee > constant-space guarantee. The downside: I don't think the attoparsec > incremental parser is capable of maintaining the source position for > error reporting. ....and here's a version that might actually work (mea culpa) ------------------------------------------------------------------------------ {-# LANGUAGE OverloadedStrings #-} module Data.Attoparsec.Iteratee (parserToIteratee) where ------------------------------------------------------------------------------ import qualified Data.Attoparsec.Incremental as Atto import Data.Attoparsec.Incremental hiding (Result(..)) import qualified Data.ByteString as S import qualified Data.ByteString.Lazy as L import Data.Iteratee import Data.Iteratee.WrappedByteString import Data.Word (Word8) import Prelude hiding (takeWhile) -- for the examples at the bottom only import Control.Monad.Identity import Data.Char import Data.ByteString.Internal (w2c) -- The principle is general enough to work for any 'StreamChunk' type (with -- appropriate wrapping/unwrapping inserted), but I'm working with -- "WrappedByteString Word8", sorry type Stream = StreamG WrappedByteString Word8 type Iteratee m = IterateeG WrappedByteString Word8 m type IterV m = IterGV WrappedByteString Word8 m type Enumerator m a = Iteratee m a -> m (Iteratee m a) parserToIteratee :: (Monad m) => Parser a a -> Iteratee m a parserToIteratee p = IterateeG $ f (\s -> parse p s) where f :: (Monad m) => (L.ByteString -> Atto.Result a) -> Stream -> m (IterV m a) f k (EOF Nothing) = finalChunk $ k "" f _ (EOF (Just e)) = reportError e f k (Chunk s) = chunk (fromWrap s) k finalChunk :: (Monad m) => Atto.Result a -> m (IterV m a) finalChunk (Atto.Failed m) = return $ Cont (error $ show m) (Just $ Err m) finalChunk (Atto.Done rest r) = return $ Done r (Chunk $ toWrap rest) finalChunk (Atto.Partial _) = return $ Cont (error "parser did not consume all input") (Just $ Err "parser did not consume all input") reportError e = return $ Cont (error $ show e) (Just e) chunk :: (Monad m) => L.ByteString -> (L.ByteString -> Atto.Result a) -> m (IterV m a) chunk s k = do let r = k s case r of (Atto.Failed m) -> return $ Cont (throwErr (Err m)) (Just $ Err m) (Atto.Done rest x) -> return $ Done x (Chunk $ toWrap rest) (Atto.Partial z) -> return $ Cont (IterateeG $ f z) Nothing -- | lazy bytestring -> wrapped bytestring toWrap :: L.ByteString -> WrappedByteString Word8 toWrap = WrapBS . S.concat . L.toChunks -- | wrapped bytestring -> lazy bytestring fromWrap :: WrappedByteString Word8 -> L.ByteString fromWrap = L.fromChunks . (:[]) . unWrap ------------------------------------------------------------------------------ -- And a quick example sp :: Parser r () sp = () <$ takeWhile (isSpace . w2c) digits :: Parser r String digits = many1 (w2c <$> satisfy (isDigit . w2c)) number :: Parser r Int number = read <$> digits numberList :: Parser r [Int] numberList = liftA2 (:) number (many (sp *> number)) ensureEOF :: Parser r () ensureEOF = endOfInput <|> reportError where reportError = do ch <- anyWord8 let msg = concat [ "unexpected character '" , [w2c ch] , "'" ] fail msg numberListIter :: (Monad m) => Iteratee m [Int] numberListIter = parserToIteratee $ numberList <* ensureEOF -- | Turn a strict bytestring into an enumerator enumBS :: (Monad m) => S.ByteString -> Enumerator m a enumBS bs = enumPure1Chunk $ WrapBS bs _example :: [Int] _example = runIdentity (enumerate numberListIter >>= run) where -- example, the source could be any enumerator enumerate = enumBS "1000 2000 3000 4000 5000 6000 7000" _exampleWithError :: Either ErrMsg [Int] _exampleWithError = runIdentity (enumerate numberListIter >>= run . checkErr) where enumerate = enumBS "1000 2000 3000 4000 5000 6000 7000q" -- > *Data.Attoparsec.Iteratee> _example -- > [1000,2000,3000,4000,5000,6000,7000] -- > *Data.Attoparsec.Iteratee> _exampleWithError -- > Left (Err "unexpected character 'q'") ------------------------------------------------------------------------------ G. -- Gregory Collins From tomahawkins at gmail.com Thu Jan 21 12:36:49 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Thu Jan 21 12:08:57 2010 Subject: [Haskell-cafe] Extracting all pruned sub trees In-Reply-To: References: <594c1e831001201009g299f5116we81b8d255608b147@mail.gmail.com> Message-ID: <594c1e831001210936o74ffe65ax86e934f81f8f4000@mail.gmail.com> On Thu, Jan 21, 2010 at 4:07 PM, Mark Lentczner wrote: > On Jan 20, 2010, at 10:09 AM, Tom Hawkins wrote: >> I'm looking for an elegant way to generate a list of all pruned trees >> where each pruned tree has one of its leaves removed. > > This turned out to be a thornier problem than I thought! (pun intended) > >> -- | A simple Tree type. >> data Tree a = Leaf a | Branches [Tree a] >> ? ? ? deriving Show >> >> -- | Produce a list of all possible Trees that can result from pruning one Leaf >> allPrunings :: Tree a -> [Tree a] >> allPrunings (Leaf _) = [] >> allPrunings (Branches ts) = Branches `fmap` pruneInTurn ts >> ? ? where pruneInTurn (a:as) = pruneOneWith a as ++ map (a:) (pruneInTurn as) >> ? ? ? ? ? pruneInTurn _ ? ? ?= [] >> ? ? ? ? ? pruneOneWith (Leaf _) as = [ as ] >> ? ? ? ? ? pruneOneWith a ? ? ? ?as = map (:as) (allPrunings a) > > The difficulty lies in the treatment of Branches vs Leaf: Pruning Branches laves a Tree who's head (well, "root") is of the same form, whereas pruning Leaf leaves nothing (no valid Tree). This gives rise for the need for the pruneOneWith function. > > A more complete module with a small parser for a string tree language, and a nice, input and pring all prunings function can be found here: > > ? ? ? ?http://bitbucket.org/mtnviewmark/haskell-playground/src/tip/cafe/TreePrune.hs > > Enjoy! Very nice. Thanks! -Tom From gue.schmidt at web.de Thu Jan 21 13:04:29 2010 From: gue.schmidt at web.de (=?ISO-8859-15?Q?G=FCnther_Schmidt?=) Date: Thu Jan 21 12:37:00 2010 Subject: [Haskell-cafe] state of High Level GUI libs? Message-ID: <4B58972D.8000408@web.de> Hello, what is the current state of the higher GUI libs with reference to usability? G?nther From dons at galois.com Thu Jan 21 13:51:00 2010 From: dons at galois.com (Don Stewart) Date: Thu Jan 21 13:23:14 2010 Subject: [Haskell-cafe] Haskell Platform In-Reply-To: <351ff25e1001210148i1f71a093n5fe8d615973ac2d0@mail.gmail.com> References: <351ff25e1001210148i1f71a093n5fe8d615973ac2d0@mail.gmail.com> Message-ID: <20100121185100.GF26216@whirlpool.galois.com> RafaelGCPP.Linux: > Hi folks, > > How are the efforts on Haskell Platform for GHC 6.12.1 going? > > I'm considering joining those brave heroes. Where can I apply? > There'll be a time table update in the next few days, but you can certainly help by attempting to build things. -- Don From scooter.phd at gmail.com Thu Jan 21 18:58:08 2010 From: scooter.phd at gmail.com (Scott Michel) Date: Thu Jan 21 18:30:17 2010 Subject: [Haskell-cafe] OT: How a Common Lisp user views other programming languages Message-ID: <258cd3201001211558n13494025l9996f28cab09738c@mail.gmail.com> Off topic, but funny: http://kvardek-du.kerno.org/2010/01/how-common-lisp-programmer-views-users.html The Haskell icon is very apt! -scooter -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100121/108aec37/attachment.html From contact at sphere-research.com Thu Jan 21 20:02:40 2010 From: contact at sphere-research.com (Sphere Research Labs) Date: Thu Jan 21 19:42:16 2010 Subject: [Haskell-cafe] Haskell on Ideone! Message-ID: Hi, test Haskell on ideone.com, see the example: http://ideone.com/bbloQ9r0 regards, Ideone Team From gwern0 at gmail.com Thu Jan 21 20:25:56 2010 From: gwern0 at gmail.com (Gwern Branwen) Date: Thu Jan 21 19:58:04 2010 Subject: [Haskell-cafe] Haskell on Ideone! In-Reply-To: References: Message-ID: On Thu, Jan 21, 2010 at 8:02 PM, Sphere Research Labs wrote: > Hi, > > test Haskell on ideone.com, > > see the example: http://ideone.com/bbloQ9r0 > > regards, > > Ideone Team Besides specifying standard in, what does Ideone do beyond codepad.org? (eg. http://codepad.org/Guukn3Ho) How are you guys doing the sandboxing - just the usual chroot with rlimits? Also, the site's visual appearance is somewhat broken under firefox 3.5.7; see screenshot. -- gwern -------------- next part -------------- A non-text attachment was scrubbed... Name: xwd-126412350810165.png Type: image/png Size: 87752 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100121/aab86176/xwd-126412350810165-0001.png From vanenkj at gmail.com Thu Jan 21 22:07:00 2010 From: vanenkj at gmail.com (John Van Enk) Date: Thu Jan 21 21:39:09 2010 Subject: [Haskell-cafe] Haskell on Ideone! In-Reply-To: References: Message-ID: Seems a little dangerous: http://ideone.com/XL6uLnLo On Thu, Jan 21, 2010 at 8:25 PM, Gwern Branwen wrote: > On Thu, Jan 21, 2010 at 8:02 PM, Sphere Research Labs > wrote: > > Hi, > > > > test Haskell on ideone.com, > > > > see the example: http://ideone.com/bbloQ9r0 > > > > regards, > > > > Ideone Team > > Besides specifying standard in, what does Ideone do beyond > codepad.org? (eg. http://codepad.org/Guukn3Ho) > > How are you guys doing the sandboxing - just the usual chroot with rlimits? > > Also, the site's visual appearance is somewhat broken under firefox > 3.5.7; see screenshot. > > -- > gwern > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100121/b4996b33/attachment.html From michael at snoyman.com Thu Jan 21 23:37:38 2010 From: michael at snoyman.com (Michael Snoyman) Date: Thu Jan 21 23:09:47 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> Message-ID: <29bf512f1001212037nc213446uf11e813e82f918a@mail.gmail.com> Hey Jeremy, I was just wondering: how does Happstack deal with gzip encoding when it uses sendfile? I can think of a few ways (cache gziped versions to the disk), but was wondering if you'd already come up with a good solution. I'm trying to keep all these things in mind when designing WAI. Thanks, Michael On Thu, Jan 14, 2010 at 5:42 PM, Jeremy Shaw wrote: > Hello, > > Happstack is currently bundled with it's own lazy I/O based HTTP backend. > Ideally, we would like to split that out, and allow happstack to be used > with that backend, hyena, or other options. > > A primary using for using hyena would be for the benefits of predictability > and constant space usage that iterators bring. People do actually running > into the issues that come with lazy I/O, such as running out of file > descriptors, etc. So, I feel like I would want to stick with using > iterators the whole way when using hyena, and not convert back to a lazy > ByteString? > > Happstack now includes support for sendfile(). This is done by adding > another constructor to the Response type: > > (line 94): > > http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/HTTP/Types.hs > > Then here on line 197, we match on that case and use sendfile to send the > data: > > > http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/HTTP/Handler.hs > > This makes it difficult for use to be compatible with WAI. We can write a > wrapper that converts the sendfile case to use lazy bytestrings instead, but > then we lose the advantages of using sendfile. > > I wonder if the 'Response' portion of WAI should support all three > currently used methods: > - lazy I/O > - Enumerator > - sendFile > > I haven't really thought about how that would work.. > > hyena currently includes a Network.WAI which uses ByteString: > > > http://hackage.haskell.org/packages/archive/hyena/0.1/doc/html/Network-Wai.html > > gotta run, sorry about any typos! > - jeremy > > > > On Jan 13, 2010, at 8:46 AM, Michael Snoyman wrote: > > Hi, >> >> I recently read (again) the wiki page on a web application interface[1] >> for Haskell. It seems like this basically works out to Hack[2], but using an >> enumerator instead of lazy bytestring in the response type. Is anyone >> working on implementing this? If not, I would like to create the package, >> though I wouldn't mind some community input on some design decisions: >> >> * Hack has been fairly well-tested in the past year and I think it >> provides the features that people want. Therefore, I would want to model the >> Environment variable for WAI from Hack. I *could* just import Hack in WAI >> and use the exact same Environment data type. Thoughts? >> >> * If using a different data type for Environment, should I replace the >> String parts with ByteStrings? On the one hand, ByteStrings are the >> "correct" data type since the HTTP protocol does not specify a character >> encoding; on the other hand, Strings are easier to deal with. >> >> * It's simple to write a function to convert between a lazy bytestring and >> an enumerator, meaning it would be very easy to write conversion functions >> between Hack and WAI applications. This would make it simpler for people to >> use either backend. >> >> If someone else is already working on WAI, please let me know, I don't >> want to have duplicate implementations. The idea here is to consolidate, not >> split the community. I have a few Hack handlers (simpleserver, cgi, fastcgi) >> that I would happily convert to WAI handlers as well. >> >> Michael >> >> [1] http://www.haskell.org/haskellwiki/WebApplicationInterface >> [2] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hack >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100121/0865ad65/attachment.html From jmillikin at gmail.com Fri Jan 22 01:09:52 2010 From: jmillikin at gmail.com (John Millikin) Date: Fri Jan 22 00:42:20 2010 Subject: [Haskell-cafe] Is Haskell capable of matching C in string processing performance? Message-ID: <3283f7fe1001212209ndd14978tfa55d3e688d3a0a8@mail.gmail.com> Recently I've been working on a library for generating large JSON[1] documents quickly. Originally I started writing it in Haskell, but quickly encountered performance problems. After exhausting my (meager) supply of optimization ideas, I rewrote some of it in C, with dramatic results. Namely, the C solution is * 7.5 times faster than the fastest Haskell I could write (both using raw pointer arrays) * 14 times faster than a somewhat functional version (uses monads, but no explicit IO) * >30 times faster than fancy functional solutions with iteratees, streams, etc I'm wondering if string processing is simply a Haskell weak point, performance-wise. The problem involves many millions of very small (<10 character, usually) strings -- the C solution can copy directly from string literals into a fixed buffer and flush it occasionally, while even the fastest Haskell version has a lot of overhead from copying around arrays. Dons suggested I was "doing it wrong", so I'm posting on -cafe in the hopes that somebody can tell me how to get better performance without resorting to C. Here's the fastest Haskell version I could come up with. It discards all error handling, validation, and correctness in the name of performance, but still can't get anywhere near C: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=16423 [1] http://json.org/ From dons at galois.com Fri Jan 22 01:28:00 2010 From: dons at galois.com (Don Stewart) Date: Fri Jan 22 01:00:11 2010 Subject: [Haskell-cafe] Is Haskell capable of matching C in string processing performance? In-Reply-To: <3283f7fe1001212209ndd14978tfa55d3e688d3a0a8@mail.gmail.com> References: <3283f7fe1001212209ndd14978tfa55d3e688d3a0a8@mail.gmail.com> Message-ID: <20100122062800.GB28541@whirlpool.galois.com> jmillikin: > Here's the fastest Haskell version I could come up with. It discards > all error handling, validation, and correctness in the name of > performance, but still can't get anywhere near C: > http://hpaste.org/fastcgi/hpaste.fcgi/view?id=16423 Thanks for posting the code. You're not using bytestrings?? They were invented to deal with the problem of [Char] being a poor structure for large scale string processing, and you should have no problem getting C-like string performance. http://www.cse.unsw.edu.au/~dons/papers/CSL06.html -- Don From briand at aracnet.com Fri Jan 22 01:43:40 2010 From: briand at aracnet.com (Brian Denheyer) Date: Fri Jan 22 01:15:53 2010 Subject: [Haskell-cafe] hsql won't install due to system.time In-Reply-To: <2F6595B1-2A5E-4EA7-8BF2-8BE0D793B034@cs.york.ac.uk> References: <20100120221007.75dfede9@windy.deldotd.com> <2F6595B1-2A5E-4EA7-8BF2-8BE0D793B034@cs.york.ac.uk> Message-ID: <20100121224340.73cebae3@windy.deldotd.com> On Thu, 21 Jan 2010 09:01:01 +0000 Malcolm Wallace wrote: > The easiest workaround is to change your local copy of the .cabal > file for hsql, modifying the build-depends line to make a more > precise dependency on old-time, e.g. > build-depends: old-time-1.0.0.2 First of all, apologies are in order, the package I am having trouble with is haskelldb-hsql-sqlite3. hsql installed just fine, as well as hsql-sqlite3. In all of the hackage database package excitement I got confused. Here's what I tried : add old-time-1.0.0.2 to the _end_ of the build-depends line: cabal: haskelldb-hsql-sqlite3.cabal:7: Parse of field 'build-depends' failed. Interestingly, if I simply add old-time then I don't get that error but instead my good friend the "hidden package" error. I tried giving it it's own build-depends line, but adding the version suffix still gives me the parse error. ?? Brian From mattphil at gmail.com Fri Jan 22 01:51:27 2010 From: mattphil at gmail.com (Matthew Phillips) Date: Fri Jan 22 01:23:41 2010 Subject: [Haskell-cafe] Spelling checker exercise Message-ID: <83757D35-C8ED-49B9-9EAA-FED2098C52F9@gmail.com> Hello all, sorry to bring up an old chestnut, but I?m trying to improve my Haskell-fu by writing a small program, and chose Peter Norvig?s spelling checker as my exercise material (http://norvig.com/spell-correct.html). While I?ve gotten it working, and found it quite illuminating, I also found it to to be very slow. And then I discovered that, of course, others have been here well before me ([1] and [2]). Those discussions were very interesting, but the code they refer to is mostly not available, so the most I?ve gotten out of it so far is that: (a) I should be using strict left folds and strict Map insertions for the word frequency map (this shaved off about a second: ~5s -> ~4s for a single word on my 2.4GHz MacBook Pro, GHC 6.10.4) (b) I should probably be using ByteString?s (c) Using Set?s for the edit permutations probably isn?t worth it (although I found using plain lists made it about a second slower) (b) is difficult because I?ve used matching patterns plus list comprehensions to generate the potential edits, and I really like how elegantly it pans out that way. Because ByteString?s are not lists, I can?t see a way to keep the current structure and use them. The code is at [3] (link to version at time of post). Profiling [4] shows: $ ./spelling becuase +RTS -p becuase -> because $ cat spelling.prof total time = 4.02 secs (201 ticks @ 20 ms) total alloc = 1,544,257,792 bytes (excludes profiling overheads) COST CENTRE MODULE %time %alloc train Main 52.7 19.7 readFile Main 28.9 8.6 wordsBy Main 10.9 49.5 toLower Main 7.0 21.8 ... So it appears that ?train" (building the freq map) and ?readFile? in ?nwords" are the places to hone. I will look at using Bloom Filters or Trie?s instead of Data.Map, but I wonder if readFile should be taking nearly %30 of the run time, even for a 6MB file? Sorry to dump such a long post on the list ? I?ll understand if no one can be bothered rehashing this. But, in summary I?d like to know: (a) how could I use ByteString?s for this to speed up I/O and reduce memory usage without losing the nice readability? (b) should readFile be so slow? (c) any other tips Possibly all my questions could be answered if someone has the code from the old posts. Cheers, Matthew. [1]: http://haskell.markmail.org/search/?q=norvig%20spelling#query:norvig%20spelling+page:1+mid:jrvpyjpms5dumd3k+state:results [2]: http://thread.gmane.org/gmane.comp.lang.haskell.cafe/21780 [3]: http://github.com/scramjet/spelling/blob/44fd336ef4f62d49c7087dbc1ffb9c009b78cec0/spelling.hs [4]: http://github.com/scramjet/spelling/blob/f5146b24b77443c22975ff69fb91aa922cc1d4a3/spelling.prof From james at neurogami.com Fri Jan 22 02:44:21 2010 From: james at neurogami.com (James Britt) Date: Fri Jan 22 02:16:28 2010 Subject: [Haskell-cafe] Cannot rebuild GHC 6.12.1 due to Cabal type conflict Message-ID: <4B595755.1020603@neurogami.com> Hey all. I recently wanted to rebuild GHC 6.12.1 from source (from a downloaded tarball). After the first install from that source I went and updated Cabal (from a tarball grabbed from Hackage). When I now try to do a rebuild of GHC, I get this error compiler/main/Packages.lhs:233:63: Couldn't match expected type `InstalledPackageInfo_ String' against inferred type `Cabal-1.8.0.2:Distribution.InstalledPackageInfo.InstalledPackageInfo_ m' Expected type: [InstalledPackageInfo_ String] Inferred type: [Cabal-1.8.0.2:Distribution.InstalledPackageInfo.InstalledPackageInfo_ m] In the second argument of `map', namely `conf' In the first argument of `return', namely `(map installedPackageInfoToPackageConfig conf)' make[1]: *** [compiler/stage1/build/Packages.o] Error 1 make[1]: *** Waiting for unfinished jobs.... make: *** [all] Error 2 (also here: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=16380#a16380) I'm running the build like this: make distclean sh boot ./configure --enable-shared make -j 2 but (I'm guessing) it's looking at the already-installed Cabal libs and not liking what it's getting. Any ideas on how to get past this? Thanks, James Britt -- www.jamesbritt.com - Playing with Better Toys www.ruby-doc.org - Ruby Help & Documentation www.rubystuff.com - The Ruby Store for Ruby Stuff www.neurogami.com - Smart application development From vandijk.roel at gmail.com Fri Jan 22 04:40:22 2010 From: vandijk.roel at gmail.com (Roel van Dijk) Date: Fri Jan 22 04:12:31 2010 Subject: [Haskell-cafe] haddock - 'could not find link destination" In-Reply-To: <201001211506.56916.daniel.is.fischer@web.de> References: <201001211451.20388.frank@geoinfo.tuwien.ac.at> <201001211506.56916.daniel.is.fischer@web.de> Message-ID: On Thu, Jan 21, 2010 at 3:06 PM, Daniel Fischer wrote: > But I find it easier to let Cabal deal with haddock, make a Cabal package, > > runghc ./Setup.hs configure --user --prefix=$HOME > runghc ./Setup.hs haddock --hyperlink-source If you use a Cabal package in conjunction with cabal-install it saves you even more typing: cabal configure cabal haddock --hyperlink-source From apfelmus at quantentunnel.de Fri Jan 22 05:00:14 2010 From: apfelmus at quantentunnel.de (Heinrich Apfelmus) Date: Fri Jan 22 04:32:55 2010 Subject: [Haskell-cafe] Re: Is Haskell capable of matching C in string processing performance? In-Reply-To: <20100122062800.GB28541@whirlpool.galois.com> References: <3283f7fe1001212209ndd14978tfa55d3e688d3a0a8@mail.gmail.com> <20100122062800.GB28541@whirlpool.galois.com> Message-ID: Don Stewart wrote: > jmillikin: >> Here's the fastest Haskell version I could come up with. It discards >> all error handling, validation, and correctness in the name of >> performance, but still can't get anywhere near C: >> http://hpaste.org/fastcgi/hpaste.fcgi/view?id=16423 > > Thanks for posting the code. > > You're not using bytestrings?? > > They were invented to deal with the problem of [Char] being a poor > structure for large scale string processing, and you should have no > problem getting C-like string performance. > > http://www.cse.unsw.edu.au/~dons/papers/CSL06.html In my limited experience, ByteStrings are great for reading data, but not that good for writing data that is being generated on the fly. For writing, good old difference lists or the Builder monoid / Put monad from Data.Binary seem to be best. Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com From marco-oweber at gmx.de Fri Jan 22 05:29:11 2010 From: marco-oweber at gmx.de (Marc Weber) Date: Fri Jan 22 05:01:20 2010 Subject: [Haskell-cafe] hsql won't install due to system.time In-Reply-To: <20100121224340.73cebae3@windy.deldotd.com> References: <20100120221007.75dfede9@windy.deldotd.com> <2F6595B1-2A5E-4EA7-8BF2-8BE0D793B034@cs.york.ac.uk> <20100121224340.73cebae3@windy.deldotd.com> Message-ID: <1264156109-sup-8536@nixos> > add old-time-1.0.0.2 to the _end_ of the build-depends line: > > cabal: haskelldb-hsql-sqlite3.cabal:7: Parse of field 'build-depends' > failed. This is a cabal issue. Get a newer cabal and retry. Marc Weber From Alistair.Bayley at invesco.com Fri Jan 22 05:38:37 2010 From: Alistair.Bayley at invesco.com (Bayley, Alistair) Date: Fri Jan 22 05:10:45 2010 Subject: [Haskell-cafe] RE: ssh ports for monk and nun? In-Reply-To: References: <79d7c4981001121243j708b6127r5cd5312f0cb97246@mail.gmail.com><79d7c4981001121257i2a8a230elad85ba04b45b2ec6@mail.gmail.com> Message-ID: <125EACD0CAE4D24ABDB4D148C4593DA911026698@GBLONXMB02.corp.amvescap.net> > From: libraries-bounces@haskell.org > [mailto:libraries-bounces@haskell.org] On Behalf Of Stefan Monnier > > >> Trying to get ssh working via putty from behind my company > firewall. > > My recommendation is to get access to an outside machine where you run > an OpenVPN server on port 80 or 443. This will solve it "once and for > all". > But first, please complain loudly and repeatedly about the firewall > being closed to port 22. Tried and failed. Our firewall will be closed to port 22 for the forseaable future. I'll give the OpenVPN thing a go, if I can find some time. I'm wondering about a couple of things: 1. how many people (in the haskell community) have the same problem? How have they solved or worked around the problem? 2. is it possible to run SSH daemons on monk and nun on ports 80 or 443? I'm wondering both from a technical feasability POV, and also an administrative POV i.e. if it were technically feasible, would the admins be open to the idea, if there was sufficient demand? Thanks, Alistair ***************************************************************** Confidentiality Note: The information contained in this message, and any attachments, may contain confidential and/or privileged material. It is intended solely for the person(s) or entity to which it is addressed. Any review, retransmission, dissemination, or taking of any action in reliance upon this information by persons or entities other than the intended recipient(s) is prohibited. If you received this in error, please contact the sender and delete the material from any computer. ***************************************************************** From jwlato at gmail.com Fri Jan 22 06:17:15 2010 From: jwlato at gmail.com (John Lato) Date: Fri Jan 22 05:49:22 2010 Subject: [Haskell-cafe] hsql won't install due to system.time Message-ID: <9979e72e1001220317r78b15b30mb719d384f91c1c91@mail.gmail.com> Hello, Could this be a global/user install issue? That is, if the old-time package is installed per-user, and you're trying to install a package globally, the user-installed packages all show up as hidden, because they can't be dependencies of a global install. This shows up frequently because global installs are the default when doing "runghc Setup.hs install", but per-user installs are the default for cabal install. If you use both of these commands, you'll run into this sooner or later. You can run "ghc-pkg list" to get a listing of what's installed where. If "old-time" is only in the local database, you should reinstall it into the global database (or install everything globally). Cheers, John > From: Brian Denheyer > > Database/HaskellDB/HSQL.hs:25:7: > ? ?Could not find module `System.Time': > ? ? ?it is a member of the hidden package `old-time-1.0.0.3' > ? ? ?it is a member of the hidden package `old-time-1.0.0.2' > ? ? ?Use -v to see a list of the files searched for. > > old-time-1.0.0.2 is installed (via cabal). > > Suggestions on how to fix this or which haskell db (for sqlite3) package > will actually install greatly appreciated. > > I get a lot of failures in hackages which involve that dreaded "hidden > package" message. ?Anybody care to enlighten us mere mortals as to why > it seems to occur so frequently (at least for me). > > Brian > From frodo at theshire.org Fri Jan 22 06:22:28 2010 From: frodo at theshire.org (Cristiano Paris) Date: Fri Jan 22 05:54:55 2010 Subject: [Haskell-cafe] RE: ssh ports for monk and nun? In-Reply-To: <125EACD0CAE4D24ABDB4D148C4593DA911026698@GBLONXMB02.corp.amvescap.net> References: <79d7c4981001121243j708b6127r5cd5312f0cb97246@mail.gmail.com> <79d7c4981001121257i2a8a230elad85ba04b45b2ec6@mail.gmail.com> <125EACD0CAE4D24ABDB4D148C4593DA911026698@GBLONXMB02.corp.amvescap.net> Message-ID: On Fri, Jan 22, 2010 at 11:38 AM, Bayley, Alistair wrote: > ... > Tried and failed. Our firewall will be closed to port 22 for the > forseaable future. I'll give the OpenVPN thing a go, if I can find some > time. Trying to ask how to pierce your company's firewall in a public mailing list, even from your company's email address, may not be advisable. Cristiano From emax at chalmers.se Fri Jan 22 06:24:37 2010 From: emax at chalmers.se (Emil Axelsson) Date: Fri Jan 22 05:56:44 2010 Subject: [Haskell-cafe] Non-termination due to context Message-ID: <4B598AF5.3090909@chalmers.se> Hello all! Consider the following program: > {-# LANGUAGE FlexibleInstances, OverlappingInstances, UndecidableInstances #-} > > class B a => A a > > instance A Int > > class Eq a => B a > > instance (A a, Eq a) => B a > > eq :: B a => a -> a -> Bool > eq = (==) > > test = 1 `eq` (2::Int) (This is a condensed version of a much larger program that I've been debugging.) It compiles just fine, but `test` doesn't terminate (GHCi 6.10.4). If I change the context `B a` to `Eq a` for the function `eq`, it terminates. Although I don't know all the details of the class system, it seems unintuitive that I can make a program non-terminating just by changing the context of a function (regardless of UndecidableInstances etc.). Is this a bug or a feature? / Emil From ozgurakgun at gmail.com Fri Jan 22 06:31:33 2010 From: ozgurakgun at gmail.com (Ozgur Akgun) Date: Fri Jan 22 06:03:40 2010 Subject: [Haskell-cafe] Existential Types (I guess) Message-ID: <7be1feae1001220331p3f3bc506x3dd3d77c8093767a@mail.gmail.com> Dear Cafe, I can write and use the following, data IntHolder = IntHolder Integer instance Show IntHolder where show (IntHolder n) = show n liftInt :: (Integer -> Integer) -> IntHolder -> IntHolder liftInt f (IntHolder c) = IntHolder (f c) But I cannot generalise it to *Num:* data NumHolder = forall a. Num a => NumHolder a instance Show NumHolder where show (NumHolder n) = show n liftNum :: (Num a) => (a -> a) -> NumHolder -> NumHolder liftNum f (NumHolder c) = NumHolder (f c) The error message I get is the following: Couldn't match expected type `a' against inferred type `a1' `a' is a rigid type variable bound by the type signature for `liftNum' at Lifts.hs:54:16 `a1' is a rigid type variable bound by the constructor `NumHolder' at Lifts.hs:55:11 In the first argument of `f', namely `c' In the first argument of `NumHolder', namely `(f c)' In the expression: NumHolder (f c) Regards, -- Ozgur Akgun -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100122/030d6693/attachment.html From nccb2 at kent.ac.uk Fri Jan 22 06:36:59 2010 From: nccb2 at kent.ac.uk (Neil Brown) Date: Fri Jan 22 06:09:46 2010 Subject: [Haskell-cafe] Existential Types (I guess) In-Reply-To: <7be1feae1001220331p3f3bc506x3dd3d77c8093767a@mail.gmail.com> References: <7be1feae1001220331p3f3bc506x3dd3d77c8093767a@mail.gmail.com> Message-ID: <4B598DDB.80804@kent.ac.uk> Ozgur Akgun wrote: > data NumHolder = forall a. Num a => NumHolder a > > instance Show NumHolder where > show (NumHolder n) = show n > > liftNum :: (Num a) => (a -> a) -> NumHolder -> NumHolder > liftNum f (NumHolder c) = NumHolder (f c) The problem here is that you declare that liftNum will work for any single type a, decided (effectively) by the caller of the function. But if the caller chooses Int for a, and your NumHolder has a Float inside it, that isn't going to work. You need to take a function that will work for any Num type a: liftNum :: (forall a. Num a => a -> a) -> NumHolder -> NumHolder liftNum f (NumHolder c) = NumHolder (f c) This uses Rank2Types, but that's necessary for what you want. By moving the forall from being implicit at the start of the signature to inside the brackets, you declare that this is a function that works for all types a (that are a member of type-class Num). This should compile and work as you wanted. Neil. From ross at soi.city.ac.uk Fri Jan 22 06:37:11 2010 From: ross at soi.city.ac.uk (Ross Paterson) Date: Fri Jan 22 06:09:58 2010 Subject: [Haskell-cafe] Non-termination due to context In-Reply-To: <4B598AF5.3090909@chalmers.se> References: <4B598AF5.3090909@chalmers.se> Message-ID: <20100122113711.GA8333@soi.city.ac.uk> On Fri, Jan 22, 2010 at 12:24:37PM +0100, Emil Axelsson wrote: > Consider the following program: > > >{-# LANGUAGE FlexibleInstances, OverlappingInstances, UndecidableInstances #-} > >class B a => A a > > > >instance A Int > > > >class Eq a => B a > > > >instance (A a, Eq a) => B a > [...] > Although I don't know all the details of the class system, it seems > unintuitive that I can make a program non-terminating just by > changing the context of a function (regardless of > UndecidableInstances etc.). > > Is this a bug or a feature? I'm afraid you voided the warranty when you used UndecidableInstances. You really do have a circularity between A and B here, so it's not surprising that you get a loop. By changing the context, you demanded more instances, undecidable ones in fact. From Alistair.Bayley at invesco.com Fri Jan 22 06:49:33 2010 From: Alistair.Bayley at invesco.com (Bayley, Alistair) Date: Fri Jan 22 06:21:41 2010 Subject: [Haskell-cafe] RE: ssh ports for monk and nun? In-Reply-To: References: <79d7c4981001121243j708b6127r5cd5312f0cb97246@mail.gmail.com> <79d7c4981001121257i2a8a230elad85ba04b45b2ec6@mail.gmail.com> <125EACD0CAE4D24ABDB4D148C4593DA911026698@GBLONXMB02.corp.amvescap.net> Message-ID: <125EACD0CAE4D24ABDB4D148C4593DA91102669B@GBLONXMB02.corp.amvescap.net> > From: cristiano.paris@gmail.com > [mailto:cristiano.paris@gmail.com] On Behalf Of Cristiano Paris > > On Fri, Jan 22, 2010 at 11:38 AM, Bayley, Alistair > wrote: > > ... > > Tried and failed. Our firewall will be closed to port 22 for the > > forseaable future. I'll give the OpenVPN thing a go, if I > can find some > > time. > > Trying to ask how to pierce your company's firewall in a public > mailing list, even from your company's email address, may not be > advisable. Well, I wasn't necessarily looking for that kind of advice, more along the lines of how to work with what I have (which is ports 80 and 443, via an http proxy server). I have been able to use CVS+SSH with sourceforge in the past, because they had cvs servers that listened for SSH connections on port 443. Alistair ***************************************************************** Confidentiality Note: The information contained in this message, and any attachments, may contain confidential and/or privileged material. It is intended solely for the person(s) or entity to which it is addressed. Any review, retransmission, dissemination, or taking of any action in reliance upon this information by persons or entities other than the intended recipient(s) is prohibited. If you received this in error, please contact the sender and delete the material from any computer. ***************************************************************** From ivan.miljenovic at gmail.com Fri Jan 22 06:51:05 2010 From: ivan.miljenovic at gmail.com (Ivan Lazar Miljenovic) Date: Fri Jan 22 06:23:14 2010 Subject: [Haskell-cafe] Non-termination due to context In-Reply-To: <20100122113711.GA8333@soi.city.ac.uk> (Ross Paterson's message of "Fri, 22 Jan 2010 11:37:11 +0000") References: <4B598AF5.3090909@chalmers.se> <20100122113711.GA8333@soi.city.ac.uk> Message-ID: <87ockmgxxy.fsf@gmail.com> Ross Paterson writes: > I'm afraid you voided the warranty when you used UndecidableInstances. I like this term of phrase. Maybe it should be used in the actual documentation? ;-) -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com From tom.davie at gmail.com Fri Jan 22 07:11:03 2010 From: tom.davie at gmail.com (Tom Davie) Date: Fri Jan 22 06:43:09 2010 Subject: [Haskell-cafe] Existential Types (I guess) In-Reply-To: <7be1feae1001220331p3f3bc506x3dd3d77c8093767a@mail.gmail.com> References: <7be1feae1001220331p3f3bc506x3dd3d77c8093767a@mail.gmail.com> Message-ID: <8b70a98a1001220411u68339a3dy4887dd933604c328@mail.gmail.com> Aside from Neil's point about rank-2 polymorphism, you can of course just parameterise your NumHolder type... data Num a => NumHolder a = NumHolder a instance Show a => Show NumHolder a where show (NumHolder x) = show x instance Functor NumHolder where fmap f (NumHolder a) = NumHolder (f a) It depends what you want to do with your NumHolder though. What is the purpose of this type? Bob On Fri, Jan 22, 2010 at 11:31 AM, Ozgur Akgun wrote: > Dear Cafe, > > I can write and use the following, > > data IntHolder = IntHolder Integer > > instance Show IntHolder where > show (IntHolder n) = show n > > liftInt :: (Integer -> Integer) -> IntHolder -> IntHolder > liftInt f (IntHolder c) = IntHolder (f c) > > But I cannot generalise it to *Num:* > > data NumHolder = forall a. Num a => NumHolder a > > instance Show NumHolder where > show (NumHolder n) = show n > > liftNum :: (Num a) => (a -> a) -> NumHolder -> NumHolder > liftNum f (NumHolder c) = NumHolder (f c) > > The error message I get is the following: > > Couldn't match expected type `a' against inferred type `a1' > `a' is a rigid type variable bound by > the type signature for `liftNum' at Lifts.hs:54:16 > `a1' is a rigid type variable bound by > the constructor `NumHolder' at Lifts.hs:55:11 > In the first argument of `f', namely `c' > In the first argument of `NumHolder', namely `(f c)' > In the expression: NumHolder (f c) > > > Regards, > > > -- > Ozgur Akgun > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100122/bdd968f6/attachment.html From si at fh-wedel.de Fri Jan 22 07:16:52 2010 From: si at fh-wedel.de (Uwe Schmidt) Date: Fri Jan 22 06:49:05 2010 Subject: [Haskell-cafe] ANNOUNCE: Haskell XML Toolbox Version 8.5.0 Message-ID: <201001221316.52258.haskell-bounces@haskell.org> Haskell XML Toolbox 8.5.0 I would like to announce a new version of the Haskell XML Toolbox. The main change in this release is the separation of the XPath module and the XSLT module into separate packages hxt-xpath and hxt-xslt. So the base package becomes a bit smaller. Installation shouldn't become more complex because of the easy install with cabal and hackage. A second major change concerns the XPath module. The internal data structures, especially the XPath node-sets, have been refactored for runtime efficiency. So even complex XPath expressions with ambiguous paths to single nodes run in acceptable time. The source repositories have been converted to the git version control system. There is a single git repository for all HXT packages at "http://git.fh-wedel.de/repos/hxt.git" More information and also downloads can be found at http://www.fh-wedel.de/~si/HXmlToolbox/index.html There's also a copy of all packages on Hackage. Please email comments, bugs, etc. to hxmltoolbox@fh-wedel.de or si@fh-wedel.de Uwe -- University of Applied Sciences, Wedel, Germany http://www.fh-wedel.de/~si/index.html From gcross at phys.washington.edu Fri Jan 22 07:23:05 2010 From: gcross at phys.washington.edu (Gregory Crosswhite) Date: Fri Jan 22 06:56:09 2010 Subject: [Haskell-cafe] Is Haskell capable of matching C in string processing performance? In-Reply-To: <3283f7fe1001212209ndd14978tfa55d3e688d3a0a8@mail.gmail.com> References: <3283f7fe1001212209ndd14978tfa55d3e688d3a0a8@mail.gmail.com> Message-ID: The following snippet of code ran ~ 33% faster than yours on my computer (GHC 6.10.4, OSX): import qualified Data.ByteString.Char8 as S import qualified Data.ByteString.Lazy as L import System.IO null_str = S.pack "null" main = withBinaryFile "out2.json" WriteMode $ \h -> do hPutStr h "[" L.hPutStr h . L.fromChunks . replicate 5000000 $ null_str hPutStr h "]" The following snippet ran in roughly the same speed (which should not be surprising, as it is essentially the same code): import Control.Monad import qualified Data.ByteString.Char8 as S import System.IO null_str = S.pack "null" main = withBinaryFile "out3.json" WriteMode $ \h -> do hPutStr h "[" replicateM_ 5000000 (S.hPutStr h null_str) hPutStr h "]" This C snippet ran ~ 6 times faster than the Haskell snippets: #include int main() { int i; FILE* f = fopen("outc.json","w"); fprintf(f,"["); for (i = 0; i < 5000000; ++i) fprintf(f,"null"); fprintf(f,"]"); } It seems to me this indicates that the big expense here is the call into the I/O system. Cheers, Greg On Jan 21, 2010, at 10:09 PM, John Millikin wrote: > Recently I've been working on a library for generating large JSON[1] > documents quickly. Originally I started writing it in Haskell, but > quickly encountered performance problems. After exhausting my (meager) > supply of optimization ideas, I rewrote some of it in C, with dramatic > results. Namely, the C solution is > > * 7.5 times faster than the fastest Haskell I could write (both using > raw pointer arrays) > * 14 times faster than a somewhat functional version (uses monads, but > no explicit IO) > * >30 times faster than fancy functional solutions with iteratees, streams, etc > > I'm wondering if string processing is simply a Haskell weak point, > performance-wise. The problem involves many millions of very small > (<10 character, usually) strings -- the C solution can copy directly > from string literals into a fixed buffer and flush it occasionally, > while even the fastest Haskell version has a lot of overhead from > copying around arrays. > > Dons suggested I was "doing it wrong", so I'm posting on -cafe in the > hopes that somebody can tell me how to get better performance without > resorting to C. > > Here's the fastest Haskell version I could come up with. It discards > all error handling, validation, and correctness in the name of > performance, but still can't get anywhere near C: > http://hpaste.org/fastcgi/hpaste.fcgi/view?id=16423 > > [1] http://json.org/ > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From emax at chalmers.se Fri Jan 22 07:38:06 2010 From: emax at chalmers.se (Emil Axelsson) Date: Fri Jan 22 07:10:14 2010 Subject: [Haskell-cafe] Non-termination due to context In-Reply-To: <20100122113711.GA8333@soi.city.ac.uk> References: <4B598AF5.3090909@chalmers.se> <20100122113711.GA8333@soi.city.ac.uk> Message-ID: <4B599C2E.8090806@chalmers.se> Ross Paterson skrev: > On Fri, Jan 22, 2010 at 12:24:37PM +0100, Emil Axelsson wrote: >> Consider the following program: >> >>> {-# LANGUAGE FlexibleInstances, OverlappingInstances, UndecidableInstances #-} >>> class B a => A a >>> >>> instance A Int >>> >>> class Eq a => B a >>> >>> instance (A a, Eq a) => B a >> [...] >> Although I don't know all the details of the class system, it seems >> unintuitive that I can make a program non-terminating just by >> changing the context of a function (regardless of >> UndecidableInstances etc.). >> >> Is this a bug or a feature? > > I'm afraid you voided the warranty when you used UndecidableInstances. > > You really do have a circularity between A and B here, so it's not > surprising that you get a loop. By changing the context, you demanded > more instances, undecidable ones in fact. But still, I've always heard that "undecidable instances can cause the type checker to loop, but if the compiler terminates, you're fine". Here the loop happens at run time, so undecidable instances must be a little more evil than I thought... / Emil From simonpj at microsoft.com Fri Jan 22 08:19:17 2010 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Fri Jan 22 07:51:58 2010 Subject: [Haskell-cafe] Non-termination due to context In-Reply-To: <4B598AF5.3090909@chalmers.se> References: <4B598AF5.3090909@chalmers.se> Message-ID: <59543203684B2244980D7E4057D5FBC10AFC9048@DB3EX14MBXC306.europe.corp.microsoft.com> It's a feature! You have * B is a superclass of A * Eq is a superclass of B So every A dictionary has a B dictionary inside it, and every B dictionary has an Eq dictionary inside it. Now, your instance declaration instance (A a, Eq a) => B a says "if you give me an A dictionary and an Eq dictionary, I'll make you a B dictionary". Now, 'test' needs a (B Int) dictionary. To get one, we need an (A Int) dictionary and an (Eq Int) dictionary. But when solving these sub-problems, GHC assumes that you have in hand a solution to the original problem, this case (B Int) Why? Read the SYB3 paper. OK so now you see the problem: we can solve the (A Int) and (Eq Int) sub-problems by selection from the (B Int) dictionary. Still, I confess that I have not fully grokked the relationship between the SYB3-style recursion stuff and the question of superclasses. So I will think about your example some more, thank you. Meanwhile, it's clear that you are on thin ice. Simon | -----Original Message----- | From: haskell-cafe-bounces@haskell.org [mailto:haskell-cafe-bounces@haskell.org] On | Behalf Of Emil Axelsson | Sent: 22 January 2010 11:25 | To: Haskell Cafe | Subject: [Haskell-cafe] Non-termination due to context | | Hello all! | | Consider the following program: | | > {-# LANGUAGE FlexibleInstances, OverlappingInstances, UndecidableInstances #-} | > | > class B a => A a | > | > instance A Int | > | > class Eq a => B a | > | > instance (A a, Eq a) => B a | > | > eq :: B a => a -> a -> Bool | > eq = (==) | > | > test = 1 `eq` (2::Int) | | (This is a condensed version of a much larger program that I've been | debugging.) | | It compiles just fine, but `test` doesn't terminate (GHCi 6.10.4). If I | change the context `B a` to `Eq a` for the function `eq`, it terminates. | | Although I don't know all the details of the class system, it seems | unintuitive that I can make a program non-terminating just by changing | the context of a function (regardless of UndecidableInstances etc.). | | Is this a bug or a feature? | | / Emil | | _______________________________________________ | Haskell-Cafe mailing list | Haskell-Cafe@haskell.org | http://www.haskell.org/mailman/listinfo/haskell-cafe From daniel.is.fischer at web.de Fri Jan 22 08:41:14 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Fri Jan 22 08:15:08 2010 Subject: [Haskell-cafe] Spelling checker exercise In-Reply-To: <83757D35-C8ED-49B9-9EAA-FED2098C52F9@gmail.com> References: <83757D35-C8ED-49B9-9EAA-FED2098C52F9@gmail.com> Message-ID: <201001221441.15160.daniel.is.fischer@web.de> Am Freitag 22 Januar 2010 07:51:27 schrieb Matthew Phillips: > Hello all, > > sorry to bring up an old chestnut, but I?m trying to improve my > Haskell-fu by writing a small program, and chose Peter Norvig?s spelling > checker as my exercise material (http://norvig.com/spell-correct.html). > > While I?ve gotten it working, and found it quite illuminating, I also > found it to to be very slow. And then I discovered that, of course, > others have been here well before me ([1] and [2]). Those discussions > were very interesting, but the code they refer to is mostly not > available, so the most I?ve gotten out of it so far is that: > > (a) I should be using strict left folds and strict Map insertions for > the word frequency map (this shaved off about a second: ~5s -> ~4s for a > single word on my 2.4GHz MacBook Pro, GHC 6.10.4) (b) I should probably > be using ByteString?s That does help, but the worst part is building the map. That takes a couple of seconds in Python, too. Just building the map takes 1.95s for Python, 3.6s (including GC) with strict ByteStrings, 4.2s with lazy ByteStrings and 6s with plain Strings here. So I'd go with strict ByteStrings, although that takes a little more memory than lazy, but waay less than Strings. > (c) Using Set?s for the edit permutations probably isn?t worth it > (although I found using plain lists made it about a second slower) Might make a difference once you need to take two edit steps on a not very short word. > > (b) is difficult because I?ve used matching patterns plus list > comprehensions to generate the potential edits, and I really like how > elegantly it pans out that way. Because ByteString?s are not lists, I > can?t see a way to keep the current structure and use them. Train with ByteStrings, then do the edits on Strings and pack for lookup. > > The code is at [3] (link to version at time of post). Profiling [4] > shows: > > $ ./spelling becuase +RTS -p > becuase -> because > $ cat spelling.prof > total time = 4.02 secs (201 ticks @ 20 ms) > total alloc = 1,544,257,792 bytes (excludes profiling overheads) > > COST CENTRE MODULE %time %alloc > > train Main 52.7 19.7 > readFile Main 28.9 8.6 > wordsBy Main 10.9 49.5 > toLower Main 7.0 21.8 > ... > > So it appears that ?train" (building the freq map) and ?readFile? in > ?nwords" are the places to hone. readFile does not appear in my profile. If you insert an SCC for updateMap, where updateMap model word = {-# SCC "updateMap" #-} insertWith' (+) word 1 model , you'll see that the really bad citizen is updateMap (splitWords is rather bad, too, together they take some 95% of the time in that profile). But once you start needing two edits (try korrekt), correct and edits1 start to show up. That shows that Norvig's algorithm isn't really good. With two edit steps, you create a _lot_ of strings you need to look up, far more than there are in the map. That takes time. It'll be better to scan the map for entries with an edit distance (< 3) if you have a good method to check that (http://old.nabble.com/haskell-in-online-contests-td26546989.html contains pointers for that). Another thing is allWords = keysSet wordCounts Ouch. For each correction, you construct that set anew. Just use member from Data.Map instead of Data.Set.member and look up the words in the map. > I will look at using Bloom Filters or > Trie?s instead of Data.Map, but I wonder if readFile should be taking > nearly %30 of the run time, even for a 6MB file? No way. But it doesn't seem to, from my GHC's point of view. > > Sorry to dump such a long post on the list ? I?ll understand if no one > can be bothered rehashing this. But, in summary I?d like to know: > > (a) how could I use ByteString?s for this to speed up I/O and reduce > memory usage without losing the nice readability? A small rewrite of your code, I would have designed it slightly differently for using ByteStrings from the beginning, the packing in known and known_edits2 isn't too beautiful. ---------------------------------------------------------------------- {-# LANGUAGE BangPatterns #-} module Main (main) where import qualified Data.ByteString.Char8 as B import Data.Char (toLower) import Data.Map (Map, findWithDefault, insertWith', member) import qualified Data.Map as Map (empty) import Data.Set as Set (Set, fromList, toList, fold, null) import Data.List (inits, tails, foldl') import System.Environment (getArgs) dataFile = "big.txt" alphabet = "abcdefghijklmnopqrstuvwxyz" splitWords :: B.ByteString -> [B.ByteString] splitWords = filter (not . B.null) . B.splitWith isNogud . B.map toLower isNogud :: Char -> Bool isNogud c = c < 'a' || 'z' < c train :: [B.ByteString] -> Map B.ByteString Int train = foldl' updateMap Map.empty where updateMap model word = insertWith' (+) word 1 model nwords :: IO (Map B.ByteString Int) nwords = return . train . splitWords =<< B.readFile dataFile edits1 :: String -> [String] edits1 s = toList . fromList $ deletes ++ transposes ++ replaces ++ inserts where deletes = [a ++ bs | (a, _:bs) <- splits] transposes = [a ++ (b2:b1:bs) | (a, b1:b2:bs) <- splits] replaces = [a ++ (c:bs) | (a, _:bs) <- splits, c <- alphabet] inserts = [a ++ (c:b) | (a, b) <- splits, c <- alphabet] splits = zip (inits s) (tails s) correct :: Map B.ByteString Int -> String -> String correct wordCounts word = B.unpack . fst $ fold maxCount (B.pack "?", 0) candidates where candidates :: Set B.ByteString candidates = known [word] `or` ((known $ edits1 word) `or` known_edits2 word) known_edits2 :: String -> Set B.ByteString known_edits2 w = fromList [w3 | w1 <- edits1 w, w2 <- edits1 w1 , let w3 = B.pack w2, w3 `member` wordCounts] known :: [String] -> Set B.ByteString known ws = fromList [w | w <- map B.pack ws, w `member` wordCounts] maxCount :: B.ByteString -> (B.ByteString, Int) -> (B.ByteString, Int) maxCount word current@(_, currentMax) | count > currentMax = (word, count) | otherwise = current where count = findWithDefault 1 word wordCounts or :: Set B.ByteString -> Set B.ByteString -> Set B.ByteString or a b | Set.null a = b | otherwise = a main :: IO () main = do args <- getArgs wordCounts <- nwords mapM_ (printCorrect wordCounts) args where printCorrect :: Map B.ByteString Int -> String -> IO () printCorrect wordCounts word = putStrLn $ word ++ " -> " ++ correct wordCounts word ---------------------------------------------------------------------- > > (b) should readFile be so slow? > > (c) any other tips Choose a better algorithm for the two-edit case. > > Possibly all my questions could be answered if someone has the code from > the old posts. > > Cheers, > > Matthew. From andrew.polonsky at gmail.com Fri Jan 22 09:16:39 2010 From: andrew.polonsky at gmail.com (Andrew Polonsky) Date: Fri Jan 22 08:48:45 2010 Subject: [Haskell-cafe] problems installing ghc-6.12.1-x86_64 In-Reply-To: <87ljfridhg.fsf@gmail.com> References: <76f550871001210912t6d8430bds86d8298bead30883@mail.gmail.com> <87ljfridhg.fsf@gmail.com> Message-ID: <76f550871001220616r744648d0saf9973df76f7bb02@mail.gmail.com> On Thu, Jan 21, 2010 at 18:17, Ivan Lazar Miljenovic wrote: > Andrew Polonsky writes: >> Help!! ?I am trying to build 6.12 on a fresh 64-bit Ubuntu, with no >> GHC installed yet. ?The compiler itself builds happily, but when I try >> to "make install" the Haskell platform, I eventually get the error > > The Haskell Platform is currently for GHC 6.10.4, not 6.12.1. ?Assuch, > there's no guarantees. Ah, that makes sense of course. But what about cabal? Is it possible to get cabal working without having the ghc package installed? Isn't there a way to set the whole thing up from the latest GHC, without dependence on distribution repositories? Thanks again, Andrew From briand at aracnet.com Fri Jan 22 09:52:45 2010 From: briand at aracnet.com (Brian Denheyer) Date: Fri Jan 22 09:24:54 2010 Subject: [Haskell-cafe] hsql won't install due to system.time In-Reply-To: <9979e72e1001220317r78b15b30mb719d384f91c1c91@mail.gmail.com> References: <9979e72e1001220317r78b15b30mb719d384f91c1c91@mail.gmail.com> Message-ID: <20100122065245.4b1a652f@windy.deldotd.com> On Fri, 22 Jan 2010 11:17:15 +0000 John Lato wrote: > Hello, > > Could this be a global/user install issue? That is, if the old-time > package is installed per-user, and you're trying to install a package > globally, the user-installed packages all show up as hidden, because > they can't be dependencies of a global install. > > This shows up frequently because global installs are the default when > doing "runghc Setup.hs install", but per-user installs are the default > for cabal install. If you use both of these commands, you'll run into > this sooner or later. > > You can run "ghc-pkg list" to get a listing of what's installed where. > If "old-time" is only in the local database, you should reinstall it > into the global database (or install everything globally). > I knew this looked familiar ! It's the dreaded Debian/Global Local conflict problem. Some packages which I can't install using cabal I install Debian packages for, which install globally. Then, naturally, there are Debian packages which won't install (running unstable :-) so I used cabal for those and they install locally. I thought it would be better to keep it local to avoid conflicts, so much for that theory. I basically use Debian for two reasons: to get ghc and to get cabal. After that it seems to me a better idea to stick with cabal rather than the debian packages. Well I know what I'm doing this weekend :-) Thanks very much (everyone) for the help. Brian From jwlato at gmail.com Fri Jan 22 10:15:20 2010 From: jwlato at gmail.com (John Lato) Date: Fri Jan 22 09:47:26 2010 Subject: [Haskell-cafe] Re: Is Haskell capable of matching C in string processing performance? Message-ID: <9979e72e1001220715o3a506793ya2228a7b35189117@mail.gmail.com> > From: Heinrich Apfelmus > Don Stewart wrote: >> jmillikin: >>> Here's the fastest Haskell version I could come up with. It discards >>> all error handling, validation, and correctness in the name of >>> performance, but still can't get anywhere near C: >>> http://hpaste.org/fastcgi/hpaste.fcgi/view?id=16423 >> >> Thanks for posting the code. >> >> You're not using bytestrings?? >> >> They were invented to deal with the problem of [Char] being a poor >> structure for large scale string processing, and you should have no >> problem getting C-like string performance. >> >> ? ? http://www.cse.unsw.edu.au/~dons/papers/CSL06.html > > In my limited experience, ByteStrings are great for reading data, but > not that good for writing data that is being generated on the fly. For > writing, good old difference lists or the ?Builder ?monoid / Put monad > from Data.Binary seem to be best. > If find that this is particularly true if you don't know the length of data to write in advance because it involves lots of new allocations and copying. Using Builder/Put is definitely a better approach. Out of curiousity, has anyone ever tried implementing a LinkedListString in C to check what its performance would be? I expect it would be pretty poor compared to standard strings. Cheers, John From tanielsen at gmail.com Fri Jan 22 10:30:33 2010 From: tanielsen at gmail.com (Tom Nielsen) Date: Fri Jan 22 10:03:01 2010 Subject: [Haskell-cafe] Is Haskell capable of matching C in string processing performance? In-Reply-To: References: <3283f7fe1001212209ndd14978tfa55d3e688d3a0a8@mail.gmail.com> Message-ID: <78dc001e1001220730i3f8f5467t783fd72eb1c359da@mail.gmail.com> > It seems to me this indicates that the big expense here is the call into the I/O system. So let's make fewer I/O calls: import Control.Monad import qualified Data.ByteString.Char8 as S import System.IO null_str1 = S.concat $ take 1000 $ repeat $ S.pack "null" n1 = 5000000 `div` 1000 main = withBinaryFile "out3.json" WriteMode $ \h -> do hPutStr h "[" replicateM_ n1 (S.hPutStr h null_str1) hPutStr h "]" --- this is 10x faster. Whether this is cheating or not depends on what John actually wants to do. Tom From frank at geoinfo.tuwien.ac.at Fri Jan 22 10:35:11 2010 From: frank at geoinfo.tuwien.ac.at (Andrew U. Frank) Date: Fri Jan 22 10:07:20 2010 Subject: [Haskell-cafe] haddock - error Message-ID: <201001221635.12044.frank@geoinfo.tuwien.ac.at> the problem with me getting no haddock output whatsoever was that i had not reconfigured cabal after replacing haddock 2.4 by 2.5 (by installing it with cabal). it would be helpful if there were an error message - but i can clearly see that this is difficult to achieve in this case. thanks for the help! From ozgurakgun at gmail.com Fri Jan 22 10:46:02 2010 From: ozgurakgun at gmail.com (Ozgur Akgun) Date: Fri Jan 22 10:18:10 2010 Subject: [Haskell-cafe] Existential Types (I guess) In-Reply-To: <8b70a98a1001220411u68339a3dy4887dd933604c328@mail.gmail.com> References: <7be1feae1001220331p3f3bc506x3dd3d77c8093767a@mail.gmail.com> <8b70a98a1001220411u68339a3dy4887dd933604c328@mail.gmail.com> Message-ID: <7be1feae1001220746g5603ca10h7e5dece1c8a6e740@mail.gmail.com> OK, I wasn't storing a simple (Num a) in my holder data structure, it was more of a thing implementing one of my type classes. So it knows how to quack, and I can use it now, thanks to Neil's suggestion. I have a (somewhat) heterogeneus list of values, belonging to the same type class, and I just wanted to map a function to that list. Now it works. BTW Tom, Thanks for your suggestion, but it simply doesn't fit my needs this time. But I'll keep your suggestion in mind. Cheers guys! 2010/1/22 Tom Davie > Aside from Neil's point about rank-2 polymorphism, you can of course just > parameterise your NumHolder type... > > data Num a => NumHolder a = NumHolder a > > instance Show a => Show NumHolder a where > show (NumHolder x) = show x > > instance Functor NumHolder where > fmap f (NumHolder a) = NumHolder (f a) > > It depends what you want to do with your NumHolder though. What is the > purpose of this type? > > Bob > > On Fri, Jan 22, 2010 at 11:31 AM, Ozgur Akgun wrote: > >> Dear Cafe, >> >> I can write and use the following, >> >> data IntHolder = IntHolder Integer >> >> instance Show IntHolder where >> show (IntHolder n) = show n >> >> liftInt :: (Integer -> Integer) -> IntHolder -> IntHolder >> liftInt f (IntHolder c) = IntHolder (f c) >> >> But I cannot generalise it to *Num:* >> >> data NumHolder = forall a. Num a => NumHolder a >> >> instance Show NumHolder where >> show (NumHolder n) = show n >> >> liftNum :: (Num a) => (a -> a) -> NumHolder -> NumHolder >> liftNum f (NumHolder c) = NumHolder (f c) >> >> The error message I get is the following: >> >> Couldn't match expected type `a' against inferred type `a1' >> `a' is a rigid type variable bound by >> the type signature for `liftNum' at Lifts.hs:54:16 >> `a1' is a rigid type variable bound by >> the constructor `NumHolder' at Lifts.hs:55:11 >> In the first argument of `f', namely `c' >> In the first argument of `NumHolder', namely `(f c)' >> In the expression: NumHolder (f c) >> >> >> Regards, >> >> >> -- >> Ozgur Akgun >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> >> > -- Ozgur Akgun -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100122/34a885b5/attachment.html From frank at geoinfo.tuwien.ac.at Fri Jan 22 11:08:15 2010 From: frank at geoinfo.tuwien.ac.at (Andrew U. Frank) Date: Fri Jan 22 10:40:27 2010 Subject: [Haskell-cafe] classes with types which are wrapped in Message-ID: <201001221708.16164.frank@geoinfo.tuwien.ac.at> i encounter often a problem when i have a class with some operations (say class X with push) applied to a type A b. I then wrap A in a type A_sup, with some more type parameters and i cannot write a instance of class A_sup because i have a kind mismatch. any suggestions? (reordering of the type parameters of A_sup is not a solution, because another class operates on this parameter) here a simplistic case (i know that A could be reduced to [], my real cases are more complicated). data A b = A b [b] data Asup x ab y = Asup x ab y class X a b where push :: b -> a b -> a b instance X A Int where push b' (A b bs) = A b' (b:bs) instance X Asup Char Int Float where push b' (Asup a b c) = Asup a (push b' b) c -- this does not compile because the number of type arguments for X is wrong. if i try with a type type A_2 b = Asup Char (A b) Float instance X A_2 Int where push b' (Asup a b c) = Asup a (push b' b) c (and --TypeSynonymInstances) i get: Type synonym `A_2' should have 1 argument, but has been given 0 In the instance declaration for `X A_2 Int' what is the solution? thank you! andrew From miguelimo38 at yandex.ru Fri Jan 22 11:07:12 2010 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Fri Jan 22 10:42:59 2010 Subject: [Haskell-cafe] classes with types which are wrapped in In-Reply-To: <201001221708.16164.frank@geoinfo.tuwien.ac.at> References: <201001221708.16164.frank@geoinfo.tuwien.ac.at> Message-ID: <4B59CD30.9060000@yandex.ru> Wrap it in a newtype. That's the only way I know. Andrew U. Frank wrote: > i encounter often a problem when i have a class with some operations (say > class X with push) applied to a type A b. I then wrap A in a type A_sup, with > some more type parameters and i cannot write a instance of class A_sup because > i have a kind mismatch. any suggestions? (reordering of the type parameters of > A_sup is not a solution, because another class operates on this parameter) > > here a simplistic case (i know that A could be reduced to [], my real cases > are more complicated). > > data A b = A b [b] > > data Asup x ab y = Asup x ab y > > class X a b where > push :: b -> a b -> a b > > instance X A Int where > push b' (A b bs) = A b' (b:bs) > > instance X Asup Char Int Float where > push b' (Asup a b c) = Asup a (push b' b) c > > -- this does not compile because the number of type arguments for X is wrong. > > if i try with a type > > type A_2 b = Asup Char (A b) Float > > instance X A_2 Int where > push b' (Asup a b c) = Asup a (push b' b) c > > (and --TypeSynonymInstances) i get: > > Type synonym `A_2' should have 1 argument, but has been given 0 > In the instance declaration for `X A_2 Int' > > what is the solution? thank you! > andrew > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From rwbarton at math.harvard.edu Fri Jan 22 11:25:41 2010 From: rwbarton at math.harvard.edu (Reid Barton) Date: Fri Jan 22 10:57:48 2010 Subject: [Haskell-cafe] classes with types which are wrapped in In-Reply-To: <201001221708.16164.frank@geoinfo.tuwien.ac.at> References: <201001221708.16164.frank@geoinfo.tuwien.ac.at> Message-ID: <20100122162541.GC3688@rwbarton.mit.edu> On Fri, Jan 22, 2010 at 05:08:15PM +0100, Andrew U. Frank wrote: > i encounter often a problem when i have a class with some operations (say > class X with push) applied to a type A b. I then wrap A in a type A_sup, with > some more type parameters and i cannot write a instance of class A_sup because > i have a kind mismatch. any suggestions? (reordering of the type parameters of > A_sup is not a solution, because another class operates on this parameter) > > here a simplistic case (i know that A could be reduced to [], my real cases > are more complicated). > > data A b = A b [b] > > data Asup x ab y = Asup x ab y > > class X a b where > push :: b -> a b -> a b This is a little strange. Are you sure you don't want either class X a where push :: b -> a b -> a b or class X a b where push :: b -> a -> a ? The second one might help you with your subsequent problem (although I didn't understand quite what you were trying to do there). Regards, Reid Barton From jeremy at n-heptane.com Fri Jan 22 11:38:14 2010 From: jeremy at n-heptane.com (Jeremy Shaw) Date: Fri Jan 22 11:10:25 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: <29bf512f1001212037nc213446uf11e813e82f918a@mail.gmail.com> References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> <29bf512f1001212037nc213446uf11e813e82f918a@mail.gmail.com> Message-ID: <1458FF61-A042-41EE-AE80-AFB900E6A0E0@n-heptane.com> Hello, In happstack, there is a Writer monad which holds a list of filters which will be applied to the Response before sending it out. One of these filters is the gzip filter. The compression filters are defined here: http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/Parts.hs The filters are apply when runWebT is called: http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/SimpleHTTP.hs runWebT is called automatically by the top-level function, simpleHTTP, that people actually call in their programs. We do not do anything fancy to cache gzip results to the disk. We don't even assume you *have* a disk. I believe that functionality could be added as a 3rd party library with out modifying core happstack. That is how we would prefer to see it done so that the core is simple, and so that people can implement their own caching system if their needs are different. - jeremy On Jan 21, 2010, at 10:37 PM, Michael Snoyman wrote: > Hey Jeremy, > > I was just wondering: how does Happstack deal with gzip encoding > when it uses sendfile? I can think of a few ways (cache gziped > versions to the disk), but was wondering if you'd already come up > with a good solution. I'm trying to keep all these things in mind > when designing WAI. > > Thanks, > Michael > > On Thu, Jan 14, 2010 at 5:42 PM, Jeremy Shaw > wrote: > Hello, > > Happstack is currently bundled with it's own lazy I/O based HTTP > backend. Ideally, we would like to split that out, and allow > happstack to be used with that backend, hyena, or other options. > > A primary using for using hyena would be for the benefits of > predictability and constant space usage that iterators bring. People > do actually running into the issues that come with lazy I/O, such as > running out of file descriptors, etc. So, I feel like I would want > to stick with using iterators the whole way when using hyena, and > not convert back to a lazy ByteString? > > Happstack now includes support for sendfile(). This is done by > adding another constructor to the Response type: > > (line 94): > http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/HTTP/Types.hs > > Then here on line 197, we match on that case and use sendfile to > send the data: > > http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/HTTP/Handler.hs > > This makes it difficult for use to be compatible with WAI. We can > write a wrapper that converts the sendfile case to use lazy > bytestrings instead, but then we lose the advantages of using > sendfile. > > I wonder if the 'Response' portion of WAI should support all three > currently used methods: > - lazy I/O > - Enumerator > - sendFile > > I haven't really thought about how that would work.. > > hyena currently includes a Network.WAI which uses ByteString: > > http://hackage.haskell.org/packages/archive/hyena/0.1/doc/html/Network-Wai.html > > gotta run, sorry about any typos! > - jeremy > > > > On Jan 13, 2010, at 8:46 AM, Michael Snoyman wrote: > > Hi, > > I recently read (again) the wiki page on a web application > interface[1] for Haskell. It seems like this basically works out to > Hack[2], but using an enumerator instead of lazy bytestring in the > response type. Is anyone working on implementing this? If not, I > would like to create the package, though I wouldn't mind some > community input on some design decisions: > > * Hack has been fairly well-tested in the past year and I think it > provides the features that people want. Therefore, I would want to > model the Environment variable for WAI from Hack. I *could* just > import Hack in WAI and use the exact same Environment data type. > Thoughts? > > * If using a different data type for Environment, should I replace > the String parts with ByteStrings? On the one hand, ByteStrings are > the "correct" data type since the HTTP protocol does not specify a > character encoding; on the other hand, Strings are easier to deal > with. > > * It's simple to write a function to convert between a lazy > bytestring and an enumerator, meaning it would be very easy to write > conversion functions between Hack and WAI applications. This would > make it simpler for people to use either backend. > > If someone else is already working on WAI, please let me know, I > don't want to have duplicate implementations. The idea here is to > consolidate, not split the community. I have a few Hack handlers > (simpleserver, cgi, fastcgi) that I would happily convert to WAI > handlers as well. > > Michael > > [1] http://www.haskell.org/haskellwiki/WebApplicationInterface > [2] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hack > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100122/98908bd0/attachment.html From jmillikin at gmail.com Fri Jan 22 12:40:58 2010 From: jmillikin at gmail.com (John Millikin) Date: Fri Jan 22 12:13:24 2010 Subject: [Haskell-cafe] Is Haskell capable of matching C in string processing performance? In-Reply-To: <20100122062800.GB28541@whirlpool.galois.com> References: <3283f7fe1001212209ndd14978tfa55d3e688d3a0a8@mail.gmail.com> <20100122062800.GB28541@whirlpool.galois.com> Message-ID: <3283f7fe1001220940y67344ffbj6d97957731323918@mail.gmail.com> Correct me if I'm wrong, but ByteStrings can't contain non-ASCII values, right? I'm looking for something like this pseudo-C: typedef void (*Callback)(const uint32_t *chars, size_t n_chars, void *); WriterState *new_state (Callback, void *); I tried using the Text type, but its conversions to Ptr Word16 are all O(n) -- not much better than String. On Thu, Jan 21, 2010 at 22:28, Don Stewart wrote: > jmillikin: >> Here's the fastest Haskell version I could come up with. It discards >> all error handling, validation, and correctness in the name of >> performance, but still can't get anywhere near C: >> http://hpaste.org/fastcgi/hpaste.fcgi/view?id=16423 > > Thanks for posting the code. > > You're not using bytestrings?? > > They were invented to deal with the problem of [Char] being a poor > structure for large scale string processing, and you should have no > problem getting C-like string performance. > > ? ?http://www.cse.unsw.edu.au/~dons/papers/CSL06.html > > -- Don > From sschuldenzucker at uni-bonn.de Fri Jan 22 12:42:04 2010 From: sschuldenzucker at uni-bonn.de (Steffen Schuldenzucker) Date: Fri Jan 22 12:14:10 2010 Subject: [Haskell-cafe] classes with types which are wrapped in In-Reply-To: <201001221708.16164.frank@geoinfo.tuwien.ac.at> References: <201001221708.16164.frank@geoinfo.tuwien.ac.at> Message-ID: <4B59E36C.5070803@uni-bonn.de> Hi Andrew, Andrew U. Frank wrote: > here a simplistic case (i know that A could be reduced to [], my real cases > are more complicated). > > data A b = A b [b] > > data Asup x ab y = Asup x ab y > > class X a b where > push :: b -> a b -> a b > > instance X A Int where > push b' (A b bs) = A b' (b:bs) > > instance X Asup Char Int Float where > push b' (Asup a b c) = Asup a (push b' b) c > > If I understand you correctly, what you want here are type level lambdas. Abusing notation: instance X (\t -> Asup Char t Float) Int where push b' (Asup a b c) = Asup a (push b' b) c However, type level lambdas introduce lots of ambiguities and are therefore AFAIK not supported in haskell[1]. > if i try with a type > > type A_2 b = Asup Char (A b) Float > > instance X A_2 Int where > push b' (Asup a b c) = Asup a (push b' b) c > > (and --TypeSynonymInstances) i get: > > Type synonym `A_2' should have 1 argument, but has been given 0 > In the instance declaration for `X A_2 Int' > However, this error message looks strange. I tried to reduce this to a simpler case[1] and got the same message. Does anyone know why it complains just about the number of type arguments (which is correct) ? -- Steffen [1] http://www.mail-archive.com/haskell-cafe@haskell.org/msg69579.html [2] http://ideone.com/9BAj7MG7 (note that ideone is using ghc-6.8) From jmillikin at gmail.com Fri Jan 22 12:45:37 2010 From: jmillikin at gmail.com (John Millikin) Date: Fri Jan 22 12:18:04 2010 Subject: [Haskell-cafe] Is Haskell capable of matching C in string processing performance? In-Reply-To: <78dc001e1001220730i3f8f5467t783fd72eb1c359da@mail.gmail.com> References: <3283f7fe1001212209ndd14978tfa55d3e688d3a0a8@mail.gmail.com> <78dc001e1001220730i3f8f5467t783fd72eb1c359da@mail.gmail.com> Message-ID: <3283f7fe1001220945v5e9af78cg87acb1d639e8c24e@mail.gmail.com> There's no such thing as "cheating", though that particular code won't work for my purposes because it assumes the output is merely a stream of "null". Fine for the benchmark, but not extractable to the full problem. I wonder: is Handle known to be particularly slow? This code only has to work on Linux and BSD, so if using (for example) a POSIX fd would be much faster, it could bring the Haskell version much closer to C. On Fri, Jan 22, 2010 at 07:30, Tom Nielsen wrote: >> It seems to me this indicates that the big expense here is the call into the I/O system. > > So let's make fewer I/O calls: > > import Control.Monad > import qualified Data.ByteString.Char8 as S > import System.IO > > null_str1 = S.concat $ take 1000 $ repeat $ S.pack "null" > > n1 = 5000000 `div` 1000 > > main = withBinaryFile "out3.json" WriteMode $ \h -> do > ?hPutStr h "[" > ?replicateM_ n1 (S.hPutStr h null_str1) > ?hPutStr h "]" > --- > this is 10x faster. Whether this is cheating or not depends on what > John actually wants to do. > > Tom > From dons at galois.com Fri Jan 22 13:08:17 2010 From: dons at galois.com (Don Stewart) Date: Fri Jan 22 12:40:25 2010 Subject: [Haskell-cafe] Is Haskell capable of matching C in string processing performance? In-Reply-To: <3283f7fe1001220945v5e9af78cg87acb1d639e8c24e@mail.gmail.com> References: <3283f7fe1001212209ndd14978tfa55d3e688d3a0a8@mail.gmail.com> <78dc001e1001220730i3f8f5467t783fd72eb1c359da@mail.gmail.com> <3283f7fe1001220945v5e9af78cg87acb1d639e8c24e@mail.gmail.com> Message-ID: <20100122180817.GB30946@whirlpool.galois.com> jmillikin: > There's no such thing as "cheating", though that particular code won't > work for my purposes because it assumes the output is merely a stream > of "null". Fine for the benchmark, but not extractable to the full > problem. > > I wonder: is Handle known to be particularly slow? This code only has > to work on Linux and BSD, so if using (for example) a POSIX fd would > be much faster, it could bring the Haskell version much closer to C. > Just make sure you're using the same data types and IO methods as in C, and you'll get the same performance. For serializing/writing to packed data, Data.Binary or cereal are a good choice for building bytestrings efficiently, which in turn can be output quickly via bytestring IO. -- Don From Christian.Maeder at dfki.de Fri Jan 22 13:31:45 2010 From: Christian.Maeder at dfki.de (Christian Maeder) Date: Fri Jan 22 13:03:53 2010 Subject: [Haskell-cafe] Re: Why no merge and listDiff? In-Reply-To: References: <61f84eff1001171254pddefd6eo57943727b01d7cb2@mail.gmail.com> <4B573EE4.4010807@dfki.de> Message-ID: <4B59EF11.4070802@dfki.de> Will Ness schrieb: > Christian Maeder dfki.de> writes: > >> Will Ness schrieb: >>> I meant strictly increasing ordered lists, without multiples, for which the > two >>> operations, 'merge' and 'minus', would also have to produce like lists, i.e >>> strictly increasing, without multiples. >> Why don't you use directly Data.Set? > > It says it's based on size balanced Trees? I initially wondered why no such > fundamental operations as merge and minus for _lists_, in the stadard libraries? Yes, balanced trees, which makes insertion and member testing O(log n). > Also, its to/from list conversions are O(n), so probably won't work for > infinite lists. One should not convert much from and to list, but always use operations on sets directly. Sets are finite. I wonder what fundamental advantage there is for infinite strictly increasing lists. > > I was told the trend is to move specifics to hackage packages, but I wonder why > shouldn't such fundamental operations be just included in standard Data.List? Both the current "Set" operations of Data.List and the (so many) functions from Data.Ordlist are only useful for short lists (or other special purposes) because of efficiency. Furthermore, there is some risk that the invariant of lists being (strictly) sorted is violated by accident (programming-error). The ...By-functions allow to further confuse orders. >> There are also bags aka multisets: >> http://hackage.haskell.org/package/multiset > > it's too seems to be based on trees. Yes. > Data.Ordlist seems to be a good match, except for its conflation of > ascending/non-decreasing lists under one "ordered" category (i.e. sets/bags > distinction). If you say, these should be two separate module, I would agree. Cheers Christian From daniel.is.fischer at web.de Fri Jan 22 13:30:16 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Fri Jan 22 13:04:09 2010 Subject: [Haskell-cafe] classes with types which are wrapped in In-Reply-To: <201001221708.16164.frank@geoinfo.tuwien.ac.at> References: <201001221708.16164.frank@geoinfo.tuwien.ac.at> Message-ID: <201001221930.17161.daniel.is.fischer@web.de> Am Freitag 22 Januar 2010 17:08:15 schrieb Andrew U. Frank: > i encounter often a problem when i have a class with some operations > (say class X with push) applied to a type A b. I then wrap A in a type > A_sup, with some more type parameters and i cannot write a instance of > class A_sup because i have a kind mismatch. any suggestions? (reordering > of the type parameters of A_sup is not a solution, because another class > operates on this parameter) > > here a simplistic case (i know that A could be reduced to [], my real > cases are more complicated). > > data A b = A b [b] > > data Asup x ab y = Asup x ab y That doesn't match its use below, perhaps data Asup x ab y = Asup x (A ab) y (matches better with A_2) or use Asup Char (A Int) Float below? > > class X a b where > push :: b -> a b -> a b How about type families? class Y a where type Pushy a :: * push :: Pushy a -> a -> a instance Y (A Int) where type Pushy (A Int) = Int push b' (A b bs) = A b' (b:bs) instance Y (Asup Char (A Int) Float) where type Pushy (Asup Char (A Int) Float) = Int push b' (Asup a b c) = Asup a (push b' b) c > > instance X A Int where > push b' (A b bs) = A b' (b:bs) > > instance X Asup Char Int Float where > push b' (Asup a b c) = Asup a (push b' b) c Missing instance X Int Int, but Int has wrong kind for that :) > > -- this does not compile because the number of type arguments for X is > wrong. > > if i try with a type > > type A_2 b = Asup Char (A b) Float > > instance X A_2 Int where > push b' (Asup a b c) = Asup a (push b' b) c > > (and --TypeSynonymInstances) i get: > > Type synonym `A_2' should have 1 argument, but has been given 0 > In the instance declaration for `X A_2 Int' > > what is the solution? thank you! > andrew From ryani.spam at gmail.com Fri Jan 22 14:50:59 2010 From: ryani.spam at gmail.com (Ryan Ingram) Date: Fri Jan 22 14:23:09 2010 Subject: [Haskell-cafe] Non-termination due to context In-Reply-To: <4B598AF5.3090909@chalmers.se> References: <4B598AF5.3090909@chalmers.se> Message-ID: <2f9b2d31001221150rcea1642l11d7087462ce4ae9@mail.gmail.com> Here's the relevant core for this file (GHC 6.10.4, so I'm a bit out of date): Rec { $dB_rh6 :: Undec.B GHC.Types.Int [GlobalId] [] $dB_rh6 = $dB_rh6 end Rec } Undec.test :: GHC.Bool.Bool [GlobalId] [] Undec.test = GHC.Classes.== @ GHC.Types.Int ($dB_rh6 `cast` ((Undec.:Co:TB) GHC.Types.Int :: (Undec.:TB) GHC.Types.Int ~ (GHC.Classes.:TEq) GHC.Types.Int)) (GHC.Types.I# 1) (GHC.Types.I# 2) The "cast" is saying that the dictionary for B is equivalent to the dictionary for Eq (an optimization for empty classes with one superclass, I guess). "$dB_rh6" is the dictionary for B Int. GHC 'solves' this into a classic looping program. I'm not sure how the derivation for this dictionary goes. -- ryan so, given an A we can just pull the dictionary out of it On Fri, Jan 22, 2010 at 3:24 AM, Emil Axelsson wrote: > Hello all! > > Consider the following program: > >> {-# LANGUAGE FlexibleInstances, OverlappingInstances, UndecidableInstances >> #-} >> >> class B a => A a >> >> instance A Int >> >> class Eq a => B a >> >> instance (A a, Eq a) => B a >> >> eq :: B a => a -> a -> Bool >> eq = (==) >> >> test = 1 `eq` (2::Int) > > (This is a condensed version of a much larger program that I've been > debugging.) > > It compiles just fine, but `test` doesn't terminate (GHCi 6.10.4). If I > change the context `B a` to `Eq a` for the function `eq`, it terminates. > > Although I don't know all the details of the class system, it seems > unintuitive that I can make a program non-terminating just by changing the > context of a function (regardless of UndecidableInstances etc.). > > Is this a bug or a feature? > > / Emil > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- A non-text attachment was scrubbed... Name: undec.core Type: application/octet-stream Size: 2507 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100122/fe82ea38/undec.obj From james at neurogami.com Fri Jan 22 15:41:37 2010 From: james at neurogami.com (James Britt) Date: Fri Jan 22 15:13:47 2010 Subject: [Haskell-cafe] http://trac.haskell.org down? Message-ID: <4B5A0D81.5060509@neurogami.com> Been trying to reach http://trac.haskell.org for most of the morning, but nothing comes up. Seems I'm not alone: http://downforeveryoneorjustme.com/http://trac.haskell.org James -- Neurogami - Smart application development http://www.neurogami.com james@neurogami.com From ndmitchell at gmail.com Fri Jan 22 17:06:03 2010 From: ndmitchell at gmail.com (Neil Mitchell) Date: Fri Jan 22 16:38:09 2010 Subject: [Haskell-cafe] http://trac.haskell.org down? In-Reply-To: <4B5A0D81.5060509@neurogami.com> References: <4B5A0D81.5060509@neurogami.com> Message-ID: <404396ef1001221406waab38ffx175d37131aa6b5e0@mail.gmail.com> Hi community.haskell.org is down as well :-( Thanks, Neil On Fri, Jan 22, 2010 at 8:41 PM, James Britt wrote: > Been trying to reach http://trac.haskell.org for most of the morning, but > nothing comes up. > > Seems I'm not alone: > > http://downforeveryoneorjustme.com/http://trac.haskell.org > > > > James > -- > > Neurogami - Smart application development > > http://www.neurogami.com > > james@neurogami.com > > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From daniel.is.fischer at web.de Fri Jan 22 17:07:11 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Fri Jan 22 16:41:02 2010 Subject: [Haskell-cafe] http://trac.haskell.org down? In-Reply-To: <404396ef1001221406waab38ffx175d37131aa6b5e0@mail.gmail.com> References: <4B5A0D81.5060509@neurogami.com> <404396ef1001221406waab38ffx175d37131aa6b5e0@mail.gmail.com> Message-ID: <201001222307.12201.daniel.is.fischer@web.de> Am Freitag 22 Januar 2010 23:06:03 schrieb Neil Mitchell: > Hi > > community.haskell.org is down as well :-( $ host trac.haskell.org trac.haskell.org is an alias for community.haskell.org. From jeremy at n-heptane.com Fri Jan 22 17:24:19 2010 From: jeremy at n-heptane.com (Jeremy Shaw) Date: Fri Jan 22 16:56:26 2010 Subject: [Haskell-cafe] could we get a Data instance for Data.Text.Text? Message-ID: Hello, Would it be possible to get a Data instance for Data.Text.Text? This would allow us to create a Serialize instance of Text for use with happstack -- which would be extremely useful. We (at seereason) are currently using this patch: http://src.seereason.com/haskell-text-debian/debian/patches/add_Data_instance.patch which basically adds: +textType = mkStringType "Data.Text" + +instance Data Text where + toConstr x = mkStringConstr textType (unpack x) + gunfold _k z c = case constrRep c of + (CharConstr x) -> z (pack [x]) + _ -> error "gunfold for Data.Text" + dataTypeOf _ = textType + This particular implementation avoids exposing the internals of the Data.Text type by casting it to a String in toConstr and gunfold. That is similar to how Data is implemented for some numeric types. However, the space usage of casting in Float to a Double is far less than casting a Text to a String, so maybe that is not a good idea? Alternatively, Data.ByteString just does 'deriving Data'. However, bytestring also exports Data.ByteString.Internal, wheres Data.Text.Internal is not exported. Any thoughts? I would like to get this handled upstream so that all happstack users can benefit from it. - jeremy -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100122/8b8673d8/attachment.html From david.waern at gmail.com Fri Jan 22 17:39:43 2010 From: david.waern at gmail.com (David Waern) Date: Fri Jan 22 17:11:51 2010 Subject: [Haskell-cafe] GHC bug? Cabal bug? Haddock bug? In-Reply-To: References: <694519c51001161141l72eb15b3ob55f515473de2131@mail.gmail.com> <694519c51001161808j103e4c4fx8a6402aef41bde4c@mail.gmail.com> Message-ID: 2010/1/17 Mark Lentczner : > AHA! > >> Note that after running "cabal haddock" we re-build all of our .hi and >> .o files EXCEPT ./dist/build/HSsyb-with-class-0.6.1.o >> >> And now, since TH generates random symbols, we have symbols in the new >> .hi files that aren't in the old (and only) HSsyb-with-class-0.6.1.o. > > So, this leaves us with two questions: > > 1) Why does "cabal haddock" rebuild the .hi and .o files? On the face of it, this seems odd: Build documentation and your library gets rebuilt? Maybe this has already been answered elsewhere: when TH is involved Haddock may rebuild your library. In this case Cabal is directing Haddock's output to the same place that is used for normal builds. This bug has been fixed in Cabal. > 2) Why doesn't Instances.o get rebuilt? Surely this has something to do with the fact that Instances.hs contains only orphan instances. But any answer here just leads to a raft of other questions: > ? ? ? ?Surely this problem would plague other modules have have similar source files? > ? ? ? ?What is Haddock doing? > ? ? ? ?If Haddock needs the .hi files, why not just use them? > ? ? ? ?If it just "builds them to be sure", why in the dist tree and not some place temporary? > ? ? ? ?If is going to build .o files, why not all? Not sure why Instances.o isn't rebuilt. David From gcross at phys.washington.edu Fri Jan 22 18:09:21 2010 From: gcross at phys.washington.edu (Gregory Crosswhite) Date: Fri Jan 22 17:44:32 2010 Subject: [Haskell-cafe] Is Haskell capable of matching C in string processing performance? In-Reply-To: <78dc001e1001220730i3f8f5467t783fd72eb1c359da@mail.gmail.com> References: <3283f7fe1001212209ndd14978tfa55d3e688d3a0a8@mail.gmail.com> <78dc001e1001220730i3f8f5467t783fd72eb1c359da@mail.gmail.com> Message-ID: <9F8ECB38-926C-4318-80E9-E565233C7E86@phys.washington.edu> I would say that counts as cheating because it assumes that knowledge of the input in advance. However, I wonder how it would perform if there were a "reChunk" function that lazily built a new lazy ByteString by merging smaller chunks together --- i.e., it would keep pullings chunks from the ByteString until it reached some threshold size, merge them into a single strict ByteString chunk, and then recursively continue processing the rest of the lazy ByteString in this manner. Cheers, Greg On Jan 22, 2010, at 7:30 AM, Tom Nielsen wrote: >> It seems to me this indicates that the big expense here is the call into the I/O system. > > So let's make fewer I/O calls: > > import Control.Monad > import qualified Data.ByteString.Char8 as S > import System.IO > > null_str1 = S.concat $ take 1000 $ repeat $ S.pack "null" > > n1 = 5000000 `div` 1000 > > main = withBinaryFile "out3.json" WriteMode $ \h -> do > hPutStr h "[" > replicateM_ n1 (S.hPutStr h null_str1) > hPutStr h "]" > --- > this is 10x faster. Whether this is cheating or not depends on what > John actually wants to do. > > Tom From derek.a.elkins at gmail.com Fri Jan 22 20:45:35 2010 From: derek.a.elkins at gmail.com (Derek Elkins) Date: Fri Jan 22 20:17:41 2010 Subject: [Haskell-cafe] Re: Why no merge and listDiff? In-Reply-To: References: <61f84eff1001171254pddefd6eo57943727b01d7cb2@mail.gmail.com> Message-ID: <61f84eff1001221745u11449ab8y60fdc08d14779278@mail.gmail.com> On Wed, Jan 20, 2010 at 9:42 AM, Will Ness wrote: > Derek Elkins gmail.com> writes: >> On Sun, Jan 17, 2010 at 2:22 PM, Will Ness yahoo.com> wrote: >> > Hello cafe, >> > >> > I wonder, if we have List.insert and List.union, why no List.merge (:: Ord > a => >> > [a] -> [a] -> [a]) and no List.minus ? These seem to be pretty general >> > operations. >> >> Presumably by List.minus you mean the (\\) function in Data.List. > > No, it has to search its second list over and over from the start, to be able > to deal with unordered lists, so its performance can't be good. Then use the ordlist one. >> You >> probably also want to look at the package data-ordlist on hackage >> (http://hackage.haskell.org/packages/archive/data-ordlist/0.0.1/doc/html/Data- > OrdList.html) >> which represents sets and bags as ordered lists and has all of the >> operations you mention. > > > I did, thanks again! Although, that package deals with non-decreasing lists, > i.e. lists with multiples possibly. As such, its operations produce non- > decreasing lists, i.e. possibly having multiples too. It is clear that some of the operations are guaranteed to produce sets given sets. The documentation could be better in this regard though. > I meant strictly increasing ordered lists, without multiples, for which the two > operations, 'merge' and 'minus', would also have to produce like lists, i.e > strictly increasing, without multiples. The 'union' and 'minus' functions of ordlist meet this requirement if you satisfy the preconditions. From dons at galois.com Fri Jan 22 21:12:28 2010 From: dons at galois.com (Don Stewart) Date: Fri Jan 22 20:44:50 2010 Subject: [Haskell-cafe] http://trac.haskell.org down? In-Reply-To: <404396ef1001221406waab38ffx175d37131aa6b5e0@mail.gmail.com> References: <4B5A0D81.5060509@neurogami.com> <404396ef1001221406waab38ffx175d37131aa6b5e0@mail.gmail.com> Message-ID: <20100123021228.GC32030@whirlpool.galois.com> We've contacted the hosting company, who had an upgrade last night. Hopefully back up in the next hour. ndmitchell: > Hi > > community.haskell.org is down as well :-( > > Thanks, Neil > > On Fri, Jan 22, 2010 at 8:41 PM, James Britt wrote: > > Been trying to reach http://trac.haskell.org for most of the morning, but > > nothing comes up. > > > > Seems I'm not alone: > > > > http://downforeveryoneorjustme.com/http://trac.haskell.org > > > > > > > > James > > -- > > > > Neurogami - Smart application development > > > > http://www.neurogami.com > > > > james@neurogami.com > > > > > > > > > > _______________________________________________ > > 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 From bos at serpentine.com Fri Jan 22 21:53:52 2010 From: bos at serpentine.com (Bryan O'Sullivan) Date: Fri Jan 22 21:25:57 2010 Subject: [Haskell-cafe] Re: could we get a Data instance for Data.Text.Text? In-Reply-To: References: Message-ID: On Fri, Jan 22, 2010 at 2:24 PM, Jeremy Shaw wrote: > > Would it be possible to get a Data instance for Data.Text.Text? > >From the last time this came up, I gather that the correctish thing to do (for reasons too obscure to me) is to teach SYB and its many cousins about Text, or else there'll be some sort of disturbance in the Force. If that feels too arduous, I'd consider adding your suggested instance of Data until such time as the One True Generics Package emerges to walk the earth. But please give it a think first. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100122/8a222687/attachment.html From mauricio.antunes at gmail.com Fri Jan 22 22:02:07 2010 From: mauricio.antunes at gmail.com (=?ISO-8859-1?Q?Maur=ED=ADcio_CA?=) Date: Fri Jan 22 21:34:44 2010 Subject: [Haskell-cafe] ANN: bindings-DSL 1.0.4 (Category: FFI) Message-ID: Hi, bindings-DSL is a mature and well documented preprocessor domain specific language you can use to generate bindings to a C API. It's based on functionality provided by hsc2hs. These are links to Hackage page and documentation: http://hackage.haskell.org/package/bindings-DSL http://bitbucket.org/mauricio/bindings-dsl New in this version: * Support for C unions. * Use of macros for wider portability. An example on the use of unions follow. Suppose you have: union example { int k; char c[4]; }; Then, using bindings-DSL, you'll write: #starttype union example #union_field k , CInt #union_array_field c , CChar #stoptype Here is a ghci session showing the resulting code: > let value = C'example 1 [] > u'example'k value (2^10) C'example {c'example'k = 1024, c'example'c = [0,4,0,0]} > u'example'c value [1,0,0,0] C'example {c'example'k = 1, c'example'c = [1,0,0,0]} > u'example'c value [0,0,0,1] C'example {c'example'k = 16777216, c'example'c = [0,0,0,1]} Peeking an uninitialized memory address: > v <- alloca $ \p -> peek p :: IO C'example > v C'example {c'example'k = 81842189, c'example'c = [13,-48,-32,4]} Hope it's useful to you. Best, Maur?cio From ekirpichov at gmail.com Sat Jan 23 03:55:40 2010 From: ekirpichov at gmail.com (Eugene Kirpichov) Date: Sat Jan 23 03:27:44 2010 Subject: [Haskell-cafe] Is Haskell capable of matching C in string processing performance? In-Reply-To: <9F8ECB38-926C-4318-80E9-E565233C7E86@phys.washington.edu> References: <3283f7fe1001212209ndd14978tfa55d3e688d3a0a8@mail.gmail.com> <78dc001e1001220730i3f8f5467t783fd72eb1c359da@mail.gmail.com> <9F8ECB38-926C-4318-80E9-E565233C7E86@phys.washington.edu> Message-ID: <5e0214851001230055u6ce011aei99bf40376b94cdbe@mail.gmail.com> Ironically, there's a TODO comment about that in the source of Data.ByteString.Lazy, just below 'copy': http://hackage.haskell.org/packages/archive/bytestring/0.9.0.4/doc/html/src/Data-ByteString-Lazy.html#copy -- TODO defrag func that concatenates block together that are below a threshold -- defrag :: ByteString -> ByteString 2010/1/23 Gregory Crosswhite : > I would say that counts as cheating because it assumes that knowledge of the input in advance. ?However, I wonder how it would perform if there were a "reChunk" function that lazily built a new lazy ByteString by merging smaller chunks together --- i.e., it would keep pullings chunks from the ByteString until it reached some threshold size, merge them into a single strict ByteString chunk, and then recursively continue processing the rest of the lazy ByteString in this manner. > > Cheers, > Greg > > > On Jan 22, 2010, at 7:30 AM, Tom Nielsen wrote: > >>> It seems to me this indicates that the big expense here is the call into the I/O system. >> >> So let's make fewer I/O calls: >> >> import Control.Monad >> import qualified Data.ByteString.Char8 as S >> import System.IO >> >> null_str1 = S.concat $ take 1000 $ repeat $ S.pack "null" >> >> n1 = 5000000 `div` 1000 >> >> main = withBinaryFile "out3.json" WriteMode $ \h -> do >> hPutStr h "[" >> replicateM_ n1 (S.hPutStr h null_str1) >> hPutStr h "]" >> --- >> this is 10x faster. Whether this is cheating or not depends on what >> John actually wants to do. >> >> Tom > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- Eugene Kirpichov Web IR developer, market.yandex.ru From taruti at taruti.net Sat Jan 23 06:43:39 2010 From: taruti at taruti.net (Taru Karttunen) Date: Sat Jan 23 06:15:44 2010 Subject: [Haskell-cafe] Is Haskell capable of matching C in string processing performance? In-Reply-To: <3283f7fe1001220940y67344ffbj6d97957731323918@mail.gmail.com> References: <3283f7fe1001212209ndd14978tfa55d3e688d3a0a8@mail.gmail.com> <20100122062800.GB28541@whirlpool.galois.com> <3283f7fe1001220940y67344ffbj6d97957731323918@mail.gmail.com> Message-ID: <1264246920-sup-9065@oz.taruti.net> Excerpts from John Millikin's message of Fri Jan 22 19:40:58 +0200 2010: > Correct me if I'm wrong, but ByteStrings can't contain non-ASCII > values, right? I'm looking for something like this pseudo-C: > > typedef void (*Callback)(const uint32_t *chars, size_t n_chars, void *); > WriterState *new_state (Callback, void *); > > I tried using the Text type, but its conversions to Ptr Word16 are all > O(n) -- not much better than String. Are you using unicode on the C side with wchar_t? You can have utf-8 inside ByteStrings. - Taru Karttunen From ndmitchell at gmail.com Sat Jan 23 08:57:45 2010 From: ndmitchell at gmail.com (Neil Mitchell) Date: Sat Jan 23 08:29:49 2010 Subject: [Haskell-cafe] Re: could we get a Data instance for Data.Text.Text? In-Reply-To: References: Message-ID: <404396ef1001230557r2d2ecc98o10fcc568f37e9ba6@mail.gmail.com> >> Would it be possible to get a Data instance for Data.Text.Text? > > From the last time this came up, I gather that the correctish thing to do > (for reasons too obscure to me) is to teach SYB and its many cousins about > Text, or else there'll be some sort of disturbance in the Force. No, that's definitely not correct, or even remotely scalable as we increase the number of abstract types in disparate packages. If someone suggests it's necessary for their generics library, I suggest you use Uniplate ;-) There are two options, both listed in the above email. 1) Use string conversion in the instance. This is morally correct, and works perfectly. However, as mentioned, it's not great performing. The Map/Set instances both do a similar trick. 2) Just add deriving on the Data type, and hope no one abuses the internals. This is what ByteString does, it works great, it's fast, but you are violating some amount of abstraction. You have to trust people not to break that abstraction, but it's not a simple abstraction to break - it's the moral equivalent of pointer prodding in a std::string, no one breaks it accidentally. > If that feels too arduous, I'd consider adding your suggested instance of > Data until such time as the One True Generics Package emerges to walk the > earth. But please give it a think first. Data.Data is the one true runtime reflection package, so Data instances are strongly advised, totally ignoring Generics stuff. I would pick option 2, but a Data instance really is useful. Thanks, Neil From nccb2 at kent.ac.uk Sat Jan 23 09:55:01 2010 From: nccb2 at kent.ac.uk (Neil Brown) Date: Sat Jan 23 09:27:04 2010 Subject: [Haskell-cafe] could we get a Data instance for Data.Text.Text? In-Reply-To: References: Message-ID: <4B5B0DC5.1000102@kent.ac.uk> Jeremy Shaw wrote: > Hello, > > Would it be possible to get a Data instance for Data.Text.Text? This > would allow us to create a Serialize instance of Text for use with > happstack -- which would be extremely useful. Last time this came up, I had a look at providing a Data instance for Text, and I "got as far as needing a Data instance for ByteString#, accompanied by an error I don't fully understand, but I think is telling me that things involving magic hashes are magic: Data/Text/Array.hs:104:35: Couldn't match kind `#' against `*' When matching the kinds of `ByteArray# :: #' and `d :: *' Expected type: d Inferred type: ByteArray# In the first argument of `z', namely `Array' " The problem with a Data instance for Text is that it is using this ByteArray# type, which can't easily interact with the Data type-class because it's a special type. I would suggest providing a Data instance for ByteArray#, but I don't think that's possible either. As far as I can understand it all, your Data instance is probably the closest you are going to get to having a decent Data instance without something else (GHC/SYB) changing significantly. Thanks, Neil. From v.dijk.bas at gmail.com Sat Jan 23 10:02:37 2010 From: v.dijk.bas at gmail.com (Bas van Dijk) Date: Sat Jan 23 09:35:01 2010 Subject: [Haskell-cafe] ANNOUNCE: Updates and a new member of the Monadic Regions family Message-ID: Hello, I released updates of all the members of the Monadic Regions family: * http://hackage.haskell.org/package/regions-0.3 - Export the 'Dup' and 'ParentOf' classes from 'Control.Monad.Trans.Region'. - Add: 'mapInternalHandle ? (Handle resource1 ? Handle resource2) ? (RegionalHandle resource1 r ? RegionalHandle resource2 r)'. - Internal refactoring. * http://hackage.haskell.org/package/regions-monadsfd-0.3 * http://hackage.haskell.org/package/regions-monadstf-0.3 * http://hackage.haskell.org/package/usb-safe-0.5.1 - No major changes in these packages just internal refactoring and support for regions-0.3.*. * http://hackage.haskell.org/package/safer-file-handles-0.3 - 'File' is turned into a GADT, it's parameterized with the IOMode and its constructors are exported. - Added support for bytestring IO. - Internal refactoring. * http://hackage.haskell.org/package/explicit-iomodes-0.2 This package is not a member of the family but it is required for 'safer-file-handles'. I released an update which: - Added support for bytestring IO. - Internal refactoring. Additionally I would like to announce a new member of the family: * http://hackage.haskell.org/package/regional-pointers-0.1 to quote the description: "The library allows you to allocate memory in a region yielding a regional pointer to it. When the region terminates all pointers are automatically freed. Most importantly, a pointer can't be returned from the region. So it's impossible to reference unallocated memory." This package need some more work (primarily documentation and testing) so I consider it a beta release. Note that the darcs repositories for all packages are not updated because I can't seem to get a SSH connection with code.haskell.org :-( Happy Haskell Hacking, Bas From v.dijk.bas at gmail.com Sat Jan 23 10:21:35 2010 From: v.dijk.bas at gmail.com (Bas van Dijk) Date: Sat Jan 23 09:53:58 2010 Subject: [Haskell-cafe] Re: ANNOUNCE: Updates and a new member of the Monadic Regions family In-Reply-To: References: Message-ID: On Sat, Jan 23, 2010 at 4:02 PM, Bas van Dijk wrote: > Note that the darcs repositories for all packages are not updated > because I can't seem to get a SSH connection with code.haskell.org :-( I just managed to update the darcs repositories, so you can now browse the sources on line. Bas From alexey.skladnoy at gmail.com Sat Jan 23 10:22:58 2010 From: alexey.skladnoy at gmail.com (Khudyakov Alexey) Date: Sat Jan 23 09:54:22 2010 Subject: [Haskell-cafe] Type level splices and instance deriving Message-ID: <201001231822.58356.alexey.skladnoy@gmail.com> Hello GHC 6.12 introduced type level splices. They are great for instances generation. They allow for much clearer and easier to understand code. However I run into problem with them. It's possible to create instance for type class which doesn't have superclass. If it does have one compiler complains that it could not deduce context. All my attempts to provide context fail. Is that accidental limitation or because of Some Good Reason? Or just due to lack of understanding on my side? Below is simplest example. > {-# LANGUAGE FlexibleInstances #-} > {-# LANGUAGE TemplateHaskell #-} > import Language.Haskell.TH > > -- OK but require FlexibleInstances > makeEq :: Name -> Q [Dec] > makeEq name = > [d| instance Eq $(conT name) where > (==) = undefined > |] > > -- Could not deduce Eq context > makeOrd :: Name -> Q [Dec] > makeOrd name = > [d| instance Ord $(conT name) where > compare = undefined > |] And GHC output: test.hs:14:17: Could not deduce (Eq t) from the context () arising from the superclasses of an instance declaration at test.hs:14:17-32 Possible fix: add (Eq t) to the context of the instance declaration In the instance declaration for `Ord t_aS5' In the Template Haskell quotation [d| instance Ord $(conT name) where { compare = undefined } |] In the expression: [d| instance Ord $(conT name) where { compare = undefined } |] -- Khudyakov Alexey From shan2 at kth.se Sat Jan 23 10:22:30 2010 From: shan2 at kth.se (Seyed Hosein Attarzadeh Niaki) Date: Sat Jan 23 09:54:47 2010 Subject: [Haskell-cafe] ANN: parameterized-data library v0.1.4 Message-ID: <2DEE3F73-CCC5-4EEB-BB4C-CB28EDD5B269@kth.se> Dear Haskell developers, A new version of the parameterized-data library providing fixed-sized vectors (based on the type-level library) is pushed into the repository and uploaded to the Hackage database. This is only a minor update to fix the compatibility issues with base 4, GHC>=6.10 and cabal-install (not backward compatible). Bests, Hosein Attarzadeh -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100123/6dec3e0e/attachment.html From shan2 at kth.se Sat Jan 23 10:32:26 2010 From: shan2 at kth.se (Seyed Hosein Attarzadeh Niaki) Date: Sat Jan 23 10:04:40 2010 Subject: [Haskell-cafe] ANN: ForSyDe DSL v3.1 Message-ID: Dear All, A new version of the ForSyDe DSL is uploaded to the Hackage database. "The ForSyDe (Formal System Design) methodology has been developed with the objective to move system design to a higher level of abstraction and to bridge the abstraction gap by transformational design refinement. This library provides ForSyDe's implementation as a Haskell-embedded Domain Specific Language (DSL). For more information, please see ForSyDe's website: http://www.ict.kth.se/forsyde/." In addition to compatibility with base 4 and GHC 6.10.x, the new version provides more freedom for declaration of process functions (e.g., support for when and let blocks). BR/ Hosein Attarzadeh -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100123/153f6b81/attachment.html From mburrel at uwo.ca Sat Jan 23 10:49:10 2010 From: mburrel at uwo.ca (Mike Burrell) Date: Sat Jan 23 10:21:15 2010 Subject: [Haskell-cafe] ghci debugger, can't set breakpoint Message-ID: <84CABE40-F734-4C3B-942B-19BC6B4F7785@uwo.ca> I recently upgraded from GHC 6.8.2 to GHC 6.10.4 and can no longer set breakpoints the way I'm used to. It seems I can only set breakpoints in the current module. I Googled around and found someone with a similar error message trying to load modules which aren't interpreted, but that's not the case for me as all modules are interpreted. Here's me loading the TypeInference module (where I want to set the breakpoint) directly and having it work. Then I load the Main module and try to set the breakpoint in TypeInference with no luck. Am I setting breakpoints wrong here? Any help would be appreciated. Cheers, Mike GHCi, version 6.10.4: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> :l TypeInference [1 of 3] Compiling Utility ( Utility.lhs, interpreted ) [2 of 3] Compiling Parser ( Parser.hs, interpreted ) Parser.hs:1897:1: Warning: Pattern match(es) are overlapped In a case alternative: _ -> ... [3 of 3] Compiling TypeInference ( TypeInference.lhs, interpreted ) Ok, modules loaded: Parser, TypeInference, Utility. *TypeInference> :break 823 Breakpoint 0 activated at TypeInference.lhs:823:10-14 *TypeInference> :l Main [1 of 7] Compiling Utility ( Utility.lhs, interpreted ) [2 of 7] Compiling Parser ( Parser.hs, interpreted ) Parser.hs:1897:1: Warning: Pattern match(es) are overlapped In a case alternative: _ -> ... [3 of 7] Compiling TypeInference ( TypeInference.lhs, interpreted ) [4 of 7] Compiling Bounds ( Bounds.lhs, interpreted ) [5 of 7] Compiling Interpreter ( Interpreter.lhs, interpreted ) [6 of 7] Compiling PatternMatching ( PatternMatching.lhs, interpreted ) [7 of 7] Compiling Main ( Main.lhs, interpreted ) Ok, modules loaded: Parser, TypeInference, Utility, Main, Bounds, PatternMatching, Interpreter. *Main> :break TypeInference 823 No breakpoints found at that location. *Main> -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 478 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100123/4d225b0a/PGP.bin From joerg.rudnick at t-online.de Sat Jan 23 11:42:50 2010 From: joerg.rudnick at t-online.de (=?UTF-8?B?SsO2cmcgUm9tYW4gUnVkbmljaw==?=) Date: Sat Jan 23 11:14:59 2010 Subject: [Haskell-cafe] hsql won't install due to system.time In-Reply-To: <1264070115-sup-444@nixos> References: <20100120221007.75dfede9@windy.deldotd.com> <1264070115-sup-444@nixos> Message-ID: <4B5B270A.3070009@t-online.de> Hi Marc, I've just finished hsql with up-to-date exception handling, which I will call hsql-1.8.1, as catchSql & handleSql can be regarded as deprecated now -- only having some final testing lest. Excuse me for the delay. Let me know if you want to be a beta tester... ;-) Cheers, Nick Marc Weber wrote: > Hi Brian > > hsql is compatibel with most recent ghc yet. > > You can get patches for the .cabal files here: > http://github.com/MarcWeber/haskell-nix-overlay/tree/master/patches/ > > However the Exception handling has to be rewritten as well. > I wanted to fix this issues for weeks - No time. > > Let me know if you start working on this. > > Marc Weber > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From michael at snoyman.com Sat Jan 23 11:52:01 2010 From: michael at snoyman.com (Michael Snoyman) Date: Sat Jan 23 11:24:06 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: <1458FF61-A042-41EE-AE80-AFB900E6A0E0@n-heptane.com> References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> <29bf512f1001212037nc213446uf11e813e82f918a@mail.gmail.com> <1458FF61-A042-41EE-AE80-AFB900E6A0E0@n-heptane.com> Message-ID: <29bf512f1001230852l5626dfd8r9bfb2bca0c30e8e6@mail.gmail.com> Jeremy, What I meant is, if you use a sendfile system call to send raw files from the disk, how does this interact with gzip compression, which clearly cannot be used when using a sendfile call? I ask because you implied there were significant performance gains from using sendfile. Michael On Fri, Jan 22, 2010 at 6:38 PM, Jeremy Shaw wrote: > Hello, > > In happstack, there is a Writer monad which holds a list of filters which > will be applied to the Response before sending it out. One of these filters > is the gzip filter. > > The compression filters are defined here: > > > http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/Parts.hs > > The filters are apply when runWebT is called: > > > http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/SimpleHTTP.hs > > runWebT is called automatically by the top-level function, simpleHTTP, that > people actually call in their programs. > > > We do not do anything fancy to cache gzip results to the disk. We don't > even assume you *have* a disk. I believe that functionality could be added > as a 3rd party library with out modifying core happstack. That is how we > would prefer to see it done so that the core is simple, and so that people > can implement their own caching system if their needs are different. > > - jeremy > > On Jan 21, 2010, at 10:37 PM, Michael Snoyman wrote: > > Hey Jeremy, > > I was just wondering: how does Happstack deal with gzip encoding when it > uses sendfile? I can think of a few ways (cache gziped versions to the > disk), but was wondering if you'd already come up with a good solution. I'm > trying to keep all these things in mind when designing WAI. > > Thanks, > Michael > > On Thu, Jan 14, 2010 at 5:42 PM, Jeremy Shaw wrote: > >> Hello, >> >> Happstack is currently bundled with it's own lazy I/O based HTTP backend. >> Ideally, we would like to split that out, and allow happstack to be used >> with that backend, hyena, or other options. >> >> A primary using for using hyena would be for the benefits of >> predictability and constant space usage that iterators bring. People do >> actually running into the issues that come with lazy I/O, such as running >> out of file descriptors, etc. So, I feel like I would want to stick with >> using iterators the whole way when using hyena, and not convert back to a >> lazy ByteString? >> >> Happstack now includes support for sendfile(). This is done by adding >> another constructor to the Response type: >> >> (line 94): >> >> http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/HTTP/Types.hs >> >> Then here on line 197, we match on that case and use sendfile to send the >> data: >> >> >> http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack-server/src/Happstack/Server/HTTP/Handler.hs >> >> This makes it difficult for use to be compatible with WAI. We can write a >> wrapper that converts the sendfile case to use lazy bytestrings instead, but >> then we lose the advantages of using sendfile. >> >> I wonder if the 'Response' portion of WAI should support all three >> currently used methods: >> - lazy I/O >> - Enumerator >> - sendFile >> >> I haven't really thought about how that would work.. >> >> hyena currently includes a Network.WAI which uses ByteString: >> >> >> http://hackage.haskell.org/packages/archive/hyena/0.1/doc/html/Network-Wai.html >> >> gotta run, sorry about any typos! >> - jeremy >> >> >> >> On Jan 13, 2010, at 8:46 AM, Michael Snoyman wrote: >> >> Hi, >>> >>> I recently read (again) the wiki page on a web application interface[1] >>> for Haskell. It seems like this basically works out to Hack[2], but using an >>> enumerator instead of lazy bytestring in the response type. Is anyone >>> working on implementing this? If not, I would like to create the package, >>> though I wouldn't mind some community input on some design decisions: >>> >>> * Hack has been fairly well-tested in the past year and I think it >>> provides the features that people want. Therefore, I would want to model the >>> Environment variable for WAI from Hack. I *could* just import Hack in WAI >>> and use the exact same Environment data type. Thoughts? >>> >>> * If using a different data type for Environment, should I replace the >>> String parts with ByteStrings? On the one hand, ByteStrings are the >>> "correct" data type since the HTTP protocol does not specify a character >>> encoding; on the other hand, Strings are easier to deal with. >>> >>> * It's simple to write a function to convert between a lazy bytestring >>> and an enumerator, meaning it would be very easy to write conversion >>> functions between Hack and WAI applications. This would make it simpler for >>> people to use either backend. >>> >>> If someone else is already working on WAI, please let me know, I don't >>> want to have duplicate implementations. The idea here is to consolidate, not >>> split the community. I have a few Hack handlers (simpleserver, cgi, fastcgi) >>> that I would happily convert to WAI handlers as well. >>> >>> Michael >>> >>> [1] http://www.haskell.org/haskellwiki/WebApplicationInterface >>> [2] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hack >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> Haskell-Cafe@haskell.org >>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>> >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100123/755edfb1/attachment.html From jmillikin at gmail.com Sat Jan 23 12:53:46 2010 From: jmillikin at gmail.com (John Millikin) Date: Sat Jan 23 12:26:08 2010 Subject: [Haskell-cafe] Is Haskell capable of matching C in string processing performance? In-Reply-To: <1264246920-sup-9065@oz.taruti.net> References: <3283f7fe1001212209ndd14978tfa55d3e688d3a0a8@mail.gmail.com> <20100122062800.GB28541@whirlpool.galois.com> <3283f7fe1001220940y67344ffbj6d97957731323918@mail.gmail.com> <1264246920-sup-9065@oz.taruti.net> Message-ID: <3283f7fe1001230953i4f9d8ccbuc2435f0a985b9106@mail.gmail.com> I'm using UCS-4, with uint32_t. On Sat, Jan 23, 2010 at 03:43, Taru Karttunen wrote: > Excerpts from John Millikin's message of Fri Jan 22 19:40:58 +0200 2010: >> Correct me if I'm wrong, but ByteStrings can't contain non-ASCII >> values, right? I'm looking for something like this pseudo-C: >> >> ? ? typedef void (*Callback)(const uint32_t *chars, size_t n_chars, void *); >> ? ? WriterState *new_state (Callback, void *); >> >> I tried using the Text type, but its conversions to Ptr Word16 are all >> O(n) -- not much better than String. > > Are you using unicode on the C side with wchar_t? > > You can have utf-8 inside ByteStrings. > > - Taru Karttunen > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From tphyahoo at gmail.com Sat Jan 23 13:38:26 2010 From: tphyahoo at gmail.com (Thomas Hartman) Date: Sat Jan 23 13:10:28 2010 Subject: [Haskell-cafe] where is the eros distribution Message-ID: <910ddf451001231038q3d6a5ae8k838b0e5e5c827fce@mail.gmail.com> I was inspired by the google tech talk and would like to install and play with eros, but the http://darcs.haskell.org/packages/Eros/dist/ address pointed to at http://www.haskell.org/haskellwiki/Eros appears to be obsolete. From michael at snoyman.com Sat Jan 23 14:31:47 2010 From: michael at snoyman.com (Michael Snoyman) Date: Sat Jan 23 14:03:51 2010 Subject: [Haskell-cafe] PROPOSAL: Web application interface In-Reply-To: <29bf512f1001180348i2cd2d97p17ef1510ab8974fe@mail.gmail.com> References: <29bf512f1001170801r15f1537bne4dd71c07b0682b8@mail.gmail.com> <67C931AB-57FC-4891-9037-AAAD8489B7B3@glyphic.com> <29bf512f1001180348i2cd2d97p17ef1510ab8974fe@mail.gmail.com> Message-ID: <29bf512f1001231131q26353618t2248aab5629f0613@mail.gmail.com> Just as an update, I've made the following changes to my WAI git repo ( http://github.com/snoyberg/wai): * I removed the RequestBody(Class) bits, and replaced them with "IO (Maybe ByteString)". This is a good example of tradeoffs versus the enumerator approach (see below). * This might just be bikeshedding, but renamed RequestMethod to Method to make names slightly shorter and more consistent. * I implemented Mark's suggestions of adding support for arbitrary request methods and information on HTTP version. I've been having some off-list discussions about WAI, and have a few issues to bring up. The first is relatively simple: what do we do about consuming the entire request body? Do we leave that as a task to the application, or should the server ensure that the entire request body is consumed? Next, I have made the ResponseBodyClass typeclass specifically with the goal of allowing optimizations for lazy bytestrings and sending files. The former seems far-fetched; the latter provides the ability to use a sendfile system call instead of copying the file data into memory. However, in the presence of gzip encoding, how useful is this optimization? Finally, there is a lot of discussion going on right now about enumerators. The question is whether the WAI protocol should use them. There are two places where they could replace the current offering: request body and response body. In my opinion, there is no major difference between the Hyena definition of an enumerator and the current response body sendByteString method. The former provides two extra features: there's an accumulating parameter passed around, and a method for indicating early termination. However, the accumulating parameter seems unnecesary to me in general, and when needed we can accomplish the same result with MVars. Early termination seems like something that would be unusual in the response context, and could be handled with exceptions. For the request body, there is a significant difference. However, I think that the current approach (called imperative elsewhere) is more in line with how most people would expect to program. At the same time, I believe there is no performance issue going either way, and am open to community input. Michael On Mon, Jan 18, 2010 at 1:48 PM, Michael Snoyman wrote: > Mark, thanks for the response, it's very well thought out. Let me state two > things first to explain some of my design decisions. > > Firstly, I'm shooting for lowest-common-denominator here. Right now, I see > that as the intersection between the CGI backend and a standalone server > backend; I think anything contained in both of those will be contained in > all other backends. If anyone has a contrary example, I'd be happy to see > it. > > Secondly, the WAI is *not* designed to be "user friendly." It's designed to > be efficient and portable. People looking for a user-friendly way to write > applications should be using some kind of frontend, either a framework, or > something like hack-frontend-monadcgi. > > That said, let's address your specific comments. > > > On Mon, Jan 18, 2010 at 8:54 AM, Mark Lentczner wrote: > >> I like this project! Thanks for resurrecting it! >> >> Some thoughts: >> >> Methods in HTTP are extensible. The type RequestMethod should probably >> have a "catchall" constructor >> | Method B.ByteString >> >> Seems logical to me. > > >> Other systems (the WAI proposal on the Wiki, Hack, etc...) have broken the >> path into two parts: scriptName and pathInfo. While I'm not particularly >> fond of those names, they do break the path into "traversed" and >> "non-traversed" portions of the URL. This is very useful for achieving >> "location independence" of one's code. While this API is trying to stay >> agnostic to the web framework, some degree of traversal is pretty universal, >> and I think it would benefit being in here. >> >> Going to the standalone vs CGI example: in a CGI script, scriptName is a > well defined variable. However, it has absolutely no meaning to a standalone > handler. I think we're just feeding rubbish into the system. I'm also not > certain how one could *use* scriptName in any meaningful manner, outside of > trying to reconstruct a URL (more on this topic below). > > >> The fields serverPort, serverName, and urlScheme are typically only used >> by an application to "reconstruct" URLs for inclusion in the response. This >> is a constant source of bugs in many web sites. It is also a problem in >> creating modular web frameworks, since the application can't be unaware of >> its context (unless the server interprets and re-writes HTML and other >> content on the fly - which isn't realistic.) Perhaps a better solution would >> be to pass a "URL generating" function in the Request and hide all this. Of >> course, web frameworks *could* use these data to dispatch on "virtual host" >> like configurations. Though, perhaps that is the provenance of the server >> side of the this API? I don't have a concrete proposal here, just a gut that >> the inclusion of these breaks some amount of encapsulation we'd like to >> achieve for the Applications. >> >> I think it's impossible to ever reconstruct a URL for a CGI application. > I've tried it; once you start dealing with mod_rewrite, anything could > happen. Given that I think we should encourage users to make pretty URLs via > mod_rewrite, I oppose inserting such a function. When I need this kind of > information (many of my web apps do), I've put it in a configuration file. > > However, I don't think it's a good idea to hide information that is > universal to all webapps. urlScheme in particular seems very important to > me; for example, maybe when serving an app over HTTPS you want to use a > secure static-file server as well. Frankly, I don't have a use case for > serverName and serverPort that don't involve reconstructing URLs, but my gut > feeling is better to leave it in the protocol in case it does have a use > case. > > >> The HTTP version information seems to have been dropped from Request. >> Alas, this is often needed when deciding what response headers to generate. >> I'm in favor of a simple data type for this: >> data HttpVersion = Http09 | Http10 | Http11 >> >> I had not thought of that at all, and I like it. However, do we want to > hard-code in all possible HTTP versions? In theory, there could be more > standards in the future. Plus, isn't Google currently working on a more > efficient approach to HTTP that would affect this? > > >> Using ByteString for all the non-body values I find awkward. Take headers, >> for example. The header names are going to come from a list of about 50 well >> known ones. It seems a shame that applications will be littered with >> expressions like: >> >> [(B.pack "Content-Type", B.pack "text/html;charset=UTF-8")] >> >> Seems to me that it would be highly beneficial to include a module, say >> Network.WAI.Header, that defined these things: >> >> [(Hdr.contentType, Hdr.mimeTextHtmlUtf8)] >> >> This approach would make WAI much more top-heavy and prone to becoming > out-of-date. I don't oppose having this module in a separate package, but I > want to keep WAI itself as lite as possible. > > >> Further, since non-fixed headers will be built up out of many little >> String bits, I'd just as soon have the packing and unpacking be done by the >> server side of this API, and let the applications deal with Strings for >> these little snippets both in the Request and the Response. >> >> As I stated at the beginning of this response, there should be a framework > or frontend sitting between WAI and the application. And given that the > actual data on the wire will be represented as a stream of bytes, I'd rather > stick with that. > > For header names, in particular, it might be beneficial (and faster) to >> treat them like RequestMethod and make them a data type with nullary >> constructors for all 47 defined headers, and one ExtensionHeader String >> constructor. >> >> Same comment of top-heaviness. > > >> Finally, note that HTTP/1.1 actually does well define the character >> encoding of these parts of the protocol. It is a bit hard to find in the >> spec, but the request line, status line and headers are all transmitted in >> ISO-8859-1, (with some restrictions), with characters outside the set >> encoded as per RFC 2047 (MIME Message Header extensions). Mind you, I >> believe that most web servers *don't* do the 2047 decoding, and only either >> a) pass the strings as ISO-8859-1 strings, or decode that to native Unicode >> strings. >> >> Thanks for that information, I was unaware. However, I think it still > makes sense to keep WAI as low-level as possible, which would mean a > sequence of bytes. > > Michael > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100123/90f1e4bc/attachment.html From jeremy at n-heptane.com Sat Jan 23 17:57:49 2010 From: jeremy at n-heptane.com (Jeremy Shaw) Date: Sat Jan 23 17:29:55 2010 Subject: [Haskell-cafe] Re: could we get a Data instance for Data.Text.Text? In-Reply-To: <404396ef1001230557r2d2ecc98o10fcc568f37e9ba6@mail.gmail.com> References: <404396ef1001230557r2d2ecc98o10fcc568f37e9ba6@mail.gmail.com> Message-ID: On Sat, Jan 23, 2010 at 7:57 AM, Neil Mitchell wrote: > No, that's definitely not correct, or even remotely scalable as we > increase the number of abstract types in disparate packages. Yes.. happstack is facing another aspect of this scalability issue as well. We have a class, Serialize, which is used to serialize and deserialize data. It builds on the binary library, but adds the ability to version your data types and migrate data from older versions to newer versions. This has a serious scalability issue though, because it requires that each type a user might want to serialize has a Serialize instance. So do we: 1. provide Serialize instances for as many data types from libraries on hackage as we can, resulting in depending on a large number of packages that people are required to install, even though they will only use a small fraction of them. 2. convince people that Serialize deserves the same status as Data, and then convince authors to create Serialize instances for their type? It would be nice, but authors will start complaining if they are asked to provide a zillion other instances for their types as well. And they will be annoyed if they their library has to depend on a bunch of other libraries, just so they can provide some instances that only a small fraction of their users might use. So, this method does not scale as the number of 'interesting' classes grows. 3. let individual users define the Serialize instances as they need them. Unfortunately, if two different library authors defined a Serialize instance for Text in their libraries, you could not use both libraries in your application because of the conflicting Serialize instances. So this method does not scale when the number of libraries using the Serialize class grows. Not really sure what the work around is. #1 could work if there was some way to just selectively install the pieces as you need them. But the only way to do this now would be to create a lot of cabal packages which just defined a single instance -- happstack-text, happstack-map, happstack-time, happstack-etc. One for each package that has types we want to create a serialization instance for... Any other suggestions? - jeremy -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100123/f0e57faf/attachment.html From haskell at kudling.de Sat Jan 23 17:59:46 2010 From: haskell at kudling.de (haskell@kudling.de) Date: Sat Jan 23 17:31:53 2010 Subject: [Haskell-cafe] Failing to install hxt Message-ID: <765086784.208466.1264287586533.JavaMail.open-xchange@oxltgw02.schlund.de> Hi guys, i have some troubles to install hxt. My first naive attempt "cabal install hxt" fails with "cabal: cannot configure hxt-8.5.0. It requires base >=4.2 && <5". I guess that's because i use ghc 6.10.4, since "base-4.2.0.0" depends on "integer-simple" which seems to only come with ghc 6.12. I then tried to install hxt-8.3.2, which seems to be the last version supporting ghc 6.10.4. If fails with: " src/Text/XML/HXT/Parser/TagSoup.hs:292:8: ?? ?Not in scope: `optLookupEntity' cabal: Error: some packages failed to install: hxt-8.3.2 failed during the building phase. The exception was: exit: ExitFailure 1 " I have no idea, what that means. What am i doing wrong? Thanks, Lenny -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100123/701fea53/attachment-0001.html From dons at galois.com Sat Jan 23 18:01:44 2010 From: dons at galois.com (Don Stewart) Date: Sat Jan 23 17:33:49 2010 Subject: [Haskell-cafe] Failing to install hxt In-Reply-To: <765086784.208466.1264287586533.JavaMail.open-xchange@oxltgw02.schlund.de> References: <765086784.208466.1264287586533.JavaMail.open-xchange@oxltgw02.schlund.de> Message-ID: <20100123230144.GB4141@whirlpool.galois.com> haskell: > Hi guys, > > i have some troubles to install hxt. > > My first naive attempt "cabal install hxt" fails with > "cabal: cannot configure hxt-8.5.0. It requires base >=4.2 && <5". > > I guess that's because i use ghc 6.10.4, since > "base-4.2.0.0" depends on "integer-simple" which seems to only come with ghc > 6.12. Looks like the author of hxt has decided to support 6.12 only, at the moment. base (>=4.2 && <5) Ensures this will only work on the 6.12 series of compilers. -- Don From haskell at kudling.de Sat Jan 23 18:09:47 2010 From: haskell at kudling.de (haskell@kudling.de) Date: Sat Jan 23 17:41:50 2010 Subject: [Haskell-cafe] Failing to install hxt In-Reply-To: <20100123230144.GB4141@whirlpool.galois.com> References: <765086784.208466.1264287586533.JavaMail.open-xchange@oxltgw02.schlund.de> <20100123230144.GB4141@whirlpool.galois.com> Message-ID: <752411966.246686.1264288187507.JavaMail.open-xchange@oxltgw16.schlund.de> > Looks like the author of hxt has decided to support 6.12 only, at the > moment. > >? ? ?base (>=4.2 && <5) > > Ensures this will only work on the 6.12 series of compilers. Thanks. I know. My point is, i don't understand why hxt-8.3.2 (base >= 4 && <5) fails to install for me with: " src/Text/XML/HXT/Parser/TagSoup.hs:292:8: ?? ?Not in scope: `optLookupEntity' cabal: Error: some packages failed to install: hxt-8.3.2 failed during the building phase. The exception was: exit: ExitFailure 1 " -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100123/c1dcabe7/attachment.html From dons at galois.com Sat Jan 23 18:10:57 2010 From: dons at galois.com (Don Stewart) Date: Sat Jan 23 17:43:00 2010 Subject: [Haskell-cafe] Failing to install hxt In-Reply-To: <752411966.246686.1264288187507.JavaMail.open-xchange@oxltgw16.schlund.de> References: <765086784.208466.1264287586533.JavaMail.open-xchange@oxltgw02.schlund.de> <20100123230144.GB4141@whirlpool.galois.com> <752411966.246686.1264288187507.JavaMail.open-xchange@oxltgw16.schlund.de> Message-ID: <20100123231057.GC4141@whirlpool.galois.com> haskell: > > Looks like the author of hxt has decided to support 6.12 only, at the > > moment. > > > > base (>=4.2 && <5) > > > > Ensures this will only work on the 6.12 series of compilers. > > Thanks. I know. > > My point is, i don't understand why hxt-8.3.2 (base >= 4 && <5) fails to > install for me with: > > " > src/Text/XML/HXT/Parser/TagSoup.hs:292:8: > Not in scope: `optLookupEntity' > cabal: Error: some packages failed to install: > hxt-8.3.2 failed during the building phase. The exception was: > exit: ExitFailure 1 > " That looks like an error relating to the versoin of tagsoup used? -- Don From nicolas.pouillard at gmail.com Sat Jan 23 18:19:25 2010 From: nicolas.pouillard at gmail.com (Nicolas Pouillard) Date: Sat Jan 23 17:51:29 2010 Subject: [Haskell-cafe] Re: could we get a Data instance for Data.Text.Text? In-Reply-To: References: <404396ef1001230557r2d2ecc98o10fcc568f37e9ba6@mail.gmail.com> Message-ID: <4b5b83fd.0d67f10a.7c61.fffff39e@mx.google.com> On Sat, 23 Jan 2010 16:57:49 -0600, Jeremy Shaw wrote: > On Sat, Jan 23, 2010 at 7:57 AM, Neil Mitchell wrote: > > > > No, that's definitely not correct, or even remotely scalable as we > > increase the number of abstract types in disparate packages. > > > Yes.. happstack is facing another aspect of this scalability issue as well. > We have a class, Serialize, which is used to serialize and deserialize data. > It builds on the binary library, but adds the ability to version your data > types and migrate data from older versions to newer versions. > > This has a serious scalability issue though, because it requires that each > type a user might want to serialize has a Serialize instance. > > So do we: [..] > Any other suggestions? 4. Write a new package: * serialize-text * text-instances (which would be a place holder for more instances) I would go for trying solution 2. and otherwise solution 4. -- Nicolas Pouillard http://nicolaspouillard.fr From haskell at kudling.de Sat Jan 23 18:38:44 2010 From: haskell at kudling.de (haskell@kudling.de) Date: Sat Jan 23 18:10:50 2010 Subject: [Haskell-cafe] Failing to install hxt In-Reply-To: <20100123231057.GC4141@whirlpool.galois.com> References: <765086784.208466.1264287586533.JavaMail.open-xchange@oxltgw02.schlund.de> <20100123230144.GB4141@whirlpool.galois.com> <752411966.246686.1264288187507.JavaMail.open-xchange@oxltgw16.schlund.de> <20100123231057.GC4141@whirlpool.galois.com> Message-ID: <1496899468.246860.1264289924532.JavaMail.open-xchange@oxltgw16.schlund.de> Don Stewart hat am 24. Januar 2010 um 00:10 geschrieben: > haskell: > > > Looks like the author of hxt has decided to support 6.12 only, at the > > > moment. > > > > > >? ? ?base (>=4.2 && <5) > > > > > > Ensures this will only work on the 6.12 series of compilers. > > > > Thanks. I know. > > > > My point is, i don't understand why hxt-8.3.2 (base >= 4 && <5) fails to > > install for me with: > > > > " > > src/Text/XML/HXT/Parser/TagSoup.hs:292:8: > >? ? ?Not in scope: `optLookupEntity' > > cabal: Error: some packages failed to install: > > hxt-8.3.2 failed during the building phase. The exception was: > > exit: ExitFailure 1 > > " > > That looks like an error relating to the versoin of tagsoup used? You're right, thanks. "optLookupEntity" is defined in tagsoup-0.6, but not in tagsoup-0.8. But hxt-8.3.2 broadly requires?tagsoup [http://hackage.haskell.org/package/tagsoup-0.8] ?(>=0.6 && <1). I am no cabal expert. What is the best solution here? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100123/f76d3f0c/attachment.html From nicolas.pouillard at gmail.com Sat Jan 23 18:40:18 2010 From: nicolas.pouillard at gmail.com (Nicolas Pouillard) Date: Sat Jan 23 18:12:27 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: <29bf512f1001230852l5626dfd8r9bfb2bca0c30e8e6@mail.gmail.com> References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> <29bf512f1001212037nc213446uf11e813e82f918a@mail.gmail.com> <1458FF61-A042-41EE-AE80-AFB900E6A0E0@n-heptane.com> <29bf512f1001230852l5626dfd8r9bfb2bca0c30e8e6@mail.gmail.com> Message-ID: <4b5b88e2.0d67f10a.74f7.fffff5c0@mx.google.com> On Sat, 23 Jan 2010 18:52:01 +0200, Michael Snoyman wrote: > Jeremy, > > What I meant is, if you use a sendfile system call to send raw files from > the disk, how does this interact with gzip compression, which clearly cannot > be used when using a sendfile call? I ask because you implied there were > significant performance gains from using sendfile. I guess you can either gzip the file to another temporary one and sendfile the temporary gz one (even maybe cache it) or abandon sendfile and stream out a gzip of file contents. The former could be more performant. Regards, -- Nicolas Pouillard http://nicolaspouillard.fr From dons at galois.com Sat Jan 23 18:48:44 2010 From: dons at galois.com (Don Stewart) Date: Sat Jan 23 18:20:48 2010 Subject: [Haskell-cafe] Failing to install hxt In-Reply-To: <1496899468.246860.1264289924532.JavaMail.open-xchange@oxltgw16.schlund.de> References: <765086784.208466.1264287586533.JavaMail.open-xchange@oxltgw02.schlund.de> <20100123230144.GB4141@whirlpool.galois.com> <752411966.246686.1264288187507.JavaMail.open-xchange@oxltgw16.schlund.de> <20100123231057.GC4141@whirlpool.galois.com> <1496899468.246860.1264289924532.JavaMail.open-xchange@oxltgw16.schlund.de> Message-ID: <20100123234844.GD4141@whirlpool.galois.com> haskell: > > That looks like an error relating to the versoin of tagsoup used? > > You're right, thanks. > "optLookupEntity" is defined in tagsoup-0.6, but not in tagsoup-0.8. > But hxt-8.3.2 broadly requires tagsoup (>=0.6 && <1). > > I am no cabal expert. What is the best solution here? I think the best bet is to: cabal install tagsoup-0.6 --reinstrall And perhaps send the HXT maintainer a cabal patch? -- Don From daniel.is.fischer at web.de Sat Jan 23 18:59:51 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sat Jan 23 18:33:40 2010 Subject: [Haskell-cafe] Failing to install hxt In-Reply-To: <1496899468.246860.1264289924532.JavaMail.open-xchange@oxltgw16.schlund.de> References: <765086784.208466.1264287586533.JavaMail.open-xchange@oxltgw02.schlund.de> <20100123231057.GC4141@whirlpool.galois.com> <1496899468.246860.1264289924532.JavaMail.open-xchange@oxltgw16.schlund.de> Message-ID: <201001240059.51780.daniel.is.fischer@web.de> Am Sonntag 24 Januar 2010 00:38:44 schrieb haskell@kudling.de: > Don Stewart hat am 24. Januar 2010 um 00:10 geschrieben: > > haskell: > > > > Looks like the author of hxt has decided to support 6.12 only, at > > > > the moment. > > > > > > > >? ? ?base (>=4.2 && <5) > > > > > > > > Ensures this will only work on the 6.12 series of compilers. > > > > > > Thanks. I know. > > > > > > My point is, i don't understand why hxt-8.3.2 (base >= 4 && <5) > > > fails to install for me with: > > > > > > " > > > src/Text/XML/HXT/Parser/TagSoup.hs:292:8: > > >? ? ?Not in scope: `optLookupEntity' > > > cabal: Error: some packages failed to install: > > > hxt-8.3.2 failed during the building phase. The exception was: > > > exit: ExitFailure 1 > > > " > > > > That looks like an error relating to the versoin of tagsoup used? > > You're right, thanks. > "optLookupEntity" is defined in tagsoup-0.6, but not in tagsoup-0.8. > But hxt-8.3.2 broadly requires?tagsoup > [http://hackage.haskell.org/package/tagsoup-0.8] ?(>=0.6 && <1). > > > I am no cabal expert. What is the best solution here? cabal unpack hxt-8.3.2 open hxt.cabal in kate, change the range of the required tagsoup to (>= 0.6 && < 0.7) cd hxt-8.3.2 cabal install perhaps not the _best_ solution, but quick and it usually works From derek.a.elkins at gmail.com Sat Jan 23 19:02:43 2010 From: derek.a.elkins at gmail.com (Derek Elkins) Date: Sat Jan 23 18:34:44 2010 Subject: [Haskell-cafe] Re: could we get a Data instance for Data.Text.Text? In-Reply-To: References: <404396ef1001230557r2d2ecc98o10fcc568f37e9ba6@mail.gmail.com> Message-ID: <61f84eff1001231602q61ef3777s56b9b919d430fa@mail.gmail.com> On Sat, Jan 23, 2010 at 4:57 PM, Jeremy Shaw wrote: > ?On Sat, Jan 23, 2010 at 7:57 AM, Neil Mitchell > wrote: > >> >> No, that's definitely not correct, or even remotely scalable as we >> increase the number of abstract types in disparate packages. > > Yes.. happstack is facing another aspect of this scalability issue as well. > We have a class, Serialize, which is used to serialize and deserialize data. > It builds on the binary library, but adds the ability to version your data > types and migrate data from older versions to newer versions. > This has a serious scalability issue though, because it requires that each > type a user might want to serialize has a Serialize instance. > So do we: > ??1. provide Serialize instances for as many data types from libraries on > hackage as we can, resulting in depending on a large number of packages that > people are required to install, even though they will only use a small > fraction of them. > ??2. convince people that Serialize deserves the same status as Data, and > then convince authors to create Serialize instances for their type? It would > be nice, but authors will start complaining if they are asked to provide a > zillion other instances for their types as well. And they will be annoyed if > they their library has to depend on a bunch of other libraries, just so they > can provide some instances that only a small fraction of their users might > use. So, this method does not scale as the number of 'interesting' classes > grows. > ??3. let individual users define the Serialize instances as they need them. > Unfortunately, if two different library authors defined a Serialize instance > for Text in their libraries, you could not use both libraries in your > application because of the conflicting Serialize instances. So this method > does not scale when the number of libraries using the Serialize class grows. > Not really sure what the work around is. #1 could work if there was some way > to just selectively install the pieces as you need them. But the only way to > do this now would be to create a lot of cabal packages which just defined a > single instance -- happstack-text, happstack-map, happstack-time, > happstack-etc. One for each package that has types we want to create a > serialization instance for... > Any other suggestions? > - jeremy The only safe rule is: if you don't control the class, C, or you don't control the type constructor, T, don't make instance C T. Application writers can often relax that rule as the set of dependencies for the whole application is known and in many cases any reasonable instance for a class C and constructor T is acceptable. Under those conditions, the worst-case scenario is that the application writer may need to remove an instance declaration when migrating to new versions of the dependencies. When you control a class C, you should make as many (relevant) type constructors instances of it as is reasonably possible, i.e. without adding any extensive dependencies. So at the very least, all standard type constructors. Similarly for those who control a type constructor T. This is for convenience. These correspond to solutions #1 and #2 only significantly weakened. Definitely, making a package depend on tons of other packages just to add instances is NOT the correct solution. The library writers depending on a package for a class and another package for a type are the problem case. There are three potential solutions in this case which basically are reduce the problem to one of the above three cases. Either introduce a new type and add it to a class, introduce a new class and add the types to it, or try to push the resolution of such things onto the application writer. The first two options have the benefit that they also protect you from the upstream libraries introducing instances that won't work for you. These two options have the drawback that they are usually less convenient to use. The last option has the benefit that it usually corresponds to having a more flexible/generic library, in some cases you can even go so far as to remove your dependence on the libraries altogether. One solution to this problem though it can't be done post-hoc usually, is to simply not use the class mechanism except as a convenience. This has the benefit that it usually leads to more flexibility and it helps to realize the third option above. Using Monoid as an example, one can provide functions of the form: f :: m -> (m -> m -> m) -> ... and then also provide f' = f mempty mappend :: Monoid m => ... The parameters can be collected into a record as well. You could even systematize this into: class C a where getCDict :: CDict a, and then write f :: CDict a -> ... and f' = f getCDict :: C a => ... Whatever one does, do NOT add instances of type constructors you don't control to classes you don't control. This can lead to cases where two libraries can't be used together at all. From jeremy at n-heptane.com Sat Jan 23 19:02:45 2010 From: jeremy at n-heptane.com (Jeremy Shaw) Date: Sat Jan 23 18:35:54 2010 Subject: [Haskell-cafe] Web application interface In-Reply-To: <29bf512f1001230852l5626dfd8r9bfb2bca0c30e8e6@mail.gmail.com> References: <29bf512f1001130646h7c2bbc6cva8c55db2d789e3a0@mail.gmail.com> <29bf512f1001212037nc213446uf11e813e82f918a@mail.gmail.com> <1458FF61-A042-41EE-AE80-AFB900E6A0E0@n-heptane.com> <29bf512f1001230852l5626dfd8r9bfb2bca0c30e8e6@mail.gmail.com> Message-ID: <0B66E6D9-6F35-4583-BAA2-DED43425B58C@n-heptane.com> On Jan 23, 2010, at 10:52 AM, Michael Snoyman wrote: > Jeremy, > > What I meant is, if you use a sendfile system call to send raw files > from the disk, how does this interact with gzip compression, which > clearly cannot be used when using a sendfile call? I ask because you > implied there were significant performance gains from using sendfile. At present there is no mechanism to use sendfile+gzip. The only solution would be to gzip the file in a cache of some sort, and the use sendfile on that. That is just a limitation of the way sendfile works. We do not have anything like that built-in yet.. but you could add in a 3rd party library... - jeremy From nicolas.pouillard at gmail.com Sat Jan 23 19:38:18 2010 From: nicolas.pouillard at gmail.com (Nicolas Pouillard) Date: Sat Jan 23 19:10:23 2010 Subject: [Haskell-cafe] PROPOSAL: Web application interface In-Reply-To: <29bf512f1001231131q26353618t2248aab5629f0613@mail.gmail.com> References: <29bf512f1001170801r15f1537bne4dd71c07b0682b8@mail.gmail.com> <67C931AB-57FC-4891-9037-AAAD8489B7B3@glyphic.com> <29bf512f1001180348i2cd2d97p17ef1510ab8974fe@mail.gmail.com> <29bf512f1001231131q26353618t2248aab5629f0613@mail.gmail.com> Message-ID: <4b5b967a.0d67f10a.7c61.fffff543@mx.google.com> On Sat, 23 Jan 2010 21:31:47 +0200, Michael Snoyman wrote: > Just as an update, I've made the following changes to my WAI git repo ( > http://github.com/snoyberg/wai): > > * I removed the RequestBody(Class) bits, and replaced them with "IO (Maybe > ByteString)". This is a good example of tradeoffs versus the enumerator > approach (see below). * Are you sure that a strict bytestring is fine here? Can the request body be used to upload large data? If so why not use a lazy one, not (only) for its laziness but for being a list of chunks that fits well into memory caches... * I would call ResponseBody a ResponseReceiver given its use and the sigs of the methods. * Why not use sendLazyByteString in sendFile as a default method, this will fix your "TODO" since I believe the chunk size would be a good one. * Maybe a ResponseReceiver Handle instance could be provided. Since it requires no data type definition and would make an orphan instance elsewhere. Maybe a one for sockets would make sense as well. > * This might just be bikeshedding, but renamed RequestMethod to Method to > make names slightly shorter and more consistent. Good for me > * I implemented Mark's suggestions of adding support for arbitrary request > methods and information on HTTP version. Nice > I've been having some off-list discussions about WAI, and have a few issues > to bring up. The first is relatively simple: what do we do about consuming > the entire request body? Do we leave that as a task to the application, or > should the server ensure that the entire request body is consumed? Good question, is there something in the HTTP spec about this. I don't think so, and I think it would make sense to give up early if you consider the input as garbage. > Next, I have made the ResponseBodyClass typeclass specifically with the goal > of allowing optimizations for lazy bytestrings and sending files. The former > seems far-fetched; the latter provides the ability to use a sendfile system > call instead of copying the file data into memory. However, in the presence > of gzip encoding, how useful is this optimization? It is useful anyway. > Finally, there is a lot of discussion going on right now about enumerators. > The question is whether the WAI protocol should use them. There are two > places where they could replace the current offering: request body and > response body. > > In my opinion, there is no major difference between the Hyena definition of > an enumerator and the current response body sendByteString method. The > former provides two extra features: there's an accumulating parameter passed > around, and a method for indicating early termination. However, the > accumulating parameter seems unnecesary to me in general, and when needed we > can accomplish the same result with MVars. Early termination seems like > something that would be unusual in the response context, and could be > handled with exceptions. IORefs could be sufficient (instead of MVars) but this seems a bit ugly compared to the accumulator. In the other hand sometimes you don't need the accumulator and so just pass a dump unit. If we live in IO yes exceptions could do that. However the point of the Either type is to remind you that you have two cases to handle. > For the request body, there is a significant difference. However, I think > that the current approach (called imperative elsewhere) is more in line with > how most people would expect to program. At the same time, I believe there > is no performance issue going either way, and am open to community input. Why an imperative approach would be more in line when using a purely functional language? Regards, -- Nicolas Pouillard http://nicolaspouillard.fr From lennart at augustsson.net Sat Jan 23 19:52:30 2010 From: lennart at augustsson.net (Lennart Augustsson) Date: Sat Jan 23 19:24:34 2010 Subject: [Haskell-cafe] Re: could we get a Data instance for Data.Text.Text? In-Reply-To: <61f84eff1001231602q61ef3777s56b9b919d430fa@mail.gmail.com> References: <404396ef1001230557r2d2ecc98o10fcc568f37e9ba6@mail.gmail.com> <61f84eff1001231602q61ef3777s56b9b919d430fa@mail.gmail.com> Message-ID: > The only safe rule is: if you don't control the class, C, or you don't > control the type constructor, T, don't make instance C T. I agree in principle, but in the real world you can't live by this rule. Example, I want to use Uniplate to traverse the tree built by haskell-src-exts, Using Data.Data is too slow, so I need to make my own instances. HSE provides like 50 types that need instances, and it has to be exactly those types. Also, Uniplate requires instances of a particular class it has. I don't own either of these packages. Including the HSE instances in Uniplate would just be plain idiotic. Including the Uniplate instances with HSE would make some sense, but would make HSE artificially depend on Uniplate for those who don't want the instances. So, what's left is to make orphan instances (that I own). It's not ideal, but I don't see any alternative to it. -- Lennart From christopher.t.wagner at gmail.com Sat Jan 23 19:55:56 2010 From: christopher.t.wagner at gmail.com (Chris Wagner) Date: Sat Jan 23 19:28:03 2010 Subject: [Haskell-cafe] Installing "encoding" package from Hackage Message-ID: <1264294556.3562.5.camel@dell-desktop.example.com> Hi all, I'm trying to install the "encoding" package using cabal, but I'm getting an error about a missing "HaXml" module... --------------------------------------------------------------------- chris@desktop:~$ cabal install encoding Resolving dependencies... /tmp/encoding-0.6.26119/encoding-0.6.2/Data/Encoding/Preprocessor/XMLMappingBuilder.hs:16:7: Could not find module `Text.XML.HaXml.XmlContent': Use -v to see a list of the files searched for. cabal: Error: some packages failed to install: encoding-0.6.2 failed during the configure step. The exception was: exit: ExitFailure 1 --------------------------------------------------------------------- (I'm actually interested in using the "idiii" package, of which "encoding" is a dependency.) Any help/insight is much appreciated! Thanks! Chris W. From mattphil at gmail.com Sun Jan 24 00:19:58 2010 From: mattphil at gmail.com (Matthew Phillips) Date: Sat Jan 23 23:52:11 2010 Subject: [Haskell-cafe] Spelling checker exercise In-Reply-To: <201001221441.15160.daniel.is.fischer@web.de> References: <83757D35-C8ED-49B9-9EAA-FED2098C52F9@gmail.com> <201001221441.15160.daniel.is.fischer@web.de> Message-ID: Thanks very much Daniel for giving my (amateurish!) exercise such an in-depth a look-over. Comments inline below. On 23/01/2010, at 12:11 AM, Daniel Fischer wrote: > Am Freitag 22 Januar 2010 07:51:27 schrieb Matthew Phillips: >> Hello all, >> >> sorry to bring up an old chestnut, but I?m trying to improve my >> Haskell-fu by writing a small program, and chose Peter Norvig?s spelling >> checker as my exercise material (http://norvig.com/spell-correct.html). >> >> While I?ve gotten it working, and found it quite illuminating, I also >> found it to to be very slow. And then I discovered that, of course, >> others have been here well before me ([1] and [2]). Those discussions >> were very interesting, but the code they refer to is mostly not >> available, so the most I?ve gotten out of it so far is that: >> >> (a) I should be using strict left folds and strict Map insertions for >> the word frequency map (this shaved off about a second: ~5s -> ~4s for a >> single word on my 2.4GHz MacBook Pro, GHC 6.10.4) (b) I should probably >> be using ByteString?s > > That does help, but the worst part is building the map. That takes a couple > of seconds in Python, too. Just building the map takes 1.95s for Python, > 3.6s (including GC) with strict ByteStrings, 4.2s with lazy ByteStrings and > 6s with plain Strings here. I get the Python version running in about 1s, compared to 5.6s for the Haskell: $ time python spelling.py because real 0m1.071s user 0m0.821s sys 0m0.139s $ time ./spelling becuase becuase -> because real 0m5.589s user 0m4.554s sys 0m0.307s And, strangely, the rewrite you provided (I called it "spelling_df") runs a fair bit slower: $ time ./spelling_df becuase becuase -> because real 0m8.087s user 0m6.966s sys 0m0.193s $ time ./spelling korrekt korrekt -> correct real 0m5.970s user 0m4.885s sys 0m0.300s $ time ./spelling_df korrekt korrekt -> correct real 0m8.616s user 0m7.538s sys 0m0.187s >> The code is at [3] (link to version at time of post). Profiling [4] >> shows: >> >> $ ./spelling becuase +RTS -p >> becuase -> because >> $ cat spelling.prof >> total time = 4.02 secs (201 ticks @ 20 ms) >> total alloc = 1,544,257,792 bytes (excludes profiling overheads) >> >> COST CENTRE MODULE %time %alloc >> >> train Main 52.7 19.7 >> readFile Main 28.9 8.6 >> wordsBy Main 10.9 49.5 >> toLower Main 7.0 21.8 >> ... >> >> So it appears that ?train" (building the freq map) and ?readFile? in >> ?nwords" are the places to hone. > > readFile does not appear in my profile. Apologies, I should have said that I?d inserted some SCC?s to try to tease out the cost of readFile (i.e. {-# SCC "readFile"}). > If you insert an SCC for updateMap, > > where updateMap model word = {-# SCC "updateMap" #-} insertWith' (+) word 1 > model > > , you'll see that the really bad citizen is updateMap (splitWords is rather > bad, too, together they take some 95% of the time in that profile). Maybe I'm doing this wrong, but I see "splitWords" in spelling_df taking 80% of runtime. Adding SCC's like this: splitWords = {-# SCC "filter" #-} filter (not . B.null) . {-# SCC "splitWith" #-} B.splitWith isNogud . {-# SCC "toLower" #-} B.map toLower gives me: splitWords Main 216 1 0.0 0.0 78.6 91.8 filter Main 217 1 1.9 3.0 78.6 91.8 splitWith Main 218 1 28.4 36.8 76.7 88.8 isNogud Main 221 6488666 4.2 4.1 4.2 4.1 toLower Main 219 1 44.2 47.9 44.2 47.9 i.e. it seems that "splitWith" and "toLower" (!) are the culprits. Why, I have no idea. Am I reading this wrong? > But once you start needing two edits (try korrekt), correct and edits1 > start to show up. That shows that Norvig's algorithm isn't really good. > With two edit steps, you create a _lot_ of strings you need to look up, far > more than there are in the map. That takes time. It'll be better to scan > the map for entries with an edit distance (< 3) if you have a good method > to check that > (http://old.nabble.com/haskell-in-online-contests-td26546989.html contains > pointers for that). Will have a look at that: it looks like it'll be very informative. > Another thing is > > allWords = keysSet wordCounts > > Ouch. For each correction, you construct that set anew. Just use member > from Data.Map instead of Data.Set.member and look up the words in the map. Whoops! Just to be clear though: Haskell will memoise the result of "allWords" for a given invocation of "correct"? So this would only make a large difference for multiple corrections? (which I wasn't worrying about for the moment). The change seems to wipe off about 0.2s on average. >> I will look at using Bloom Filters or >> Trie?s instead of Data.Map, but I wonder if readFile should be taking >> nearly %30 of the run time, even for a 6MB file? > > No way. But it doesn't seem to, from my GHC's point of view. Just to be sure I wasn't using the SCC incorrectly, I split out the readFile call into "myReadFile". The prof line comes out as: myReadFile Main 210 1 35.8 8.6 35.8 8.6 i.e. 35.8% of runtime. >> Sorry to dump such a long post on the list ? I?ll understand if no one >> can be bothered rehashing this. But, in summary I?d like to know: >> >> (a) how could I use ByteString?s for this to speed up I/O and reduce >> memory usage without losing the nice readability? And thanks for the other small tips (e.g. findWithDefault), and I didn't know you could use let the way you did either. Cheers, Matthew. From michael at snoyman.com Sun Jan 24 01:12:58 2010 From: michael at snoyman.com (Michael Snoyman) Date: Sun Jan 24 00:45:01 2010 Subject: [Haskell-cafe] PROPOSAL: Web application interface In-Reply-To: <4b5b967a.0d67f10a.7c61.fffff543@mx.google.com> References: <29bf512f1001170801r15f1537bne4dd71c07b0682b8@mail.gmail.com> <67C931AB-57FC-4891-9037-AAAD8489B7B3@glyphic.com> <29bf512f1001180348i2cd2d97p17ef1510ab8974fe@mail.gmail.com> <29bf512f1001231131q26353618t2248aab5629f0613@mail.gmail.com> <4b5b967a.0d67f10a.7c61.fffff543@mx.google.com> Message-ID: <29bf512f1001232212w6065b341uf261e24ac7eeb6e2@mail.gmail.com> On Sun, Jan 24, 2010 at 2:38 AM, Nicolas Pouillard < nicolas.pouillard@gmail.com> wrote: > On Sat, 23 Jan 2010 21:31:47 +0200, Michael Snoyman > wrote: > > Just as an update, I've made the following changes to my WAI git repo ( > > http://github.com/snoyberg/wai): > > > > * I removed the RequestBody(Class) bits, and replaced them with "IO > (Maybe > > ByteString)". This is a good example of tradeoffs versus the enumerator > > approach (see below). > > * Are you sure that a strict bytestring is fine here? Can the request body > be used to upload large data? If so why not use a lazy one, not (only) > for its laziness but for being a list of chunks that fits well into memory > caches... > > Sorry, this is where I should have put in some documentation. The IO (Maybe ByteString) returns chunks of strict bytestring until it encounters the end of the body. If we were to use a lazy bytestring, we would either need lazy I/O or to read everything into memory (which is what we're trying to avoid). The handler has the prerogative to determine chunk size. * I would call ResponseBody a ResponseReceiver given its use and the sigs > of the methods. > > * Why not use sendLazyByteString in sendFile as a default method, this > will fix your "TODO" since I believe the chunk size would be a good one. > > * Maybe a ResponseReceiver Handle instance could be provided. Since it > requires no data type definition and would make an orphan instance > elsewhere. > Maybe a one for sockets would make sense as well. > > Sorry, I added a few more patches since sending this e-mail. I did away with ResponseBody as well, and replaced it with Either FilePath ((ByteString -> IO ()) -> IO ()). This is *very* close to the Hyena version in my opinion, with three differences (I think I've written these elsewhere, so sorry if I'm repeating myself). 1) It provides the option of providing optimized file sending, as per the Happstack sendfile system call. I was concerned at first that we might wish to provide sending multiple files, but I think people will prefer the simplicity that comes without having a typeclass. I'm completely open to revisiting this issue, as I have no strong feelings. 2) There is no "accumulating parameter" as there is with Hyena. In the general case, I don't think it's necesary, and when it is, we can use MVars. 3) There is no built in way to force early termination. I think this is a better approach, since early termination would be an exceptional situation. Forcing the application to check a return value each time would be overhead that would rarely be used, and we can achieve the same effect with an exception. Sorry for not sending this update earlier, but I only finished at about 2:30 last night. I found it difficult to write coherently. > * This might just be bikeshedding, but renamed RequestMethod to Method to > > make names slightly shorter and more consistent. > > Good for me > > > * I implemented Mark's suggestions of adding support for arbitrary > request > > methods and information on HTTP version. > > Nice > > > I've been having some off-list discussions about WAI, and have a few > issues > > to bring up. The first is relatively simple: what do we do about > consuming > > the entire request body? Do we leave that as a task to the application, > or > > should the server ensure that the entire request body is consumed? > > Good question, is there something in the HTTP spec about this. I don't > think > so, and I think it would make sense to give up early if you consider the > input as garbage. > > What do you mean by this? That we don't need to consume that input at all, or that the server should be held responsible for "/dev/null"ing the data? > Next, I have made the ResponseBodyClass typeclass specifically with the > goal > > of allowing optimizations for lazy bytestrings and sending files. The > former > > seems far-fetched; the latter provides the ability to use a sendfile > system > > call instead of copying the file data into memory. However, in the > presence > > of gzip encoding, how useful is this optimization? > > It is useful anyway. > > > Finally, there is a lot of discussion going on right now about > enumerators. > > The question is whether the WAI protocol should use them. There are two > > places where they could replace the current offering: request body and > > response body. > > > > In my opinion, there is no major difference between the Hyena definition > of > > an enumerator and the current response body sendByteString method. The > > former provides two extra features: there's an accumulating parameter > passed > > around, and a method for indicating early termination. However, the > > accumulating parameter seems unnecesary to me in general, and when needed > we > > can accomplish the same result with MVars. Early termination seems like > > something that would be unusual in the response context, and could be > > handled with exceptions. > > IORefs could be sufficient (instead of MVars) but this seems a bit ugly > compared to the accumulator. In the other hand sometimes you don't need > the accumulator and so just pass a dump unit. If we live in IO yes > exceptions > could do that. However the point of the Either type is to remind you that > you have two cases to handle. > > > For the request body, there is a significant difference. However, I think > > that the current approach (called imperative elsewhere) is more in line > with > > how most people would expect to program. At the same time, I believe > there > > is no performance issue going either way, and am open to community input. > > Why an imperative approach would be more in line when using a purely > functional language? > > Regards, > > -- > Nicolas Pouillard > http://nicolaspouillard.fr > Because I don't think it really *is* an imperative approach. For that matter, enumerators are frankly also an "imperative approach." It's frankly a silly distinction IMO. The question is whether this is a *good* approach. I think passing in an output function fits very nicely with Haskell. The question to me lies more on the request side than the response side. Basically, should the application provide a caller or a callee for reading the request body? Most of the time, the latter is simpler to write I believe. Ha! I finally found the article I'd read a while ago demonstrating this point in C. You can obviously disagree with the sentiment there, but I've found the point to be true in Haskell as well: http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100124/48372193/attachment.html From jsnow at cs.pdx.edu Sat Jan 23 21:04:12 2010 From: jsnow at cs.pdx.edu (Jim Snow) Date: Sun Jan 24 02:01:25 2010 Subject: [Haskell-cafe] ANN: GlomeTrace raytracing library Message-ID: <4B5BAA9C.1080008@cs.pdx.edu> I have uploaded to hackage a new version of my ray-tracer, Glome. In previous releases, Glome was a monolithic application. In this release, the core algorithms have been abstracted out into a pair of libraries, GlomeVec and GlomeTrace. GlomeVec is a vector library. It's not necessarily any better than any of the other vector libraries on Hackage, but it's fairly simple and does what I need it to do. Also included with GlomeVec is a solid texture library, which has a perlin noise function that may be useful for other projects. GlomeTrace contains constructors for building scenes out of basic primitives like spheres, cones, triangles, and grouping them, moving them around, and performing boolean operations on them, and functions to test rays for intersection against these objects. It also has some higher-level operations, like tracing a ray corresponding to a certain x/y coordinate within the camera's field of view, and returning the color by recursively tracing rays against the scene. (Recursion comes into play if the object is reflective.) GlomeTrace uses a typeclass called Solid for geometric primitives, and the composite primitives that are built up from other primitives use an existential type SolidItem that is just a container for all types that are instances of Solid, so it should be quite easy for an application to add new primitives of its own and have them integrate nicely with the ones that are already defined, just by making them instances of Solid. One very useful composite primitive is a BIH (Bounding Interval Hierarchy), which is a type of automatically-constructed tree of bounding volumes used to speed up the process of tracing a ray against many objects. Constructing a bih is easy: just pass a list of SolidItems to the bih constructor, and it returns a "Bih" object that is itself a SolidItem, so you can trace rays against it as if it were a single primitive. GlomeTrace and GlomeVec now have (partial) haddock documentation so it should be easier to understand the code than it was previously. There is also a (somewhat out of date) tutorial linked to from the Haskell wiki: http://www.haskell.org/haskellwiki/Glome Glome the application requires OpenGL for display, but GlomeVec and GlomeTrace do not. -jim Packages: http://hackage.haskell.org/package/GlomeVec http://hackage.haskell.org/package/GlomeTrace http://hackage.haskell.org/package/glome-hs From sanzhiyan at gmail.com Sun Jan 24 03:33:03 2010 From: sanzhiyan at gmail.com (Andrea Vezzosi) Date: Sun Jan 24 03:05:06 2010 Subject: [Haskell-cafe] SYB <> very, very mysteriously In-Reply-To: References: <740BE15A-8247-422E-B0FD-D52CC11717E4@n-heptane.com> <8625cd9c0912050238g2ed403a4u1c0e82262f57168e@mail.gmail.com> Message-ID: <8625cd9c1001240033l67a5a086v140d4930bdd5f25e@mail.gmail.com> On Mon, Dec 7, 2009 at 3:38 PM, David Fox wrote: > On Sat, Dec 5, 2009 at 2:38 AM, Andrea Vezzosi wrote: >> On Fri, Dec 4, 2009 at 8:51 PM, Jeremy Shaw wrote: >>> I have stripped things down to the bare minimum, and test under GHC 6.10, >>> GHC 6.12, Linux, and Mac OS X. Results are consistent. >>> >>> In the following code, >>> >>> ?1. if you load the code into ghci and evaluate e it will hang, but >>> (defaultValueD dict) :: Expression returns fine >>> ?2. if you change the gunfold instance for Proposition to, error "gunfold" >>> it stops hanging -- even though this code is never called. >>> ?3. if you change, ( Data ctx [Expression], Sat (ctx Expression) => Data ctx >>> Expression, to (Data ctx Expression, ....) => ... it stops hanging. >>> >>> If someone could explain why each of these cases perform as they do, that >>> would be awesome! Right now it is a big mystery to me.. e calls dict .. and >>> there is only one instance of dict available, which should call error right >>> away. I can't see how something could get in the way there... >>> >> >> It's less of a mystery if you think about the actual dictionaries ghc >> uses to implement typeclasses. >> The instance for Data ctx [a] depends on Data ctx a, so by requiring >> Data ctx [Expression] in the Data ctx Expression instance you're >> indeed making a loop there, though typeclasses do allow this, and the >> implementation has to be lazy enough to permit it. >> Strange that with a direct Data ctx Expression => Data ctx Expression >> loop we don't get the same problem. >> The reason the implementation of Proposition's gunfold matters is >> probably that k gets passed the dictionary for Data DefaultD >> Expression at the site of its call and some optimization is making it >> stricter than necessary. >> >> Looks like we need a ghc dev here to fully unravel the mystery, in the >> meantime i'll try to reduce the test case even further. > > I have posted a ghc bug for this: > http://hackage.haskell.org/trac/ghc/ticket/3731 > and an syb-with-class bug, in case it is not a ghc bug (perhaps due to > undecidable instances?):http://code.google.com/p/syb-with-class/issues/detail?id=3 > While trying to make the test case on the ghc trac self-contained I've found a workaround which involves changing the Default [a] instance in happstack-data. I've attached the patch. I don't know why it works with certainity, so it'd be nice if you could test it in a large codebase at least. The problem is that one should work out how all these dictionaries get constructed, and that means staring at a lot of Core. -------------- next part -------------- A non-text attachment was scrubbed... Name: workaround-for-default-wrt-http___hackage_haskell_org_trac_ghc_ticket_3731.dpatch Type: application/octet-stream Size: 2026 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100124/aea97d8f/workaround-for-default-wrt-http___hackage_haskell_org_trac_ghc_ticket_3731.obj From haskell at kudling.de Sun Jan 24 06:18:18 2010 From: haskell at kudling.de (haskell@kudling.de) Date: Sun Jan 24 05:50:23 2010 Subject: [Haskell-cafe] Failing to install hxt In-Reply-To: <20100123234844.GD4141@whirlpool.galois.com> References: <765086784.208466.1264287586533.JavaMail.open-xchange@oxltgw02.schlund.de> <20100123230144.GB4141@whirlpool.galois.com> <752411966.246686.1264288187507.JavaMail.open-xchange@oxltgw16.schlund.de> <20100123231057.GC4141@whirlpool.galois.com> <1496899468.246860.1264289924532.JavaMail.open-xchange@oxltgw16.schlund.de> <20100123234844.GD4141@whirlpool.galois.com> Message-ID: <2101515252.543723.1264331898129.JavaMail.open-xchange@oxltgw17.schlund.de> > I think the best bet is to: > >? ? ?cabal install tagsoup-0.6 --reinstrall This somehow didn't work, since hxt-3.8.2 insisted on using tagsoup-0.8 even when i removed every?tagsoup-0.8 directory. > And perhaps send the HXT maintainer a cabal patch? Ok, did this. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100124/c9ea5590/attachment.html From spam at scientician.net Sun Jan 24 06:23:46 2010 From: spam at scientician.net (Bardur Arantsson) Date: Sun Jan 24 05:56:14 2010 Subject: [Haskell-cafe] Re: PROPOSAL: Web application interface In-Reply-To: <29bf512f1001231131q26353618t2248aab5629f0613@mail.gmail.com> References: <29bf512f1001170801r15f1537bne4dd71c07b0682b8@mail.gmail.com> <67C931AB-57FC-4891-9037-AAAD8489B7B3@glyphic.com> <29bf512f1001180348i2cd2d97p17ef1510ab8974fe@mail.gmail.com> <29bf512f1001231131q26353618t2248aab5629f0613@mail.gmail.com> Message-ID: Michael Snoyman wrote: [--snip--] > Next, I have made the ResponseBodyClass typeclass specifically with the goal > of allowing optimizations for lazy bytestrings and sending files. The former > seems far-fetched; the latter provides the ability to use a sendfile system > call instead of copying the file data into memory. However, in the presence > of gzip encoding, how useful is this optimization? [--snip--] I'm hoping that the "Web" bit in your project title doesn't literally mean that WAI is meant to be restricted to solely serving content to browsers. With that caveat in mind: For non-WWW HTTP servers it can be extremely useful to have sendfile. An example is my Haskell UPnP Media Server (hums) application. It's sending huge files (AVIs, MP4s, etc.) over the network and since these files are already compressed as much as they're ever going to be, gzip would be useless. The CPU load of my hums server went from 2-5% to 0% when streaming files just from switching from a Haskell I/O based solution to proper sendfile. Lack of proper support for sendfile() was indeed one of the reasons that I chose to roll my own HTTP server for hums. I should note that this was quite a while ago and I haven't really gone back to reevaluate that choice -- there's too many HTTP stacks to choose from right now and I don't have the time to properly evaluate them all. For this type of server, response *streaming* is also extremely important for those cases where you cannot use sendfile, so I'd hate to see a standard WAI interface preclude that. (No, lazy I/O is NOT an option -- the HTTP clients in a typical UPnP media client behave so badly that you'll run out of file descriptors in no time. Trust me, I've tried.) Cheers, From haskell at kudling.de Sun Jan 24 06:24:37 2010 From: haskell at kudling.de (haskell@kudling.de) Date: Sun Jan 24 05:56:43 2010 Subject: [Haskell-cafe] Failing to install hxt In-Reply-To: <201001240059.51780.daniel.is.fischer@web.de> References: <765086784.208466.1264287586533.JavaMail.open-xchange@oxltgw02.schlund.de> <20100123231057.GC4141@whirlpool.galois.com> <1496899468.246860.1264289924532.JavaMail.open-xchange@oxltgw16.schlund.de> <201001240059.51780.daniel.is.fischer@web.de> Message-ID: <1504586192.543843.1264332277646.JavaMail.open-xchange@oxltgw17.schlund.de> Thank you, that worked. I wonder two things: 1) How to downgrade cabal packages? Just installing tagsoup-0.6 and removing every trace of tagsoup-0.8 somehow didn't work for me. cabal still insisted that there should be a?tagsoup-0.8. 2) Is the commonly used version-scheming >= XYZ ideal? Maybe package maintainers should depend on exactly one version they know that works? I mean how can you guarantee, that every future version of a package will work? Daniel Fischer hat am 24. Januar 2010 um 00:59 geschrieben: > cabal unpack hxt-8.3.2 > > open hxt.cabal in kate, change the range of the required tagsoup to > (>= 0.6 && < 0.7) > > cd hxt-8.3.2 > cabal install > > perhaps not the _best_ solution, but quick and it usually works > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100124/486293dd/attachment.html From ndmitchell at gmail.com Sun Jan 24 06:49:53 2010 From: ndmitchell at gmail.com (Neil Mitchell) Date: Sun Jan 24 06:21:55 2010 Subject: [Haskell-cafe] Re: could we get a Data instance for Data.Text.Text? In-Reply-To: References: <404396ef1001230557r2d2ecc98o10fcc568f37e9ba6@mail.gmail.com> <61f84eff1001231602q61ef3777s56b9b919d430fa@mail.gmail.com> Message-ID: <404396ef1001240349x6843a686if6f398eb0512994b@mail.gmail.com> Hi, The problem with Data for Text isn't that we have to write a new instance, but that you could argue that proper handling of Text with Data would not be using a type class, but have special knowledge baked in to Data. That's far worse than the Serialise problem mentioned above, and no one other than the Data authors could solve it. Of course, I don't believe that, but it is a possible interpretation. The Serialise problem is a serious one. I can't think of any good solutions, but I recommend you give knowledge of your serialise class to Derive (http://community.haskell.org/~ndm/derive/) and then at least the instances can be auto-generated. Writing lots of boilerplate and regularly ripping it up is annoying, setting up something to generate it for you reduces the pain. >> The only safe rule is: if you don't control the class, C, or you don't >> control the type constructor, T, don't make instance C T. > > I agree in principle, but in the real world you can't live by this rule. > Example, I want to use Uniplate to traverse the tree built by haskell-src-exts, > Using Data.Data is too slow, so I need to make my own instances. > HSE provides like 50 types that need instances, and it has to be > exactly those types. > Also, Uniplate requires instances of a particular class it has. Read my recent blog post (http://neilmitchell.blogspot.com/2010/01/optimising-hlint.html), I optimised Uniplate for working with HSE on top of the Data instances - it's now significantly faster in some cases, which may mean you don't need to resort to the Direct stuff. Of course, if you do, then generating them with Derive is the way to go. Thanks, Neil From daniel.is.fischer at web.de Sun Jan 24 06:52:10 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sun Jan 24 06:25:57 2010 Subject: [Haskell-cafe] Spelling checker exercise In-Reply-To: References: <83757D35-C8ED-49B9-9EAA-FED2098C52F9@gmail.com> <201001221441.15160.daniel.is.fischer@web.de> Message-ID: <201001241252.10357.daniel.is.fischer@web.de> Am Sonntag 24 Januar 2010 06:19:58 schrieb Matthew Phillips: > Thanks very much Daniel for giving my (amateurish!) exercise such an > in-depth a look-over. Comments inline below. > > On 23/01/2010, at 12:11 AM, Daniel Fischer wrote: > > > > That does help, but the worst part is building the map. That takes a > > couple of seconds in Python, too. Just building the map takes 1.95s > > for Python, 3.6s (including GC) with strict ByteStrings, 4.2s with > > lazy ByteStrings and 6s with plain Strings here. Correction: I took the total time for a no-argument run for the time it took Python to build the map, adding timing for the map-building, that says it takes ~1.45 seconds. I'm clueless as to what Python needs the remaining half second for. > > I get the Python version running in about 1s, compared to 5.6s for the > Haskell: $ python --version Python 2.6 With psyco.full(): $ time python ./norvig.py becuase Trained in 1.16967606544 seconds ./norvig.py because 1.52user 0.08system 0:01.60elapsed 100%CPU without psyco: $ time python ./norvig.py becuase Trained in 1.45706319809 seconds ./norvig.py because 1.95user 0.08system 0:02.03elapsed 100%CPU $ time python ./norvig.py Trained in 1.46250891685 seconds ./norvig.py 1.95user 0.09system 0:02.04elapsed 100%CPU > > $ time python spelling.py > because > > real 0m1.071s > user 0m0.821s > sys 0m0.139s > > $ time ./spelling becuase > becuase -> because > > real 0m5.589s > user 0m4.554s > sys 0m0.307s > > And, strangely, the rewrite you provided (I called it "spelling_df") > runs a fair bit slower: > > $ time ./spelling_df becuase > becuase -> because > > real 0m8.087s > user 0m6.966s > sys 0m0.193s > > $ time ./spelling korrekt > korrekt -> correct > > real 0m5.970s > user 0m4.885s > sys 0m0.300s > > $ time ./spelling_df korrekt > korrekt -> correct > > real 0m8.616s > user 0m7.538s > sys 0m0.187s > I think I know what happened here: $ ghc -fforce-recomp --make matthew -o matthew0 [1 of 1] Compiling Main ( matthew.hs, matthew.o ) Linking matthew0 ... $ ghc -O2 -fforce-recomp --make matthew -o matthew2 [1 of 1] Compiling Main ( matthew.hs, matthew.o ) Linking matthew2 ... $ time ./matthew0 becuase becuase -> because 7.07user 0.21system 0:07.28elapsed 99%CPU $ time ./matthew2 becuase becuase -> because 6.01user 0.19system 0:06.21elapsed 100%CPU $ ghc -fforce-recomp --make spellingBS -o spelling0 [1 of 1] Compiling Main ( spellingBS.hs, spellingBS.o ) Linking spelling0 ... $ ghc -O2 -fforce-recomp --make spellingBS -o spelling2 [1 of 1] Compiling Main ( spellingBS.hs, spellingBS.o ) Linking spelling2 ... $ time ./spelling0 becuase becuase -> because 9.78user 0.09system 0:09.87elapsed 100%CPU $ time ./spelling2 becuase becuase -> because 3.57user 0.03system 0:03.60elapsed 100%CPU I habitually compile all code with -O2, unless I have a specific reason not to. I tend to forget that some compile without optimisations. For some kinds of code that makes hardly any difference, for others it makes a big difference. *** Don't even think of using ByteStrings without optimising. *** > > > > readFile does not appear in my profile. > > Apologies, I should have said that I?d inserted some SCC?s to try to > tease out the cost of readFile (i.e. {-# SCC "readFile"}). > > > If you insert an SCC for updateMap, > > > > where updateMap model word = {-# SCC "updateMap" #-} insertWith' (+) > > word 1 model > > > > , you'll see that the really bad citizen is updateMap (splitWords is > > rather bad, too, together they take some 95% of the time in that > > profile). > > Maybe I'm doing this wrong, but I see "splitWords" in spelling_df taking > 80% of runtime. Adding SCC's like this: > > splitWords = {-# SCC "filter" #-} filter (not . B.null) . {-# SCC > "splitWith" #-} B.splitWith isNogud . {-# SCC "toLower" #-} B.map > toLower > > gives me: > > splitWords Main 216 1 0.0 0.0 78.6 > 91.8 filter Main 217 1 1.9 3.0 78.6 > 91.8 splitWith Main 218 1 28.4 36.8 > 76.7 88.8 isNogud Main 221 6488666 4.2 4.1 > 4.2 4.1 toLower Main 219 1 44.2 47.9 > 44.2 47.9 > > i.e. it seems that "splitWith" and "toLower" (!) are the culprits. Why, > I have no idea. > > Am I reading this wrong? > No, you're just compiling it wrong :) If I profile without optimising, I get Sun Jan 24 11:37 2010 Time and Allocation Profiling Report (Final) pspellingBS0 +RTS -P -RTS becuase total time = 16.46 secs (823 ticks @ 20 ms) total alloc = 4,088,410,184 bytes (excludes profiling overheads) COST CENTRE MODULE %time %alloc ticks bytes toLower Main 36.3 45.9 299 468806205 splitWith Main 30.6 33.9 252 346657565 train Main 25.8 13.5 212 138466403 isNogud Main 4.3 3.8 35 38931996 filter Main 2.1 2.7 17 27466769 which is compatible with your results. With -O2: Sun Jan 24 11:33 2010 Time and Allocation Profiling Report (Final) pspellingBS +RTS -P -RTS becuase total time = 5.66 secs (283 ticks @ 20 ms) total alloc = 708,686,372 bytes (excludes profiling overheads) COST CENTRE MODULE %time %alloc ticks bytes updateMap Main 68.6 76.9 194 136314135 toLower Main 16.6 0.9 47 1622182 splitWith Main 6.7 14.3 19 25366835 train Main 3.5 2.5 10 4362826 filter Main 2.1 4.4 6 7736998 splitWords Main 1.8 0.0 5 0 which gives a completely different picture. Still, toLower takes a significant part of the time, we can drastically reduce that by exploiting the fact that we don't need to handle the whole Unicode complexity: Sun Jan 24 11:53 2010 Time and Allocation Profiling Report (Final) pspellingBSW +RTS -P -RTS becuase total time = 4.72 secs (236 ticks @ 20 ms) total alloc = 708,686,372 bytes (excludes profiling overheads) COST CENTRE MODULE %time %alloc ticks bytes updateMap Main 76.3 76.9 180 136314135 splitWith Main 9.7 14.3 23 25366835 filter Main 5.1 4.4 12 7736998 train Main 3.0 2.5 7 4362826 splitWords Main 2.1 0.0 5 0 isNogud Main 2.1 0.0 5 0 mkLow Main 1.7 0.9 4 1622182 And, without profiling: $ time ./spellingBSW becuase becuase -> because 2.84user 0.03system 0:02.88elapsed 99%CPU Finally, building the set of two-step edits takes longer than the additional lookups: $ time ./spellingBSW becuase becuase -> because 2.84user 0.03system 0:02.88elapsed 99%CPU $ time ./spellingBSW korrekt korrekt -> correct 3.50user 0.02system 0:03.52elapsed 100%CPU vs. $ time ./spellingBSWL becuase becuase -> because 2.79user 0.04system 0:02.83elapsed 100%CPU $ time ./spellingBSWL3 korrekt korrekt -> correct 3.20user 0.02system 0:03.23elapsed 99%CPU Which is reached with ---------------------------------------------------------------------- {-# LANGUAGE BangPatterns #-} module Main (main) where import qualified Data.ByteString.Char8 as B import qualified Data.ByteString as BS import Data.Bits import Data.Word (Word8) import Data.Char (toLower) import Data.Map (Map, findWithDefault, insertWith', keysSet, empty, member) import qualified Data.Map as Map (lookup, empty, size) import Data.Set (toList, fromList) import Data.List (inits, tails, foldl') import System.Environment (getArgs) dataFile = "big.txt" alphabet = "abcdefghijklmnopqrstuvwxyz" splitWords :: B.ByteString -> [B.ByteString] splitWords = {-# SCC "filter" #-} filter (not . BS.null) . {-# SCC "splitWith" #-} BS.splitWith isNogud . {-# SCC "mkLow" #-} BS.map mkLow mkLow :: Word8 -> Word8 mkLow x = x .|. 32 isNogud :: Word8 -> Bool isNogud c = c < 97 || 122 < c train :: [B.ByteString] -> Map B.ByteString Int train = foldl' updateMap Map.empty where updateMap model word = {-# SCC "updateMap" #-} insertWith' (+) word 1 model nwords :: IO (Map B.ByteString Int) nwords = (return $!) . train . splitWords =<< B.readFile dataFile edits1 :: String -> [String] edits1 s = deletes ++ transposes ++ replaces ++ inserts where deletes = [a ++ bs | (a, _:bs) <- splits] transposes = [a ++ (b2:b1:bs) | (a, b1:b2:bs) <- splits] replaces = [a ++ (c:bs) | (a, _:bs) <- splits, c <- alphabet] inserts = [a ++ (c:b) | (a, b) <- splits, c <- alphabet] splits = zip (inits s) (tails s) correct :: Map B.ByteString Int -> String -> String correct wordCounts word = B.unpack $ maxCount (B.pack "?") 0 candidates where candidates :: [B.ByteString] candidates = known [word] `or` ((known e1) `or` known_edits2) e1 :: [String] e1 = toList . fromList $ edits1 word known_edits2 :: [B.ByteString] known_edits2 = [w3 | w1 <- e1, w2 <- edits1 w1, let w3 = B.pack w2, w3 `member` wordCounts] known :: [String] -> [B.ByteString] known ws = {-# SCC "known" #-} [w | w <- map B.pack ws, w `member` wordCounts] maxCount :: B.ByteString -> Int -> [B.ByteString] -> B.ByteString maxCount best cmax (word:more) | cmax < count = maxCount word count more | otherwise = maxCount best cmax more where count = findWithDefault 1 word wordCounts maxCount best _ _ = best or :: [B.ByteString] -> [B.ByteString] -> [B.ByteString] or a b | null a = b | otherwise = a main :: IO () main = do args <- getArgs wordCounts <- nwords mapM_ (printCorrect wordCounts) args where printCorrect :: Map B.ByteString Int -> String -> IO () printCorrect wordCounts word = putStrLn $ word ++ " -> " ++ correct wordCounts word ---------------------------------------------------------------------- > > But once you start needing two edits (try korrekt), correct and edits1 > > start to show up. That shows that Norvig's algorithm isn't really > > good. With two edit steps, you create a _lot_ of strings you need to > > look up, far more than there are in the map. That takes time. It'll be > > better to scan the map for entries with an edit distance (< 3) if you > > have a good method to check that Indeed: $ time ./nLDBSWSpelling becuase becuase -> because 2.84user 0.02system 0:02.86elapsed 100%CPU $ time ./nLDBSWSpelling korrekt korrekt -> correct 2.83user 0.05system 0:02.88elapsed 100%CPU > > (http://old.nabble.com/haskell-in-online-contests-td26546989.html > > contains pointers for that). > > Will have a look at that: it looks like it'll be very informative. > > > Another thing is > > > > allWords = keysSet wordCounts > > > > Ouch. For each correction, you construct that set anew. Just use > > member from Data.Map instead of Data.Set.member and look up the words > > in the map. > > Whoops! Just to be clear though: Haskell will memoise the result of > "allWords" for a given invocation of "correct"? Yes. But not across different invocations. > So this would only make a large difference for multiple corrections? Right. But that's the interesting use case, isn't it? > (which I wasn't worrying about for the moment). > The change seems to wipe off about 0.2s on average. > Which is pretty bad for multiple corrections. > >> I will look at using Bloom Filters or > >> Trie?s instead of Data.Map, but I wonder if readFile should be taking > >> nearly %30 of the run time, even for a 6MB file? > > > > No way. But it doesn't seem to, from my GHC's point of view. > > Just to be sure I wasn't using the SCC incorrectly, I split out the > readFile call into "myReadFile". The prof line comes out as: > > myReadFile Main 210 1 35.8 8.6 > 35.8 8.6 > > i.e. 35.8% of runtime. > Can I see the exact code which gives that profile? Somehow, things which shouldn't must be attributed to readFile. > >> Sorry to dump such a long post on the list ? I?ll understand if no > >> one can be bothered rehashing this. But, in summary I?d like to know: > >> > >> (a) how could I use ByteString?s for this to speed up I/O and reduce > >> memory usage without losing the nice readability? > > And thanks for the other small tips (e.g. findWithDefault), and I didn't > know you could use let the way you did either. > > Cheers, > > Matthew. From daniel.is.fischer at web.de Sun Jan 24 07:58:56 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sun Jan 24 07:32:43 2010 Subject: [Haskell-cafe] Failing to install hxt In-Reply-To: <1504586192.543843.1264332277646.JavaMail.open-xchange@oxltgw17.schlund.de> References: <765086784.208466.1264287586533.JavaMail.open-xchange@oxltgw02.schlund.de> <201001240059.51780.daniel.is.fischer@web.de> <1504586192.543843.1264332277646.JavaMail.open-xchange@oxltgw17.schlund.de> Message-ID: <201001241358.56626.daniel.is.fischer@web.de> Am Sunday 24 January 2010 12:24:37 schrieben Sie: > Thank you, that worked. > > > I wonder two things: > > > 1) How to downgrade cabal packages? Just installing tagsoup-0.6 and > removing every trace of tagsoup-0.8 somehow didn't work for me. cabal > still insisted that there should be a?tagsoup-0.8. Hm, I'd think if there's no trace of tagsoup-0.8, cabal would use the installed versions to satisfy dependencies by preference. But maybe, because it sees version 0.8 available, it prefers to use the latest version available and allowed. > > > 2) Is the commonly used version-scheming >= XYZ ideal? No. Far from it. It's rotten, as you saw. > Maybe package maintainers should depend on exactly one version > they know that works? I mean how can you guarantee, that every > future version of a package will work? > You can't. Well, if you only use map, filter and arithmetics, build-depends: base is a pretty safe bet, but otherwise, adhere to the recommended dependency- scheme, build-depends: foo >= X.Y.Z && < U Specifying one exact version is too restrictive, you'll end up with everybody having umpteen versions of almost all packages installed. Minor version bumps which leave the API unchanged shouldn't break anything, small additions to the API should rarely break things, so if people adhere to http://www.haskell.org/haskellwiki/Package_versioning_policy , build-depends: foo >= X.Y.Z && < X.(Y+1) should be almost safe, build-depends: foo >= X.Y.Z && < (X+1) should be fine for relatively stable packages like base. From apfelmus at quantentunnel.de Sun Jan 24 08:07:59 2010 From: apfelmus at quantentunnel.de (Heinrich Apfelmus) Date: Sun Jan 24 07:40:24 2010 Subject: [Haskell-cafe] Re: Space Efficiency When Sorting a List of Many Lists In-Reply-To: <0D54968D-B3BF-48EF-B6E1-9DA9D7C461F9@me.com> References: <20100110210516.8A0F03244F8@www.haskell.org> <0D54968D-B3BF-48EF-B6E1-9DA9D7C461F9@me.com> Message-ID: Peter Green wrote: > >>> Another interesting problem is starting from a file of single wagers >>> and >>> trying to compress them (i.e. inverse of 'explosion'. I believe this >>> problem is analogous to Set Cover and therefore NP-Complete. Heuristics >>> are the order of the day here. >> >> Interesting indeed! What kind of heuristics do you employ there? It >> seems quite difficult to me, somehow. > > Essentially wager generation in multi-leg races works like this: > > (1) We have estimated win probabilities for the entrants in each of the > race legs. Assume that I have a black box which produces these estimated > probabilities. > > (2) We generate the CP of the entrant numbers in the race fields: Leg 1 > Entants x Leg 2 Entrants x.. > For each combination generated by the CP, we apply some formula to the > probabilities associated with combination entrant numbers to arrive at a > decision about whether or not that particular combination represents a > viable wager. > > (3) If a combination does represent a viable wager, we then need to > ensure that we have sized its wager amount in a correct and optimal manner. > > This gives output looking like: > > 1, 1, 2, 3 - $1.10 > 1, 1, 2, 4 - $1.20 > .. > .. > 15, 15, 15, 12, - $0.35 > > Unfortunately these are hard to compress well - and that is ignoring > issues of what to do about differing wager sizes when we can match two > combinations for merging together. > > So one possible hack is to insert step 1(a) where we k-means cluster the > win probabilities in each leg, such that we end up with multiple entrant > numbers per cluster mean (which is a probability). We then proceed > through steps 2 and 3, but instead of generating single combinations, we > are now directly producing wagers which look like: > > 1+6+12/3+4+7/13+14 - $1.20 > > In this case, k-means clustering will have clustered 1,6,12 together > with cluster mean/probability of (say) 0.1, etc. > > This a bit of a hack, as clearly it will result in the wagers not > covering exactly the same single combinations as if we had generated > pure single wagers without k-means clustering. Hence my interest in > doing set comparisons! > > Another brute force greedy approach is to start with single combinations > and do something like this: > [...] > > Unfortunately this approach never seems to result in more than a 10 x > compression factor. Can do much better with the k-means approach - at > the cost of missing some theoretically desirable combinations and > betting on some spurious combinations. > > As always, would be very interested to hear if you have any > ideas/insights on first seeing this kind of problem. I'm almost > certainly too fixed in my thinking due to long association with the > wagering problem domain and probably cannot see the wood for the trees! I think that you're on the right track with trying to compress the output before actually generating it, i.e. compressing after step (1) instead of after step (3). My reasoning is that I don't see a good reason why, a priori, a *random* list of single wager combinations could be compressed well into *cartesian products*. I mean, if you have data without apparent structure, the best you can do is to pipe it through gzip , which has nothing to do with cartesian products at all. So, the fact that your "compression" works at all is a strong hint that your data does have a lot of structure, which you saw in the graphviz visualizations and which you are wisely exploiting at creation time with step (1a). (The greedy algorithm you mentioned is doomed to failure because it doesn't respect symmetries. The optimal result is invariant under * interchanging columns * renaming all numbers in one column but the greedy algorithm gives completely different results when you apply these operations to the input.) To achieve better compression, you have to open the black boxes in (1) and (2). The good news is that you don't need to open them completely; instead you just want to know properties like for example * Prob( entrant A wins in leg 1) = Prob( entrant A wins in leg 2) * Prob( entrant A wins) is independent of other participants * if {A,B} is a viable wager for leg 1 , so are {A} and {B} ("monotonicity") * Prob( A, B, C ) = Prob(A in leg 1) * Prob(B in leg 2) * Prob(C in leg 3) ("independence") * etc... In other words, the idea is that the probability for race outcome with multiple legs is, say, the product of the probabilities of the single legs, which then leads to these hypercube structures in your list of wagers. (I don't know which properties you need exactly because I don't understand the details about the probabilities, choosing wagers and pricing them.) Armed with such properties, there are systematic ways to exploit them for efficient algorithms. See for example the case study De Moor and Gibbons. Bridging the algorithm gap: A linear-time functional program for paragraph formatting. http://tinyurl.com/ydt5n5z (This is a .ps.gz file!) Understanding this might also lead to a better representation of compressed wagers that also includes wager sizes. In a sense, you're storing a recipe for creating a list of single wagers instead of the list itself, and [Row [a]] is just one possible "recipe format". Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com From maydwell at gmail.com Sun Jan 24 12:02:10 2010 From: maydwell at gmail.com (Lyndon Maydwell) Date: Sun Jan 24 11:34:12 2010 Subject: [Haskell-cafe] ghc: unrecognised flags: -I Message-ID: Hi Cafe! That's a capital "i" for anyone with font issues. I posted this question to beginners a while ago, but received no meaningful response so I'm trying cafe instead :-) Most packages I try to install off Hackage with cabal are giving me the error "ghc: unrecognised flags: -I". For example, when I "cabal install -v storable-complex" I get the following: /usr/bin/ghc -package-name storable-complex-0.2.1 --make -hide-all-packages -i -idist/build -i. -idist/build/autogen -Idist/build/autogen -Idist/build -I -optP-include -optPdist/build/autogen/cabal_macros.h -odir dist/build -hidir dist/build -stubdir dist/build -package base-3.0.3.1 -O Foreign.Storable.Complex ghc: unrecognised flags: -I I've updated everything several times since this error started occurring, but it persists. I've tried digging to find out where the lone -I is being injected but can't seem to track it down. Has anyone encountered this before, or more realistically, can anyone give me some advice on how to narrow this problem down further? I'm running cabal version 1.6.0.1, ghc 6.10.4 on OS X 10.5. Thanks guys! From gtener at gmail.com Sun Jan 24 12:11:18 2010 From: gtener at gmail.com (=?UTF-8?Q?Krzysztof_Skrz=C4=99tnicki?=) Date: Sun Jan 24 11:43:19 2010 Subject: [Haskell-cafe] Installing "encoding" package from Hackage In-Reply-To: <1264294556.3562.5.camel@dell-desktop.example.com> References: <1264294556.3562.5.camel@dell-desktop.example.com> Message-ID: <220e47b41001240911l6d9c6ef6jaeb5d78e2265b1f5@mail.gmail.com> I was able to build encoding-0.6.2. My steps: (0. Update package list with 'cabal update') 1. Unpack package with 'cabal unpack encoding' 2. Edit encoding.cabal. We need to add HaXml as dependency. It should be added to 'Build-Depends' field. I've added below "HaXml == 1.20.2" because 1.20.2. is the latest version available at the time of writing. Library if flag(splitBase) if flag(newGHC) Build-Depends: bytestring, base >= 3 && < 5, binary, mtl, containers, extensible-exceptions, array, template-haskell, regex-compat, ghc-prim, ghc >= 6.10, HaXml == 1.20.2 else Build-Depends: bytestring, base >= 3 && < 5, binary, mtl, containers, extensible-exceptions, array, template-haskell, regex-compat, ghc < 6.10, HaXml == 1.20.2 else Build-Depends: base < 3, binary, extensible-exceptions, template-haskell 3. Instal with "cabal install" run in the directory next to encoding.cabal. It looks like package maintainer forgot to specify this dependency. Best regards Krzysztof Skrz?tnicki From nicolas.pouillard at gmail.com Sun Jan 24 13:45:25 2010 From: nicolas.pouillard at gmail.com (Nicolas Pouillard) Date: Sun Jan 24 13:17:28 2010 Subject: [Haskell-cafe] Re: PROPOSAL: Web application interface In-Reply-To: References: <29bf512f1001170801r15f1537bne4dd71c07b0682b8@mail.gmail.com> <67C931AB-57FC-4891-9037-AAAD8489B7B3@glyphic.com> <29bf512f1001180348i2cd2d97p17ef1510ab8974fe@mail.gmail.com> <29bf512f1001231131q26353618t2248aab5629f0613@mail.gmail.com> Message-ID: <4b5c9545.1067f10a.3764.1ddf@mx.google.com> On Sun, 24 Jan 2010 12:23:46 +0100, Bardur Arantsson wrote: > Michael Snoyman wrote: > > [--snip--] > > Next, I have made the ResponseBodyClass typeclass specifically with the goal > > of allowing optimizations for lazy bytestrings and sending files. The former > > seems far-fetched; the latter provides the ability to use a sendfile system > > call instead of copying the file data into memory. However, in the presence > > of gzip encoding, how useful is this optimization? > [--snip--] > > I'm hoping that the "Web" bit in your project title doesn't literally > mean that WAI is meant to be restricted to solely serving content to > browsers. With that caveat in mind: > > For non-WWW HTTP servers it can be extremely useful to have sendfile. An > example is my Haskell UPnP Media Server (hums) application. It's sending > huge files (AVIs, MP4s, etc.) over the network and since these files are > already compressed as much as they're ever going to be, gzip would be > useless. The CPU load of my hums server went from 2-5% to 0% when > streaming files just from switching from a Haskell I/O based solution to > proper sendfile. > > Lack of proper support for sendfile() was indeed one of the reasons that > I chose to roll my own HTTP server for hums. I should note that this was > quite a while ago and I haven't really gone back to reevaluate that > choice -- there's too many HTTP stacks to choose from right now and I > don't have the time to properly evaluate them all. Good reason indeed. > For this type of server, response *streaming* is also extremely > important for those cases where you cannot use sendfile, so I'd hate to > see a standard WAI interface preclude that. (No, lazy I/O is NOT an > option -- the HTTP clients in a typical UPnP media client behave so > badly that you'll run out of file descriptors in no time. Trust me, I've > tried.) Is the experiment easily re-doable? I would like to try using safe-lazy-io instead. -- Nicolas Pouillard http://nicolaspouillard.fr From kolar at fit.vutbr.cz Sun Jan 24 14:01:09 2010 From: kolar at fit.vutbr.cz (=?ISO-8859-2?Q?Du=B9an_Kol=E1=F8?=) Date: Sun Jan 24 13:33:10 2010 Subject: [Haskell-cafe] Naive booleans and numbers - type-checking fails Message-ID: <4B5C98F5.5040804@fit.vutbr.cz> Dear cafe, I'm trying to prepare a naive definition of booleans, numbers and some helper functions such a way, so that definition in lambda-calculus can be used in a straightforward way in Haskell. I was caught in trouble quite soon during change of lambda-expressions to Haskell - defining prefn as a helper for prev. When using Haskell-ish if-then-else then there is no problem (the code commented out), while using defined if-then-else (mif), the type-checking fails, but just for this case! Other simple tests are OK for the mif. Do I need some extra option for type-checker, or is it a principal failure (infinite type is reported) - I'm running ghci 6.10.4. > mtrue x y = x > mfalse x y = y > m0 f n = n > m1 f n = f n > m2 f n = f (f n) > msucc x g m = x g (g m) > iszero m = m (\_ -> mfalse) mtrue > mif c t f = c t f > mpair f s = \e -> e f s > mfst p = p mtrue > msnd p = p mfalse > -- mprefn f p = if mex True False then mth else mel > mprefn f p = mif mex mth mel > where > mex = mfst p > mth = mpair mfalse (msnd p) > mel = mpair mfalse (f (msnd p)) Please, change of definitions is not a solution, I'm trying to follow available resources, so using something else is not an option. :-( Thanks for any help Dusan From jfredett at gmail.com Sun Jan 24 15:29:51 2010 From: jfredett at gmail.com (jfredett@gmail.com) Date: Sun Jan 24 15:01:56 2010 Subject: [Haskell-cafe] Haskell Weekly News: Issue 147 - January 24, 2010 Message-ID: <4b5cadbf.9753f10a.3413.5835@mx.google.com> --------------------------------------------------------------------------- Haskell Weekly News http://sequence.complete.org/hwn/20100124 Issue 147 - January 24, 2010 --------------------------------------------------------------------------- Welcome to issue 147 of HWN, a newsletter covering developments in the [1]Haskell community. This week on the HWN, we have a new blogger in town, Bartek, over at 'The Power of Types Compels You', wrote an excellent article which is highlighted in the blogs section. Many new packages this week as well, and some interesting discussions about performance and existential types. So, Haskellers, till next week, your Haskell Weekly News! Announcements ForSyDe DSL v3.1. Seyed Hosein Attarzadeh Niaki [2]announced a new version of the ForSyDe DSL. This version provides more freedom in the declaration of process functions, as well as compatibility with base 4. parameterized-data library v0.1.4. Seyed Hosein Attarzadeh Niaki [3]announced a new version of the parameterized-data library. The parameterized-data library provides fixed-sized vectors, this update is provide minor compatibility fixes. Updates and a new member of the Monadic Regions family. Bas van Dijk [4]announced several new updates and a new member of the Monadic Regions family. bindings-DSL 1.0.4 (Category: FFI). Mauricio CA [5]announced a new version of his package bindings-DSL. Haskell XML Toolbox Version 8.5.0. Uwe Schmidt [6]announced a new version of the Haskell XML Toolbox (HXT). The main change in this version is the separation of the XPath and XSLT modules. Cardinality-0.1. Andrey Sisoyev [7]announced the release of his package Cardinality, a package for transforming between container types safely. afv-0.0.3. Tom Hawkins [8]announced a new release of AFV, an infinite state model checker for simple, iterative C programs. CfP: PPDP 2010. Temur Kutsia [9]announced a call for papers for the PPDP 2010 conference in July Mini-announce: A few package updates. Andrew Coppin [10]announced several new releases and updates to AC-EasyRaster-GTK, AC-Vector, and other packages. amqp-0.1. Holger Reinhardt [11]announced the release of his AMQP library. It currently only works with RabbitMQ and supports most of the 0-8 spec. An introduction to AMQP can be found [12]here. nntp 0.0.3. Maciej Piechotka [13]1f4e gmane.comp.lang.haskell.cafe/69228 announced a bugfix release to nntp. haskell-src-exts 1.7.0. Niklas Broberg [14]announced a new version of haskell-src-exts, featuring many new changes to the API. Discussion Existential Types (I guess). Ozgur Akgun [15]asked about a problem he encountered when trying to use Existential types. Is Haskell capable of matching C in string processing performance? John Millikin [16]asked a question about Haskell Performance... Quick! Someone get Don Stewart! Blog noise [17]Haskell news from the [18]blogosphere. Blog posts from people new to the Haskell community are marked with >>>, be sure to welcome them! * ++Bartek Paczesiowa++: [19]Pure, extensible exceptions and self-returning functions. Bartek, over at 'The Power of Types Compels You', wrote a fantastic introduction to his forthcoming exceptions package. It's funny, and a great read about using type families (particularly, equality constraints) to create a pure exception handling mechanic. Definitely worth a visit. * Neil Mitchell: [20]Optimising HLint. * Kevin Reid (kpreid): [21]Darcs repositories back. * Darcs: [22]darcs weekly news #52. * Bryan O'Sullivan: [23]New GHC I/O manager, first sets of benchmark numbers. * Galois, Inc: [24]POPL 2010, Day 1. * Galois, Inc: [25]Tech Talk: A Scalable I/O Manager for GHC. * Galois, Inc: [26]PADL/PEPM 2010, Day 2. * Neil Brown: [27]The Process Composition Monad. * Galois, Inc: [28]PADL/PEPM 2010, Day 1. * Thomas M. DuBuisson: [29]GHC on ARM. * David Sankel: [30]Semantic Editor Combinators - one of my favorite blog posts. * David Sankel: [31]Best Haskell Papers of 2009. * Gtk2HS: [32]Compiling with ghc 6.12. * Arch Haskell News: [33]wxHaskell packaged for Arch. * Darcs: [34]darcs weekly news #51. * Don Stewart (dons): [35]Playing with the new Haskell epoll event library. * Dan Piponi (sigfpe): [36]Target Enumeration with the Euler Characteristic. Parts 1 & 2. Quotes of the Week * tensorpudding: the Plot monad allow you to keep the story pure by containing all the glaring time travel silliness * sproingie: quickcheck myLanguage.hs --> "Web browser created after 285,731 tests" * RossPaterson: I'm afraid you voided the warranty when you used UndecidableInstances. * aavogt: strong static typing is not a substitute for sleep * tensorpudding: fixity goes up to 11 * temoto: Backwards written in as Forth? * Paczesiowa: oh. can't argue with Cale :) * Axman6: and smilies make code run faster About the Haskell Weekly News New editions are posted to [37]the Haskell mailing list as well as to [38]the Haskell Sequence and [39]Planet Haskell. [40]RSS is also available, and headlines appear on [41]haskell.org. To help create new editions of this newsletter, please see the information on [42]how to contribute. Send stories to jfredett . at . gmail . dot . com. The darcs repository is available at darcs get [43]http://patch-tag.com/r/jfredett/HWN2/pullrepo HWN2 . References 1. http://haskell.org/ 2. http://article.gmane.org/gmane.comp.lang.haskell.cafe/69474 3. http://article.gmane.org/gmane.comp.lang.haskell.cafe/69473 4. http://article.gmane.org/gmane.comp.lang.haskell.cafe/69470 5. http://article.gmane.org/gmane.comp.lang.haskell.cafe/69465 6. http://article.gmane.org/gmane.comp.lang.haskell.cafe/69434 7. http://article.gmane.org/gmane.comp.lang.haskell.cafe/69366 8. http://article.gmane.org/gmane.comp.lang.haskell.cafe/69339 9. http://article.gmane.org/gmane.comp.lang.haskell.general/17753 10. http://article.gmane.org/gmane.comp.lang.haskell.cafe/69322 11. http://article.gmane.org/gmane.comp.lang.haskell.cafe/69250 12. http://blogs.digitar.com/jjww/2009/01/rabbits-and-warrens/ 13. http://article.gmane.org/ 14. http://article.gmane.org/gmane.comp.lang.haskell.cafe/69197 15. http://thread.gmane.org/gmane.comp.lang.haskell.cafe/69428 16. http://thread.gmane.org/gmane.comp.lang.haskell.cafe/69416 17. http://planet.haskell.org/ 18. http://haskell.org/haskellwiki/Blog_articles 19. http://paczesiowa.blogspot.com/2010/01/pure-extensible-exceptions-and-self.html 20. http://neilmitchell.blogspot.com/2010/01/optimising-hlint.html 21. http://kpreid.livejournal.com/21077.html 22. http://blog.darcs.net/2010/01/darcs-weekly-news-52.html 23. http://www.serpentine.com/blog/2010/01/22/new-ghc-io-manager-first-benchmark-numbers/ 24. http://www.galois.com/blog/2010/01/21/popl-2010-day-1/ 25. http://www.galois.com/blog/2010/01/20/tech-talk-a-scalable-io-manager-for-ghc/ 26. http://www.galois.com/blog/2010/01/20/padlpepm-2010-day-2/ 27. http://chplib.wordpress.com/2010/01/19/the-process-composition-monad/ 28. http://www.galois.com/blog/2010/01/19/padlpepm-2010-day-1/ 29. http://tommd.wordpress.com/2010/01/19/ghc-on-arm/ 30. http://netsuperbrain.com/blog/posts/semantic-editor-combiners/ 31. http://netsuperbrain.com/blog/posts/best-haskell-papers-of-2009/ 32. http://haskell.org/gtk2hs/archives/2010/01/18/compiling-with-ghc-612/ 33. http://archhaskell.wordpress.com/2010/01/18/wxhaskell-packaged-for-arch/ 34. http://blog.darcs.net/2010/01/darcs-weekly-news-51.html 35. http://donsbot.wordpress.com/2010/01/17/playing-with-the-new-haskell-epoll-event-library/ 36. http://blog.sigfpe.com/2010/01/target-enumeration-with-euler.html 37. http://www.haskell.org/mailman/listinfo/haskell 38. http://sequence.complete.org/ 39. http://planet.haskell.org/ 40. http://sequence.complete.org/node/feed 41. http://haskell.org/ 42. http://haskell.org/haskellwiki/HWN 43. http://patch-tag.com/r/jfredett/HWN2/pullrepo%20HWN2 From michael at snoyman.com Sun Jan 24 16:00:23 2010 From: michael at snoyman.com (Michael Snoyman) Date: Sun Jan 24 15:32:23 2010 Subject: [Haskell-cafe] Re: PROPOSAL: Web application interface In-Reply-To: References: <29bf512f1001170801r15f1537bne4dd71c07b0682b8@mail.gmail.com> <67C931AB-57FC-4891-9037-AAAD8489B7B3@glyphic.com> <29bf512f1001180348i2cd2d97p17ef1510ab8974fe@mail.gmail.com> <29bf512f1001231131q26353618t2248aab5629f0613@mail.gmail.com> Message-ID: <29bf512f1001241300l264853b0xf0783215bfa29420@mail.gmail.com> On Sun, Jan 24, 2010 at 1:23 PM, Bardur Arantsson wrote: > Michael Snoyman wrote: > > [--snip--] > > Next, I have made the ResponseBodyClass typeclass specifically with the >> goal >> of allowing optimizations for lazy bytestrings and sending files. The >> former >> seems far-fetched; the latter provides the ability to use a sendfile >> system >> call instead of copying the file data into memory. However, in the >> presence >> of gzip encoding, how useful is this optimization? >> > [--snip--] > > I'm hoping that the "Web" bit in your project title doesn't literally mean > that WAI is meant to be restricted to solely serving content to browsers. > With that caveat in mind: > > For non-WWW HTTP servers it can be extremely useful to have sendfile. An > example is my Haskell UPnP Media Server (hums) application. It's sending > huge files (AVIs, MP4s, etc.) over the network and since these files are > already compressed as much as they're ever going to be, gzip would be > useless. The CPU load of my hums server went from 2-5% to 0% when streaming > files just from switching from a Haskell I/O based solution to proper > sendfile. > > Lack of proper support for sendfile() was indeed one of the reasons that I > chose to roll my own HTTP server for hums. I should note that this was quite > a while ago and I haven't really gone back to reevaluate that choice -- > there's too many HTTP stacks to choose from right now and I don't have the > time to properly evaluate them all. > > For this type of server, response *streaming* is also extremely important > for those cases where you cannot use sendfile, so I'd hate to see a standard > WAI interface preclude that. (No, lazy I/O is NOT an option -- the HTTP > clients in a typical UPnP media client behave so badly that you'll run out > of file descriptors in no time. Trust me, I've tried.) > > Both sendfile and response streaming are in the top priorities in the WAI proposal. As far as "web," I think the term is just a synonym for HTTP here. I'd be especially interested to hear input from people using Haskell for non-standard HTTP applications, because I want WAI to be as general as possible. Please let me know if you see anything that you would like added. The code is all available at http://github.com/snoyberg/wai Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100124/7de84518/attachment.html From stephen.tetley at gmail.com Sun Jan 24 16:12:19 2010 From: stephen.tetley at gmail.com (Stephen Tetley) Date: Sun Jan 24 15:44:19 2010 Subject: [Haskell-cafe] Naive booleans and numbers - type-checking fails In-Reply-To: <4B5C98F5.5040804@fit.vutbr.cz> References: <4B5C98F5.5040804@fit.vutbr.cz> Message-ID: <5fdc56d71001241312h10f4677aib2e1e8c39266da42@mail.gmail.com> Doesn't the simply typed lambda calculus introduce if-then-else as a primitive precisely so that it can be typed? Its not an illuminating answer to your question and I'd welcome clarification for my own understanding, but I don't think you can solve the problem without appealing to Haskell's built-in if-then-else. Best wishes Stephen From derek.a.elkins at gmail.com Sun Jan 24 18:26:07 2010 From: derek.a.elkins at gmail.com (Derek Elkins) Date: Sun Jan 24 17:58:06 2010 Subject: [Haskell-cafe] Naive booleans and numbers - type-checking fails In-Reply-To: <5fdc56d71001241312h10f4677aib2e1e8c39266da42@mail.gmail.com> References: <4B5C98F5.5040804@fit.vutbr.cz> <5fdc56d71001241312h10f4677aib2e1e8c39266da42@mail.gmail.com> Message-ID: <61f84eff1001241526p12d6ab69p4693cb643e3ef73e@mail.gmail.com> On Sun, Jan 24, 2010 at 3:12 PM, Stephen Tetley wrote: > Doesn't the simply typed lambda calculus introduce if-then-else as a > primitive precisely so that it can be typed? > > Its not an illuminating answer to your question and I'd welcome > clarification for my own understanding, but I don't think you can > solve the problem without appealing to Haskell's built-in > if-then-else. Yes, encoding data types as pure typed lambda terms requires rank-2 types. I'd recommend that Du?an Kol?? start giving types to all these functions. However, it will, eventually, be necessary to go beyond Haskell 98 to give the appropriate types. From michael at snoyman.com Sun Jan 24 18:30:00 2010 From: michael at snoyman.com (Michael Snoyman) Date: Sun Jan 24 18:02:01 2010 Subject: [Haskell-cafe] Re: PROPOSAL: Web application interface In-Reply-To: <29bf512f1001241300l264853b0xf0783215bfa29420@mail.gmail.com> References: <29bf512f1001170801r15f1537bne4dd71c07b0682b8@mail.gmail.com> <67C931AB-57FC-4891-9037-AAAD8489B7B3@glyphic.com> <29bf512f1001180348i2cd2d97p17ef1510ab8974fe@mail.gmail.com> <29bf512f1001231131q26353618t2248aab5629f0613@mail.gmail.com> <29bf512f1001241300l264853b0xf0783215bfa29420@mail.gmail.com> Message-ID: <29bf512f1001241530r5a57ae46n4d79289c4f9e8404@mail.gmail.com> Minor spec question: what should be the defined behavior when an application requests that a file be sent and it does not exist? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100124/0d97dbce/attachment.html From mattphil at gmail.com Sun Jan 24 23:34:50 2010 From: mattphil at gmail.com (Matthew Phillips) Date: Sun Jan 24 23:06:57 2010 Subject: [Haskell-cafe] Spelling checker exercise In-Reply-To: <201001241252.10357.daniel.is.fischer@web.de> References: <83757D35-C8ED-49B9-9EAA-FED2098C52F9@gmail.com> <201001221441.15160.daniel.is.fischer@web.de> <201001241252.10357.daniel.is.fischer@web.de> Message-ID: On 24/01/2010, at 10:22 PM, Daniel Fischer wrote: <...> > I think I know what happened here: > > $ ghc -fforce-recomp --make matthew -o matthew0 <...> > I habitually compile all code with -O2, unless I have a specific reason not > to. I tend to forget that some compile without optimisations. > For some kinds of code that makes hardly any difference, for others it > makes a big difference. I used the flags "-funbox-strict-fields -fvia-C -optc-O2", but *not* -O2. Whoops! I could kick myself: I blindly assumed that -optc-O2 would turn on optimisation, but of course that's just the flag for GCC. $ time ./spelling becuase becuase -> because real 0m4.467s user 0m3.865s sys 0m0.280s $ time ./spelling_df becuase becuase -> because real 0m2.422s user 0m2.198s sys 0m0.081s Your previous version is close to twice as fast, and now only 2.5 times slower than Python. With your suggested changes, your latest version on my machine: $ time ./spelling_df becuase becuase -> because real 0m1.731s user 0m1.572s sys 0m0.056s Now, we're getting close: 4.7s -> 2.3s -> 1.7s. >>> But once you start needing two edits (try korrekt), correct and edits1 >>> start to show up. That shows that Norvig's algorithm isn't really >>> good. With two edit steps, you create a _lot_ of strings you need to >>> look up, far more than there are in the map. That takes time. It'll be >>> better to scan the map for entries with an edit distance (< 3) if you >>> have a good method to check that > > Indeed: > $ time ./nLDBSWSpelling becuase > becuase -> because > 2.84user 0.02system 0:02.86elapsed 100%CPU > $ time ./nLDBSWSpelling korrekt > korrekt -> correct > 2.83user 0.05system 0:02.88elapsed 100%CPU Not sure if I see what you're saying here: do you mean to point out the 2.86 vs 2.88 elapsed? >>> Another thing is >>> >>> allWords = keysSet wordCounts >>> >>> Ouch. For each correction, you construct that set anew. Just use >>> member from Data.Map instead of Data.Set.member and look up the words >>> in the map. >> >> Whoops! Just to be clear though: Haskell will memoise the result of >> "allWords" for a given invocation of "correct"? > > Yes. But not across different invocations. > >> So this would only make a large difference for multiple corrections? > > Right. But that's the interesting use case, isn't it? It will be when I get the the rest of it working, yes :) >>>> I will look at using Bloom Filters or >>>> Trie?s instead of Data.Map, but I wonder if readFile should be taking >>>> nearly %30 of the run time, even for a 6MB file? >>> >>> No way. But it doesn't seem to, from my GHC's point of view. >> >> Just to be sure I wasn't using the SCC incorrectly, I split out the >> readFile call into "myReadFile". The prof line comes out as: >> >> myReadFile Main 210 1 35.8 8.6 >> 35.8 8.6 >> >> i.e. 35.8% of runtime. >> > > Can I see the exact code which gives that profile? > Somehow, things which shouldn't must be attributed to readFile. The version at this link has myReadFile split out. http://github.com/scramjet/spelling/blob/31071edb2166b2bc4d350358900d975228fd43b9/spelling.hs Doing the same to your version has the same result: myReadFile Main 210 1 45.7 9.6 45.7 9.6 It does seem that the profiler is wrong or misleading somehow. Two other quick questions: (1) you added parentheses to "candidates": candidates = known [word] `or` ((known e1) `or` known_edits2) The "or"'s should short circuit so that if "known [word]" is non-empty, the others shouldn't be evaluated. I read the above as forcing evaluation of the second "or" first: am I wrong? (2) you eliminated the "fold" in "correct" in favour of a tail-recursive search in "maxCount": was this for style or performance reasons (or both :)? Cheers, Matthew. From tomahawkins at gmail.com Sun Jan 24 23:47:10 2010 From: tomahawkins at gmail.com (Tom Hawkins) Date: Sun Jan 24 23:19:08 2010 Subject: [Haskell-cafe] ANN: afv-0.1.0 Message-ID: <594c1e831001242047g4b435e6eo63383a3ff089aa99@mail.gmail.com> AFV is an infinite state model checker to verify assertions in embedded C programs. New in this release: - Starts analysis from 'main' entry point. Automatically identifies the main loop (for (;;), while (1)). - Better counter example generation. - Enforces stateless expressions. Unfortunately, the list of unsupported C is still long. No... - arrays - pointers - structs - unions - typedefs - type casts - static top-level declarations - non void functions - switch statements - arbitrary loop statements http://hackage.haskell.org/package/afv From daniel.is.fischer at web.de Mon Jan 25 02:19:59 2010 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Jan 25 01:53:47 2010 Subject: [Haskell-cafe] Spelling checker exercise In-Reply-To: References: <83757D35-C8ED-49B9-9EAA-FED2098C52F9@gmail.com> <201001241252.10357.daniel.is.fischer@web.de> Message-ID: <201001250820.00307.daniel.is.fischer@web.de> Am Montag 25 Januar 2010 05:34:50 schrieb Matthew Phillips: > On 24/01/2010, at 10:22 PM, Daniel Fischer wrote: > > <...> > > > I think I know what happened here: > > > > $ ghc -fforce-recomp --make matthew -o matthew0 > > <...> > > > I habitually compile all code with -O2, unless I have a specific > > reason not to. I tend to forget that some compile without > > optimisations. For some kinds of code that makes hardly any > > difference, for others it makes a big difference. > > I used the flags "-funbox-strict-fields -fvia-C -optc-O2", but *not* > -O2. Whoops! I could kick myself: I blindly assumed that -optc-O2 would > turn on optimisation, but of course that's just the flag for GCC. By the way, compiling via C nowadays hardly ever produces faster code than the native code generator (most times I tried since 6.10, if there was a difference, native was faster). > > $ time ./spelling becuase > becuase -> because > > real 0m4.467s > user 0m3.865s > sys 0m0.280s > > $ time ./spelling_df becuase > becuase -> because > > real 0m2.422s > user 0m2.198s > sys 0m0.081s > > Your previous version is close to twice as fast, and now only 2.5 times > slower than Python. > > > > With your suggested changes, your latest version on my machine: > > $ time ./spelling_df becuase > becuase -> because > > real 0m1.731s > user 0m1.572s > sys 0m0.056s > > Now, we're getting close: 4.7s -> 2.3s -> 1.7s. > > >>> But once you start needing two edits (try korrekt), correct and > >>> edits1 start to show up. That shows that Norvig's algorithm isn't > >>> really good. With two edit steps, you create a _lot_ of strings you > >>> need to look up, far more than there are in the map. That takes > >>> time. It'll be better to scan the map for entries with an edit > >>> distance (< 3) if you have a good method to check that > > > > Indeed: > > $ time ./nLDBSWSpelling becuase > > becuase -> because > > 2.84user 0.02system 0:02.86elapsed 100%CPU > > $ time ./nLDBSWSpelling korrekt > > korrekt -> correct > > 2.83user 0.05system 0:02.88elapsed 100%CPU > > Not sure if I see what you're saying here: do you mean to point out the > 2.86 vs 2.88 elapsed? Well, above the code, I had the times for Norvig's algorithm (creating all two-step edits and checking which are known): > > And, without profiling: > > $ time ./spellingBSW becuase > > becuase -> because > > 2.84user 0.03system 0:02.88elapsed 99%CPU > > > > Finally, building the set of two-step edits takes longer than the > > additional lookups: > > > > $ time ./spellingBSW becuase > > becuase -> because > > 2.84user 0.03system 0:02.88elapsed 99%CPU > > $ time ./spellingBSW korrekt > > korrekt -> correct > > 3.50user 0.02system 0:03.52elapsed 100%CPU > > > > vs. > > > > $ time ./spellingBSWL becuase > > becuase -> because > > 2.79user 0.04system 0:02.83elapsed 100%CPU > > $ time ./spellingBSWL3 korrekt > > korrekt -> correct > > 3.20user 0.02system 0:03.23elapsed 99%CPU For "becuase", which is a one-step edit, all take the same time (within normal fluctuation), 2.8x seconds. For the two-step edit "korrekt", the version building Sets takes 3.5 seconds, the version which doesn't build a Set of two-step edits takes 3.2 seconds, *and the version scanning the Map of known words for entries with a Levenshtein distance [modified to account for transpositions] less than 3, takes 2.8y seconds, practically the same time as for the one-step edit*. It becomes more obvious, perhaps, if we test a couple of two-steppers: Lazy Levenshtein: time ./nLDBSWSpelling becrase korrekt halmos territoir gutzenperg becrase -> because korrekt -> correct halmos -> holmes territoir -> territory gutzenperg -> gutenberg 2.94user 0.03system 0:02.97elapsed 100%CPU just something like 0.1 - 0.15 seconds more than for "becuase", that makes 0.02 - 0.04 seconds per two-edit correction. Sets: $ time ./spellingBSW becrase korrekt halmos territoir gutzenperg becrase -> because korrekt -> correct halmos -> holmes territoir -> territory gutzenperg -> gutenberg 7.48user 0.03system 0:07.55elapsed 99%CPU Gewalt geschrien! That takes almost a second per two-edit correction. List: $ time ./spellingBSWL3 becrase korrekt halmos territoir gutzenperg becrase -> because korrekt -> correct halmos -> holmes territoir -> territory gutzenperg -> gutenberg 5.54user 0.04system 0:05.58elapsed 99%CPU Better, but still bad, roughly half a second per correction. Python without psyco: $ time python ./norvig.py becrase korrekt halmos territoir gutzenperg Trained in 1.46993017197 seconds because correct holmes territory gutenberg 3.00user 0.08system 0:03.09elapsed 99%CPU $ time python ./norvig.py becuase Trained in 1.49027395248 seconds because 1.46user 0.08system 0:01.55elapsed 100%CPU about 0.3 seconds per correction and with: $ time python ./norvig.py becrase korrekt halmos territoir gutzenperg Trained in 1.22417902946 seconds because correct holmes territory gutenberg 2.12user 0.09system 0:02.21elapsed 100%CPU $ time python ./norvig.py becuase Trained in 1.17486715317 seconds because 1.14user 0.08system 0:01.23elapsed 99%CPU about 0.2 seconds per correction. (Just for the record, I found out what Python did in the half second I couldn't account for: it looked for matches for "./norvig.py", I forgot that Python passes the name of the script in argv[0] - d'oh) > > >>> Another thing is > >>> > >>> allWords = keysSet wordCounts > >>> > >>> Ouch. For each correction, you construct that set anew. Just use > >>> member from Data.Map instead of Data.Set.member and look up the > >>> words in the map. > >> > >> Whoops! Just to be clear though: Haskell will memoise the result of > >> "allWords" for a given invocation of "correct"? > > > > Yes. But not across different invocations. > > > >> So this would only make a large difference for multiple corrections? > > > > Right. But that's the interesting use case, isn't it? > > It will be when I get the the rest of it working, yes :) > > >>>> I will look at using Bloom Filters or > >>>> Trie?s instead of Data.Map, but I wonder if readFile should be > >>>> taking nearly %30 of the run time, even for a 6MB file? > >>> > >>> No way. But it doesn't seem to, from my GHC's point of view. > >> > >> Just to be sure I wasn't using the SCC incorrectly, I split out the > >> readFile call into "myReadFile". The prof line comes out as: > >> > >> myReadFile Main 210 1 35.8 8.6 > >> 35.8 8.6 > >> > >> i.e. 35.8% of runtime. > > > > Can I see the exact code which gives that profile? > > Somehow, things which shouldn't must be attributed to readFile. > > The version at this link has myReadFile split out. > > http://github.com/scramjet/spelling/blob/31071edb2166b2bc4d350358900d975 >228fd43b9/spelling.hs > > Doing the same to your version has the same result: > > myReadFile Main 210 1 45.7 9.6 45.7 > 9.6 > > It does seem that the profiler is wrong or misleading somehow. Strange. Doing that here has no such effect. The only line in the profile (ByteString) where myReadFile occurs is myReadFile Main 260 1 0.0 0.9 0.0 0.9 0 6507348 (snipped whitespace), entered once, allocated 6.5 million bytes, took not measurable time. Both, compiled via C and with the native code generator. With String IO, it costs 4.6% time and 8.1% allocation. > > Two other quick questions: > > (1) you added parentheses to "candidates": > > candidates = known [word] `or` ((known e1) `or` known_edits2) > > The "or"'s should short circuit so that if "known [word]" is non-empty, > the others shouldn't be evaluated. I read the above as forcing > evaluation of the second "or" first: am I wrong? Au contraire, "Any operator lacking a fixity declaration is assumed to be infixl 9" says the report, so without parentheses, it's parsed as (known [word] `or` known e1) `or` known_edits2 and both 'or's must be evaluated even if word is known. Since 'or' is lazy in its second argument, if we associate it known [word] `or` (known e1 `or` known_edits2) , in case of a known word, we needn't look at the parenthesis at all (it will probably not make a measurable difference in running time unless you check a couple of million known words, but still, it feels lazier). For a local definition, I thought an explicit fixity declaration was overkill. > > (2) you eliminated the "fold" in "correct" in favour of a tail-recursive > search in "maxCount": was this for style or performance reasons (or both > :)? Performance, kind of. Since the lists we fold over are in fact short, it doesn't really matter, but if they were long, there'd be the risk of unnecessarily allocating lots of pairs. I'm rather confident that with -O2, GHC will eliminate the pairs anyway, but without looking at the core, I'm not entirely sure. However, in fact it was an unthought-through rewrite because I just had someone with a stack overflow in spite of foldl' due to the laziness of the data constructors[*]. So I made sure that that couldn't happen, without looking at the folded function to see if that already prevents it. And in fact, it does, so using a foldl' if you use lists instead of Sets is fine, with respect to style, even preferable. [*] classic example: why will average xs = sum / len where (sum,len) = foldl' accum (0,0) xs accum (sm,ln) x = (sm+x,ln+1) cause a stack overflow for long lists? > > Cheers, > > Matthew. From emax at chalmers.se Mon Jan 25 03:09:43 2010 From: emax at chalmers.se (Emil Axelsson) Date: Mon Jan 25 02:41:43 2010 Subject: [Haskell-cafe] Non-termination due to context In-Reply-To: <59543203684B2244980D7E4057D5FBC10AFC9048@DB3EX14MBXC306.europe.corp.microsoft.com> References: <4B598AF5.3090909@chalmers.se> <59543203684B2244980D7E4057D5FBC10AFC9048@DB3EX14MBXC306.europe.corp.microsoft.com> Message-ID: <4B5D51C7.8070803@chalmers.se> OK, I'll try to get to the SYB3 paper at some point. For now I'll just add to my knowledge that UndecidableInstances allows you to create non-terminating dictionaries in addition to the well-known risk of making the type checker loop. Thanks! / Emil Simon Peyton-Jones skrev: > It's a feature! > > You have > * B is a superclass of A > * Eq is a superclass of B > > So every A dictionary has a B dictionary inside it, and every B dictionary has an Eq dictionary inside it. > > Now, your instance declaration > instance (A a, Eq a) => B a > says "if you give me an A dictionary and an Eq dictionary, I'll make you a B dictionary". > > Now, 'test' needs a (B Int) dictionary. To get one, we need an (A Int) dictionary and an (Eq Int) dictionary. But > > when solving these sub-problems, GHC assumes that you > have in hand a solution to the original problem, this case (B Int) > > Why? Read the SYB3 paper. > > OK so now you see the problem: we can solve the (A Int) and (Eq Int) sub-problems by selection from the (B Int) dictionary. > > > Still, I confess that I have not fully grokked the relationship between the SYB3-style recursion stuff and the question of superclasses. So I will think about your example some more, thank you. > > Meanwhile, it's clear that you are on thin ice. > > Simon > > > | -----Original Message----- > | From: haskell-cafe-bounces@haskell.org [mailto:haskell-cafe-bounces@haskell.org] On > | Behalf Of Emil Axelsson > | Sent: 22 January 2010 11:25 > | To: Haskell Cafe > | Subject: [Haskell-cafe] Non-termination due to context > | > | Hello all! > | > | Consider the following program: > | > | > {-# LANGUAGE FlexibleInstances, OverlappingInstances, UndecidableInstances #-} > | > > | > class B a => A a > | > > | > instance A Int > | > > | > class Eq a => B a > | > > | > instance (A a, Eq a) => B a > | > > | > eq :: B a => a -> a -> Bool > | > eq = (==) > | > > | > test = 1 `eq` (2::Int) > | > | (This is a condensed version of a much larger program that I've been > | debugging.) > | > | It compiles just fine, but `test` doesn't terminate (GHCi 6.10.4). If I > | change the context `B a` to `Eq a` for the function `eq`, it terminates. > | > | Although I don't know all the details of the class system, it seems > | unintuitive that I can make a program non-terminating just by changing > | the context of a function (regardless of UndecidableInstances etc.). > | > | Is this a bug or a feature? > | > | / Emil > | > | _______________________________________________ > | Haskell-Cafe mailing list > | Haskell-Cafe@haskell.org > | http://www.haskell.org/mailman/listinfo/haskell-cafe > From haskell at kudling.de Mon Jan 25 03:39:01 2010 From: haskell at kudling.de (haskell@kudling.de) Date: Mon Jan 25 03:11:01 2010 Subject: [Haskell-cafe] Failing to install hxt: tagsoup versioning In-Reply-To: <201001241358.56626.daniel.is.fischer@web.de> References: <765086784.208466.1264287586533.JavaMail.open-xchange@oxltgw02.schlund.de> <201001240059.51780.daniel.is.fischer@web.de> <1504586192.543843.1264332277646.JavaMail.open-xchange@oxltgw17.schlund.de> <201001241358.56626.daniel.is.fischer@web.de> Message-ID: <244708177.568797.1264408741072.JavaMail.open-xchange@oxltgw17.schlund.de> > Specifying one exact version is too restrictive, you'll end up with > everybody having umpteen versions of almost all packages installed. I don't see this as a problem. Disk space is extremely cheap, but our time is precious. Aplications on Mac OS X provide necessary libraries in their .app folder. That's some waste but it relieves you from dependency hell. > Minor version bumps which leave the API unchanged shouldn't break anything, > small additions to the API should rarely break things, so if people adhere > to http://www.haskell.org/haskellwiki/Package_versioning_policy , Indeed. Neil, in this case i think, tagsoup's version shouldn't have changed from 0.6 to minor 0.8 while exported definitions such as "optLookupEntity" were removed. What do you think? I'd be glad if we could find a general solution. Currently everybody using ghc 6.10.4 and trying to install hxt will go through this hassle. Which would be almost everybody. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100125/8e1b205e/attachment.html From Christian.Maeder at dfki.de Mon Jan 25 03:58:35 2010 From: Christian.Maeder at dfki.de (Christian Maeder) Date: Mon Jan 25 03:30:33 2010 Subject: [Haskell-cafe] Re: ghc: unrecognised flags: -I In-Reply-To: References: Message-ID: <4B5D5D3B.9050404@dfki.de> Lyndon Maydwell schrieb: > For example, when I "cabal install -v storable-complex" I get the following: > > /usr/bin/ghc -package-name storable-complex-0.2.1 --make > -hide-all-packages -i -idist/build -i. -idist/build/autogen > -Idist/build/autogen -Idist/build -I -optP-include > -optPdist/build/autogen/cabal_macros.h -odir dist/build -hidir > dist/build -stubdir dist/build -package base-3.0.3.1 -O > Foreign.Storable.Complex > ghc: unrecognised flags: -I For me this wo