Re: [Haskell-cafe] The Riddle of the Buddhist Monk
On 20/12/11 10:16, Patrick Browne wrote: Hi, I am trying to implement a set of 4 modules that blend the action of a monk moving up a mountain on day 1 and returning down by the same path on day 2 [1][2]. The code should reflect the fact that there is some time and place which is common to the two days where the monk would *meets himself*. My Haskell code is based on a Maude version[3][4]. Only 3 times and places are considered in the code; start, meet, and end called 1,2, and 3 (e.g. the start time for the upward journey is timeu1). Using qualified elements, I can get the meets function to give the correct results, but I cannot get the location function to work. Is it possible the get meets to work without qualification? Any suggestions in getting location to work? Regards, Pat I think you need to rethink the solution: Haskell is not a logic programming language. You definitely don't need the type class, and you don't need instances. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] German names for kinds and sorts
An odd suggestion I know, but take a look at some bibles. The King James Bible uses the word kind to describe different animals in Genesis 1: ^24 And God said, Let the earth bring forth the living creature after his kind, cattle, and creeping thing, and beast of the earth after his kind: and it was so. http://www.kingjamesbibleonline.org/Genesis-1-24/ At least some other English translations use the same word (I'm not a bible scholar, so I can't give you a detailed list). But you might try finding out what German bibles use in that passage. On 11/12/2011 04:05 PM, Robert Clausecker wrote: Hi all! I want to write my Facharbeit (kind of an essay you have to write on a specific topic you can choose yourself for highschool graduation) about the type-system of Haskell. It is required in our school to write this document in German language. Most time, it is not really difficult to find an appropriate term for concepts of Haskell, like types (Typen) or type classes (Typklassen). But I really don't know how to call kinds and sorts in German. Any ideas? Yours, Robert Clausecker ___ 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
Re: [Haskell-cafe] pointer equality
I would have thought that the compiler, as a matter of optimisation, could insert a check to see if (==) is comparing an object with itself. The only way I can see this breaking is with perverse instances of Eq that would return False for f == f. Paul. On 07/20/2011 04:51 AM, Nikhil A. Patil wrote: Hi, Is there any way of getting the following code to immediately return True without performing the element-by-element comparison? Essentially this boils down to checking whether pointers are equal before comparing the contents. main = print $ f == f where f = [1..10^9] Thanks!! nikhil ___ 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] Why aren't files flushed at exit?
If you open a file for writing and then exit with output unflushed, then Haskell does not flush the file for you. In ghci the program seems to work, but then when you compile it in ghc it mysteriously fails. I've just been bitten by this, but when I went to the bug tracker I found http://hackage.haskell.org/trac/ghc/ticket/4119 ticket 4119, which describes this behaviour and was resolved as invalid. So presumably this behaviour is by design. Given that most environments get this right, why doesn't Haskell? Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How do you test a parser?
On 11/06/11 14:10, Andrew Coppin wrote: OK, so suppose you sit down and write a complicated string parser. Now how do you test that it works correctly? If you have a function that turns a parse tree back into text again, you can try verifying that a round-trip is the identity function. Except perhaps sometimes it isn't. Perhaps a given expression has more than one equivalent representation. A round-trip from string and back again is even less likely to be stable. So what's the best way to attack this problem? _ If your parse tree has a show instance (or better yet, a pretty-print function) then you can generate random parse trees, print them, and then show that the parse returns an equal tree. However if you want to have useful error messages or a wider range of representations than just those generated by show then you will need to write a QuickCheck variant on the show function that emits all these variations, which is likely to be rather more work. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Haskell Platform web page is out of date
The Haskell Platform web page at http://hackage.haskell.org/platform// seems to need updating. (Incidentally, that double slash at the end doesn't look right). * The next release is promised in Jan 2011. * The Release Timetable schedules the next release for 5 March 2011. I just worry that this is one of the first things someone investigating Haskell sees, and it creates a bad first impression. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Can't install Leksah
I installed gtk2hs-buildtools as per the Leksah page, and then tried to install Leksah itself. I got: [r...@eiffel download]# cabal install leksah Resolving dependencies... cabal: cannot configure leksah-server-0.8.0.8. It requires ghc=6.10.1 6.13 There is no available version of ghc that satisfies=6.10.1 6.13 But there is... [r...@eiffel download]# ghc --version The Glorious Glasgow Haskell Compilation System, version 6.12.3 I don't know whether this is a problem with the GHC installation or the Leksah build. I'm running Fedora 14 with GHC installed through the package manager. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Can't install Leksah
On 27/11/10 11:25, Christopher Done wrote: Interesting. Perhaps Cabal isn't looking at the same GHC version. If you run cabal install with --version passed to GHC, GHC will just output the version instead of doing any compiling and the install will stop. You can see what version Cabal actually uses. Maybe it's different? Cabal is using ghc-6.12.3. However with Leksah it doesn't seem to be getting that far: it seems to be looking for a package called ghc during dependency analysis. However when I run ghc-pkg list there is no such package. Obviously this is meant to be a package that flags the compiler version for Cabal. Is it a bug that I don't have one? Paul ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Slightly humorous: Headhunters toolbox (example for Germany)
On 27/08/10 23:45, sylvain wrote: Other sources show growing interest in Haskell (much to the dismay of our favorite motto). Would you accept to refer to these other sources? One interesting one is http://www.itjobswatch.co.uk/jobs/uk/haskell.do Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: DSTM 0.1.1
Looks interesting. One point: you seem to be using Read and Show typeclasses for serialisation. I think you would be better off using Binary, which is much more efficient. Paul. On 03/08/10 09:35, Frank Kupke wrote: Hi, DSTM is an implementation of a robust distributed Software Transactional Memory (STM) library for Haskell. Many real-life applications are distributed by nature. Concurrent applications may profit from robustness added by re-implementation as distributed applications. DSTM extends the STM abstraction to distributed systems and presents an implementation efficient enough to be used in soft real-time applications. Further, the implemented library is robust in itself, offering the application developer a high abstraction level to realize robustness, hence, significantly simplifying this, in general, complex task. The DSTM package consists of the DSTM library, a name server application, and three sample distributed programs using the library. Provided are a simple Dining Philosophers, a Chat, and a soft real-time Bomberman game application. Distributed communication is transparent to the application programmer. The application designer uses a very simple name server mechanism to set up the system. The DSTM library includes the management of unavailable process nodes and provides the application with abstract error information thus facilitating the implementation of robust distributed application programs. For usage please look into the documentation file: DSTMManual.pdf. The package including the documentation can be found on: http://hackage.haskell.org/package/DSTM-0.1.1 Best regards, Frank Kupke ___ 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
Re: [Haskell-cafe] Small flexible projects a possible niche for Haskell - your statement, please...
On 16/07/10 05:41, Nick Rudnick wrote: In consequence, an 8-student-project with two B.Sc. theses is raised as a pilot to examine the possibilities of using Haskell in the combination small team with limited resources and experience in a startup setting - we want to find out whether Haskell can be an offer competitive whith languages like Ruby Co. in such a setting. I'm not sure exactly what you are asking, but I'm going to try to answer the question Does Haskell have a niche in small, flexible projects? I think the answer is a definite yes. I also think that Haskell can do great things in bigger projects as well, but successful technologies often start out with a niche that was previously poorly served, and then move out from there. Haskell developers generally start by writing down an axiomatic definition of the problem domain. To a developer raised in traditional top down development this looks like a jump into coding, and furthermore coding at the lowest level. In fact it is a foundation step in the architecture, because Haskell works well with a bottom up approach. The property that makes this work is composability, which says that you can take primitive elements and integrate them into bigger units without having to worry about mutual compatibility. A Haskell library will typically define a data type Foo and then have functions with types along the lines of mungFoo :: Something - Foo - Foo. This combinator style of library give you the basic building blocks for manipulating Foos, along with a guarantee that the output will always be a valid Foo. So you can build up your own applications that work at the Foo level rather than down in the coding level of flow control and updated variables like conventional programs. This lets domain experts read and comment on the code, which reduces defect rates a lot. But these combinator libraries are also highly reusable because they describe an entire domain rather than just being designed to fit a single application. So the best bet is to analyse a domain, write a combinator library that models the domain, and then produce a series of related programs for specific applications within that domain. That will let a small team be amazingly productive. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How easy is it to hire Haskell programmers
On 02/07/10 14:43, Edward Kmett wrote: Knowledge of Haskell means very different things to different people. I'd be somewhat leery of blindly hiring someone based on their ability to answer a couple of pop Haskell quiz questions. Fair enough, and I should probably have put a smiley in there. I'd also just that day read a couple of laments from hiring managers about applicants for Java jobs who *couldn't* write Fizzbuzz. I was really trying to ask about the general level of knowledge amongst the job applicants. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] How easy is it to hire Haskell programmers
I'm starting to see job adverts mentioning Haskell as a nice to have, and even in some cases as a technology to work with. However right now I'm looking at it from the other side. Suppose someone wants to hire a Haskell developer or three. How easy is this? I'd appreciate replies from people who have actually done this. * How many applications did you get? * How many of those applicants knew what a monad is, or how to write FizzBuzz in Haskell? Thanks, Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Accounting Engine in Haskell
On 15/06/10 09:08, Amiruddin Nagri wrote: I wanted some insight as to how Haskell is going to help me with my project. Also there has been some concerns because of lazy evaluation in Haskell and memory leaks associated with it. http://jlouisramblings.blogspot.com/2010/04/haskell-vs-erlang-for-bittorent-clients.html In this talk: http://www.galois.com/blog/2009/04/27/engineering-large-projects-in-haskell-a-decade-of-fp-at-galois/ Don Stewart says that memory leaks are a tractable problem. Just profile and look for the retainers. Lazy evaluation is a big win for large projects because it lets you modularise your solution; one function generates a data structure, and another function (or several) consume it. If the data structure is big or infinite then conventional languages force you to either interleave the generator and consumer, or else jump through lots of hoops re-inventing lazy evaluation on a case-by-case basis. With Haskell you just say what you mean and let the compiler worry about implementing it. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Continuations and coroutines
On 19/06/10 17:23, Yves Parès wrote: It helps me understand better, but would you have some simple code that would do that ? http://www.cs.chalmers.se/~koen/pubs/jfp99-monad.ps Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Continuations and coroutines
On 20/06/10 22:03, Paul Johnson wrote: On 19/06/10 17:23, Yves Parès wrote: It helps me understand better, but would you have some simple code that would do that ? http://www.cs.chalmers.se/~koen/pubs/jfp99-monad.ps Except that the paper I'm trying to refer to seems to have fallen off the net. Its A Poor Man's Concurrency Monad. Does anyone have a copy? Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Continuations and coroutines
On 19/06/10 10:36, Yves Parès wrote: Hello, I saw on the haskell wikibook that coroutines could be implemented by using continuations : http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style#Example:_coroutines (unhappily, the section is empty) Since I'm actually learning the wonders of continuations, I just wonder : how ? Coroutines depend on the ability to suspend and resume execution. A continuation acts as the resume point in the current function. The callCC function in the continuation monad takes a function that expects the continuation as an argument (which is how you get access to it). So you say something like: yield = callCC $ \continuation - Then you would typically store the continuation somewhere and call some other previously stored continuation to switch contexts. Continuations can be used to pass data back into the continuation: you call the continuation with an argument, and that argument becomes the return value of the callCC. In this case you probably just want to use (). You typically have a queue for continuations, so the new continuation goes on the back of the queue and then you call the head of the queue. Obvious modifications for priority, simulated time, real time or whatever else you are trying to schedule. This implies some kind of monadic state to store the queue in, so you will probably make your monad of type ContT (State Queue) If you want a thread to wait, say on a semaphore, then you have a queue of continuations in the semaphore data structure. Is this any help? Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] US Patent for the idea of using Haskell to implement UAX #9
On 16/04/10 19:59, Daniel Fischer wrote: Am Freitag 16 April 2010 20:50:25 schrieb Brian Hulley: revealed a link to a US Patent (7120900) for the idea of implementing the Unicode Bidirectional Algorithm (UAX #9 http://www.unicode.org/reports/tr9) in Haskell, making use, as far as I can tell, of nothing more than the normal approach any functional programmer would use, namely separation of concerns etc. In which case the patent should be null and void since obvious ideas aren't patentable, AFAIK. But of course, IANAL, you never know what jurists think a law means, ... First, everyone in this thread needs to stop writing and read http://news.swpat.org/2010/03/transcript-tridgell-patents/ , which is a talk by Andrew Tridgell of Samba fame about patents and how to avoid/invalidate them. His main point is that avoidance is much much easier than invalidation. Now, about obviousness and prior art. The patent system has been shaped by lawsuits. Judges want nice clear dividing lines because otherwise the law becomes unclear and a trial becomes even more of a crapshoot than it already is. This search for bright dividing lines has forced judges to make some decisions that sound rather odd. The problem with the obvious bit is that almost everything is obvious after you've had it explained to you. Sherlock Holmes had this problem with Watson; every time Holmes explained his reasoning Watson realised that the puzzle was absurdly easy and couldn't understand why he hadn't understood it before. Its the same with inventions. So its no use having an engineer on the witness stand testify against a patent by saying I'm skilled in the art and this looks obvious to me. You need something a bit less subjective. So to prove a patent obvious you have to locate some piece of prior art that almost does what is in the patent, then find another piece of prior art that fills the gap, and then find a motivation (such as a problem with the first piece of art) that would lead an engineer to logically put the two together. You can string several such steps together, and the bits of prior art can be as obscure as you want, as long as they actually were published. What you cannot do is assume even the tiniest inventive step in this process. In short the person skilled in the art of patent law isn't any real kind of person, its more like Google with an inference engine attached. (Actually thats a pretty cool idea). Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] US Patent for the idea of using Haskell to implement UAX #9
This patent has zero practical impact. When the patent was written there was no Unicode support, so the implementation translates the input into lists of integers instead of lists of characters. Crucially this step was also written into all three independent claims (which are the only bit of a patent that actually matters). So you are free to re-implement this algorithm provided that you manipulate lists of characters rather than lists of integers. Now that GHC has full unicode support this should not be a problem. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Data.Binary.GetT or ... ?
On 13/03/10 10:06, Juraj Hercek wrote: Hello, I'm thinking about using Data.Binary to parse binary stream of data. Binary data stream consists of messages which can have one or more (sometimes couple of hundreds) sub-messages. The stream is spitting out data slowly. I would like to parse this data with Data.Binary.Get monad, but I would like to send sub-messages to a STM channel while parsing, so observers could handle them during parsing process. I think you could do this by having your top-level Get action return a list of IO actions, like this: bigGet :: Get ([IO ()]) Then arrange for the parser for each smaller sub-message to return the corresponding action. In this case these actions will be calls to atomic to run the appropriate STM action. The trick is in lazyness: the lazy bytestring is read as it comes in, and hence is translated to a lazy list of IO actions, which are also executed as they come in. Hope this helps, Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] First time haskell - parse error!
Thats because you can't put a where in a then clause. Move the where stuff to the end of the function. On 09/03/10 19:04, boblettoj wrote: Hi, i am getting an error when trying to compile this part of my program, its my first time using haskell and as lovely as it is it didn't give me very much to go on in the error message! codescore :: String - String - String score [s] [] = false score [s] [g] = if valid 4 g then (s1 ++ s2 ++ s3 ++ s4) where s1 = Golds s2 = show (gold s g) s3 = , Silvers s4 = show (silver s g) else Bad Guess/code when i try to compile it says: test.hs 63:29: parse error on input 'where' (its the line beginning with 'then') Anybody got any ideas whats going on? thanks! ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What happened in Ohloh?
On 19/02/10 22:31, Don Stewart wrote: paul: I'd like to use this kind of graph at work as evidence that Haskell is on a growth trajectory. You might be more interested in data from Hackage: http://www.galois.com/blog/2009/03/23/one-million-haskell-downloads/ runched when we passed the 1M downloads mark a year ago (closer to 2M downloads now). We've also got just shy of 2000 packages on Hackage, up from 1100 a year ago (~3 new packages a day) Thanks Don. I've already used this data in presentations. I don't want to use the Hackage upload graph you posted because a) its got more to do with the growth of Hackage than the growth of Haskell, and b) it levels off. I need something with more visual punch. This is always a problem, related to the Why is Haskell so little used in Industry question. Decision makers use a simple chain of reasoning: I've never heard of it = academic language = can't hire programmers = unsupportable software. Maybe I should write a guide to Haskell advocacy in the workplace. Would there be any interest? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] What happened in Ohloh?
If you go to http://www.ohloh.net/languages/compare?l0=haskellmeasure=projects and look at the number (not percentage) of Haskell projects you see it rise exponentially until the start of 2008 and then suddenly drop away. Does anyone know what happened? Assuming this is just an artefact because they aren't scanning Haskell project hosts, can we get them to fix it? I'd like to use this kind of graph at work as evidence that Haskell is on a growth trajectory. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Please help me debug my arrow
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. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Please help me debug my arrow
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. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] consulting and contracting
On 15/12/09 21:19, Anton van Straaten wrote: Without that advocacy, this client would have used Java by default. As it was, the first of those two systems was developed in parallel with a Java version, and we used the two versions to verify each other's results. For the second system, a Java version wasn't deemed necessary, partly because the comparison succeeded in making Haskell's advantages sufficiently clear. Can you give us some more details on this dual-language project? I'm trying to collect objective evidence of the relative advantages of Haskell and Java (or any other languages) and this kind of comparison is gold dust. Very few companies are prepared to develop the same system twice. SLOC counts are good objective evidence (preferably from a standard SLOC counter such as http://www.dwheeler.com/sloccount/). Days of effort in development and defect counts are also powerful (although more subject to random noise: give several developers the same job and developer effort seems to vary even more than SLOC). Also any specific anecdotes about changed requirements, defects discovered by QuickCheck can also be useful. They are not objective evidence, but people listen to stories more readily than statistics. Of course if you can reveal the client's name that would also be very useful, for the same reason. But I understand that may not be possible. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why?
On 10/12/09 12:07, Magnus Therning wrote: As I understand it it all started with laziness. I don't know if laziness is impossible without purity, but talks and papers tend to say something like laziness has kept Haskell pure. This is true, but laziness has its own advantages. Suppose I have two modules, Foo and Bar. Foo generates a data structure which is then consumed by Bar (possibly with some other component calling both of them). In a strict language I have to choose between one of these three options: 1. Foo generates the structure all at once, and some kind of reference is then passed to Bar. This is nice, simple and modular, but it only works for small structures. There can also be a problem if the structure is slow to generate but is only consumed a bit at a time (e.g. by the user interface) because Bar can only start work once Foo has finished the whole thing. You may also find the Foo is doing lots of unnecessary work building bits of the structure that Bar uses only rarely. 2. Foo and Bar are built together in a single module with their functionality interleaved. This means that Foo can build a bit of the structure, have Bar process it, and so on. However it also destroys any modularity the system might have had. If Bar is part of the user interface, for instance, it means that core functionality gets mixed up. 3. Implement some kind of generator object. This takes a lot of code and makes the logic of Foo and Bar harder to follow. For instance the version of Foo from option 1 might have had a loop of the form foreach i in xs. Now i has to be turned into some kind of member variable with logic to move to the next instance. Of course what you are really doing is creating an ad-hoc hand-coded version of lazy evaluation. Different applications are going to require different choices. Worse yet, the right answer can change. For instance you may start with option 1, then discover that the program runs too slowly. Or marketing decide that the maximum size of the data structure has to be increased. So at that point you have to rewrite a big chunk of code. Or else you go with option 2 or 3 because the designer thought it was necessary for efficiency when in fact option 1 would have done nicely. Of course with lazy evaluation you get option 3 all the time automatically. So its just not a problem. This makes the design much simpler because things that previously had to be decided by a human are now decided by the compiler. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] You are in a twisty maze of concurrency libraries, all different ...
On 04/12/09 11:51, Patrick Caldon wrote: I'm looking for the right concurrency library/semantics for what should be a reasonably simple problem. I have a little simulator: runWorldSim :: MTGen - SimState - IO SimState it takes about a second to run on a PC. It's functional except it whacks the rng, which needs IO. I run 5-10 of these jobs, and then use: mergeWorld :: [SimState] - SimState to pick the best features of the runs and build another possible world (state). Then I use this new world to run another 5-10 jobs and so on. I run this through ~2 iterations. It's an obvious place for parallelism. If you can get rid of the need for IO then you can use Control.Parallel to evaluate pure functions instead. If you only use IO for the random numbers then you can either keep a StdGen in your SimState or else use a State StdGen monad. Since your random number use is presumably already in monadic IO you could probably switch to a state monad fairly trivially. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] seems like I'm on the wrong track
On 02/12/09 01:55, Michael Mossey wrote: I have a quite messy problem which is describable as a big state machine, at least in the way I think of it. An input event can trigger a cascade of changes to the state. Channel numbers must be assigned and tracked, table numbers as well, decisions about whether to create a new table or re-use an old one, global variables and commands added and/or modified, etc. So I am hoping for a comment from that perspective. First, I wonder if some of the ideas in Functional Reactive Programming might help; its a very clean and declarative way of dealing with messy event-based stuff like this. Second, more generally, for Haskell design you need to take a step back and think about the mathematical relations between things in your domain that an application programmer cares about. Then you can think about how to map from your domain model to an implementation like CSound. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell as an alternative to Java
On 18/11/09 11:54, Philippos Apolinarius wrote: I wonder whether the Haskell community tryed to reproduce the study Lisp as an alternative to Java, by Ron Garret / Erann Gat. Sort of. See http://www.haskell.org/haskellwiki/Phone_number Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Time and space complexity of take k . sort
This question on StackOverflow asked about how to find the largest 100 items in a very long list: http://stackoverflow.com/questions/1602998/fastest-way-to-obtain-the-largest-x-numbers-from-a-very-large-unsorted-list/1603198#1603198 I replied that you could do it with something like this (but here taking the k smallest to strip out some irrelevant complications): takeLargest k = take k . sort Because sort is lazily evaluated this only does enough sorting to find the first k elements. I guess the complexity is something like O(n*k*log(k)). But of equal practical interest is the space complexity. The optimum algorithm is to take the first k items, sort them, and then iterate through the remaining items by adding each item to the sorted list and then throwing out the highest one. That has space complexity O(k). What does the function above do? Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Time and space complexity of take k . sort
On 22/10/09 15:31, Paul Johnson wrote: takeLargest k = take k . sort Because sort is lazily evaluated this only does enough sorting to find the first k elements. I guess the complexity is something like O(n*k*log(k)). Correction: O(n*log(k)) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell-tan competition
What about Lambdabot? On 10/10/09 20:22, Miguel Mitrofanov wrote: Just a note: Haskell and 'tan' in one sentence, combined with some girlish flavour, makes me think about Audrey TANg. On 10 Oct 2009, at 23:02, Svein Ove Aas wrote: I say competition, but.. at the moment I'm only aware of a single Haskell-tan, namely the one at http://www.reddit.com/r/programming/comments/9ss7n/haskell%E3%82%BF%E3%83%B3_%E7%B5%B5/. This cannot stand. Haskell needs an anthropomorphized personification, like any other modern language. Anyway, have any of you seen any others? -- Svein Ove Aas ___ 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
Re: [Haskell-cafe] Test.QuickCheck: generate
On 08/10/09 04:57, David Menendez wrote: On Wed, Oct 7, 2009 at 8:29 PM, Michael Mosseym...@alumni.caltech.edu wrote: In Test.QuickCheck, the type of 'generate' is generate :: Int - StdGen - Gen a - a I can't find docs that explain what the Int does. Some docs are here: Judging by the source code, the integer is the upper bound for the size parameter. If you are generating a list, for example, it gives the maximum size of the list Thats right. Its the size parameter, and what it does depends on the instance of Arbitrary. Arbitrary numbers will be within +/- size. Arbitrary lists will be of maximum length size. On the other hand arbitrary booleans will just be True or False. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell for Physicists
I can't help with the title, but you might show how Haskell can help avoid the subtle bugs that create erroneous results. Start with the dimensional library (http://hackage.haskell.org/package/dimensional). Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Proof in Haskell
One alternative approach is to use QuickCheck to test many trees and look for counter-examples. You can also use SmallCheck to do an exhaustive check up to a chosen size of tree. To do this with QuickCheck you would write a function such as prop_mirror :: Node a - Bool prop_mirror x = (mirror (mirror x)) == x You would also need to define an instance of Arbitrary for Node to create random values of the Node type. Then you can call: quickCheck prop_mirror and it will call the prop_mirror function with 100 random test cases. Not the formal proof you wanted, but still very effective at finding bugs. On 25/09/09 12:14, pat browne wrote: Hi, Below is a function that returns a mirror of a tree, originally from: http://www.nijoruj.org/~as/2009/04/20/A-little-fun.html where it was used to demonstrate the use of Haskabelle(1) which converts Haskell programs to the Isabelle theorem prover. Isabelle was used to show that the Haskell implementation of mirror is a model for the axiom: mirror (mirror x) = x My question is this: Is there any way to achieve such a proof in Haskell itself? GHC appears to reject equations such has mirror (mirror x) = x mirror (mirror(Node x y z)) = Node x y z Regards, Pat =CODE= module BTree where data Tree a = Tip | Node (Tree a) a (Tree a) mirror :: Tree a - Tree a mirror (Node x y z) = Node (mirror z) y (mirror x) mirror Tip = Tip (1)Thanks to John Ramsdell for the link to Haskabelle: http://www.cl.cam.ac.uk/research/hvg/Isabelle/haskabelle.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
Re: [Haskell-cafe] Is it possible to do type-level arithmetic without UndeciableInstances?
This is a bit beyond my normal level of expertise, but if I understand it correctly the type checker is normally limited to type functions that are primitive recursive (http://en.wikipedia.org/wiki/Primitive_recursive_function). This means that they are guaranteed to terminate, but on the other hand the resulting language is not Turing complete. Setting UndecidableInstances lifts the Primitive Recursive restriction, making the type checker Turing Complete, but also creating the potential for endless loops. So yes, you can do type arithmetic without UndecidableInstances, provided you limit yourself to the Primitive Recursive axioms. The Wikipedia page lists them, and turning them into Haskell type classes shouldn't be more than a few milli-Olegs. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell] The speed, size and dependability of programming languages
Lyle Kopnicky wrote: I think it's a combination of 1) the expressiveness measure is too simplistic, measuring number of lines alone, or counting comments, and 2) the problem set is skewed toward number-crunching, which is not (say) Prolog's strong suit. Also there is a strong tendency to optimise the code for performance rather than conciseness (concision?). In the past this tended to bloat (e.g.) Haskell entries as simple intuitive code was replaced by arrays of unboxed integers and similar C-like constructs. ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell-cafe] Building a better dog house?
michael rice wrote: I was just looking at my UML (Unified Modeling Language) User Guide and discovered this: The number of object-oriented methods increased from fewer than 10 to more than 50 during the period between 1989 and 1994. pg. xviii, Booch, Rumbaugh, Jacobson, 1999 Is there a modeling methodology recommended for functional languages? Michael UML of course is not a methodology, its a language. Rational Unified Process (RUP) is a methodology. There is no recommended methodology for functional programming, but large chunks of RUP and most similar methodologies have little to do with OO programming, and therefore could be used as-is. All the project planning, configuration management, requirements management and so on will work just fine. When it comes to the software design in functional languages I find it best to start by looking for a domain analysis of the problem (something that RUP includes as well, if I recall correctly). Then try to translate that domain analysis into an embedded domain specific language (EDSL). Ideally the EDSL should allow you to describe anything that is physically or logically possible in the domain, but nothing that is impossible. Then you can go ahead and create your software by translating the requirements directly into the EDSL. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] looking for suggestion on pattern matching problem
Sounds like you need regular expressions applied to the string representation, although the sequence of increasing numbers is not something any of the standard regexp packages do. So you will have to roll your own. Alternatively you could use one of the parsing libraries to parse the string and define sequence of increasing numbers using a stateful parser. Paul. Daryoush Mehrtash wrote: I am trying to analyze a list of items (say integers) for longest matches on patterns and their location on the list. One catch is that pattern may be defined in terms of other patterns. Example of patterns would be the any sequence of increasing numbers, or sequence of increasing numbers followed by upto 5 zeros then followed by any odd digits. I don't know much about the actual patterns, but would like to be able to define EDSL for composing the patterns and an execution environment to actually find the patterns. I like to find out various ways I can structure the problem and its trade offs. I appreciate any books, articles, suggestions, papers, etc on this type of problems. Thanks, Daryoush ___ 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
Re: [Haskell] Helpful libraries to implement a board game?
Frank Rosemeier wrote: Dear Haskellers, I would like to implement a board game for a single player in Haskell. The pieces may be moved one step in any direction if there is no piece next to it, and the goal is to rearrange the pieces to their home positions. The Haskell program should find an optimal solution (with minimal number of moves). Can anybody recommend some helpful libraries for this task? Any hints are very welcome! This sounds like a homework problem, so I'll be a bit vague. This is a job for a combination of the list and state monads. Something of type ListT (State GameState) will probably be important. You just need to define the GameState type and something to give you a list of legal next moves :: GameState - [GameState]. After that, its trivial. Paul. ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell-cafe] [SoC] XML Schema Implementation
On Mar 31, 2009, at 12:16 AM, Vlad Dogaru wrote: More specifically, I would be interested in the degree the Haskell community uses XML Schema, and if you were tempted to use it if we had an implementation. To further expand the question, how useful do you consider each of these components: * a validator * a pretty-printer * a translator from XML Schema to Haskell, similar to DtdToHaskell[4] Haskell badly needs better middleware. At present that means WS-* stuff, which is all defined in XML Schema. So the Xmls2Haskell translator would be a really valuable foundation for that. Also it would be particularly valuable if the XML Schema parser generated a parse tree which was then interpreted by the Haskell generator, as that would make it much easier to build other tools (e.g. type validators, schema version translators) on top of the XML Schema parser. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Looking for a co-founder for a startup using Haskell
Ed McCaffrey wrote: Other investors I have spoken with want me to contact them again when it is further developed; That means no. See http://blog.guykawasaki.com/2006/01/the_top_ten_lie.html Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] MPTC inheritance
Derek Gladding wrote: Please forgive me if I'm still mentally contaminated by the OO way of seeing (and discussing) the universe, but I'm trying to figure out how to inherit an interface from a multi-parameter type class. [...] but this isn't allowed (kind mismatch). Kinds are a meta-type system for types. Because Haskell has such a rich type system, the types themselves need a type-like system. These are kinds. You never declare kinds (apart from certain language extensions not in use here): the compiler infers them. This suggests that your problem is in the types lower down. Probably you are using a or b in a way that implies they take a type argument in one place (kind * - *) and not in another place (kind *). ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] instance MonadFix GenParser
I want to write a parser for a Haskell-like type language. Amongst other things this means having a symbol table of top-level declarations. So for instance I want to be able to write in my type language: type Foo = Bar Int data Bar a = Bar String a I can come up with a parser that identifies Bar in the type synonym as the name of another type. I could define a type to return from the parser which just has that as a string, but then I would have to write another data type which is essentially the same but replaces the string name with the actual data type, and a mapping function to use a symbol table to convert one into the other, like this: data ParsedTypeExpr = ParsedTypeExpr {parsedBaseType :: String, parsedTypeArgs :: [String]} data TypeExpr = TypeExpr {baseType :: MyType, typeArgs :: [String]} convertTypeExpr :: (String - MyType) - ParsedTypeExpr - TypeExpr I want to short-circuit this by looking up the definition of Bar in the parser. But that requires the symbol table to exist during the parse. I have to admit I haven't quite got my head around MonadFix yet, but if I understand it correctly I should be able to have a top level parser something like this: parseDeclarations :: Parser [Declaration] parseDeclarations = mdo decls - many ParseDeclaration symbols let symbols = makeSymbolTable decls return decls Unfortunately GenParser isn't an instance of MonadFix, so this won't work. Is there a good reason why GenParser can't be an instance of MonadFix? If not, what would the instance declaration be? Thanks, Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] instance MonadFix GenParser
Oops. The last code sample should have been parseDeclarations :: Parser [Declaration] parseDeclarations = mdo decls - many ParseDeclaration symbols let symbols = makeSymbolTable decls return decls ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: permuting a list
See http://okmij.org/ftp/Haskell/perfect-shuffle.txt Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Race condition possible?
Peter Verswyvelen wrote: Consider the following code stamp v x = do t - getCurrentTime putMVar v (x,t) Is it possible - with GHC - that a thread switch happens after the t - getCurrentTime and the putMVar v (x,t)? If so, how would it be possible to make sure that the operation of reading the current time and writing the pair to the MVar is an atomic operation, in the sense that no thread switch can happen between the two? Would this require STM? Thanks again for sharing your wisdom with me :) Peter I'm not entirely sure what you are trying to achieve here. Presumably you want v to contain the (value, time) pair as soon as possible after time t. Of course it won't be instantaneous. So another thread could observe that at time (t+delta) the variable v does not yet contain (x,t). Is this a problem? Atomic transactions won't work because getCurrentTime is of type IO Time, whereas anything inside atomic has to be of type STM a. In theory you could lock out context switches by messing around with the GHC runtime, but if you are running on a multicore machine then that won't work either. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] The Haskell re-branding exercise
Paul Johnson wrote: A call has gone out http://www.haskell.org/pipermail/haskell-cafe/2008-December/051836.html for a new logo for Haskell. Candidates (including a couple http://www.haskell.org/haskellwiki/Image:Haskell-logo-revolution.png of mine http://www.haskell.org/sitewiki/images/f/fd/Ouroborous-oval.png) are accumulating here http://www.haskell.org/haskellwiki/Haskell_logos/New_logo_ideas. There has also been a long thread on the Haskell Cafe mailing list. So what's happening about this? Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] pure crisis :)
Bulat Ziganshin wrote: Hello haskell-cafe, pure functional denotation for crisis: (_|_) See also: http://www.haskell.org/haskellwiki/Humor/Enron http://paulspontifications.blogspot.com/2008/09/why-banks-collapsed-and-how-paper-on.html Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Employment
Tom Hawkins wrote: Such a database would help me counter by boss's argument that it's impossible to find and hire Haskell programmers. There was a thread last week where someone asked who would be interested in a hypothetical Haskell job. He got about 20 positive responses. This agrees with the experience of Microsoft Research in 2006 when they advertised for a third person to help with GHC development. They also had about 20 applicants. So next time I hear the you can't get the programmers line I'm going to respond with something like this: If you post an advert for a Haskell developer you will get 20 applicants. All of those people will be the kind of developer who learns new programming languages to improve their own abilities and stretch themselves, because nobody yet learns Haskell just to get a job. If you post an advert for a Java developer you will get 200 applicants. Most of them will be the kind of developer who learned Java because there are lots of Java jobs out there, and as long as they know enough to hold down a job then they see no reason to learn anything. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] teaching functional programming at work
Warren Harris wrote: I am seeking suggestions from the haskell cafe for teaching functional programming concepts to colleagues at work. I'd suggest starting with a couple of hours of Why Haskell talk to sell them on the concepts, followed by something like the the study group you mentioned for anyone who wants to pursue it. If you can get them to spare the time then the video of the SPJ talk from last year might be a good starting point. Failing that, try presenting them with some case studies of here is where Haskell (saves effort) / (improves modularity) in the kind of environment where you work. Explain how monads are a reprogrammable semicolon and show an application of that. No need to go into bind operators, just show what the code looks like before and after monads. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Logos of Other Languages
Paulo Tanimoto wrote: Another idea: something in the form of an Ouroboros. Is that already taken for a programming language? http://en.wikipedia.org/wiki/Ouroboros Something like this? http://www.haskell.org/sitewiki/images/f/fd/Ouroborous-oval.png Paul ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] The Haskell re-branding exercise
A call has gone out for a new logo for Haskell. Candidates (including a couple of mine) are accumulating here. There has also been a long thread on the Haskell Cafe mailing list. I've lived through a couple of corporate rebranding exercises in my time, and I've read about some others. They follow a pattern: Management decide that the organisation needs a makeover to change public perception. A new corporate "look and feel" is part of this, and a new logo is therefore required. The rest of the makeover may be deep or shallow; that doesn't affect the rest of this story. The new branding is released with as much fanfare as possible. Press releases are released. Staff are given briefings about the significance of the whole exercise and the bold new future that it symbolises. The staff universally agree that the new logo is not a patch on the old one. The old one was a much loved friend; it stood for something; people have spent years working for it. The new one is obviously a piece of cheap gimcrackery munged up by an overpaid consultancy hired by senior managers who mistake image for substance. A ten year-old with an Etch-a-Sketch could have done better. Over time the new logo blends in and becomes part of the scenery. Years pass. Go to stage 1 and repeat. This suggests that the current effort to find a new logo for Haskell needs to go back to the basics. Its no good expecting consensus on one of the suggestions because there are too many options and everyone has their favourite. Nothing will attract a majority of the community. Furthermore I think that (just like programmers everywhere) we have dived into development before deciding what the requirements are. This is reflected in the mailing list discussion, where two broad positions seem to be emerging. On one side we have what I think of as the "Vulcans". This group sees Haskell as abstract and difficult, and believes that the logo should reflect these qualities. They want mathematical symbols to dominate the design. On the other side we have the "Warm Fuzzies". They want Haskell to be perceived as accessible and welcoming, and so want a logo featuring something warm and friendly. A paradox of the Haskell world is that, while the language is Vulcan, the community around it is dominated by Warm Fuzziness. Clearly the two are not mutually exclusive. A rebranding exercise needs to start with a short list of adjectives that the brand is to represent, and I think that the Haskell community needs to decide this before it fires up Inkscape. To that end, here are a sample of adjectives in alphabetical order: abstract, academic, accessible, accurate, adventurous, business-like, communal, complicated, dangerous, different, easy, exciting, familiar, friendly, fun, fuzzy, hard, interesting, inventive, precise, productive, profitable, reliable, revolutionary, safe, simple, strange, supportive, warm, welcoming. What are the top three adjectives we want to project? Once we have decided that, we can write a brief for the Haskell logo. Note that the selected adjectives need not be related. In fact they may be partly contradictory. I've already noted that the language is Vulcan whereas the community is Warm and Friendly. So they might reasonably be the three adjectives (though I wouldn't take "Vulcan" too literally). The challenge will then be for the graphical work to project these qualities, even if they seem incompatible. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell as a religion
Hugo Pacheco wrote: http://www.aegisub.net/2008/12/if-programming-languages-were-religions.html What does it mean, *If* Programming Languages were religions? Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Animated line art
Andrew Coppin wrote: So I want some sort of sequencing primitives. Sequencing generally suggests a monad. something = do { action1; delay 10; action2} I had a go at writing what I thought the interface might look like. (Fortunately, I made no attempt to *implement* it - otherwise I would doubtless have wasted huge amounts of time implementing something that isn't designed right yet!) Unfortunately Haskell doesn't really provide a way to write an interface, and then write the implementation behind it seperately somewhere else. So the code I wrote wasn't actually compilable at all, but it was useful to sketch something out. When I do this I generally write functions like foo = error foo: Not implemented yet My initial idea was that I could have some kind of monad for controlling adding and removing stuff. The monad could provide an add action that adds a visual object to the frame and returns a unique ID. Then you could have a remove action that removes the specified ID again. And a wait action that makes the display stay the same for so many seconds. (But the visual objects may internally be animated.) I'd suggest that each object has its own action to animate it. You will need to write a custom monad to interleave actions. See http://www.cs.chalmers.se/~koen/pubs/jfp99-monad.ps for something along the right lines. Then I hit upon the idea that maybe one thread of control could spawn a second one - so that for example one thread could generate a bunch of snowflakes raining down the screen while a seperate thread rotates a geometric figure in the center. Or something. Sounds right. Of course, these threads have no need (or use) for actually running concurrently - they are only concurrent in the sence that they both affect the same frame, rather than their actions happening one after another on consecutive frames. Next I got to thinking that maybe these threads of control might need to communicate for synchronisation. E.g., when a rotating line reaches 90° with another line, a signal is sent to another thread, which then adds another visual element or stops the animation or something. The parent thread *could* algebraicly _compute_ what time this will happen, but sending a signal is much simpler. (E.g., if you change the speed of an animation, the threads still stay synchronised without you having to remember to adjust parameters in your calculations all over the place...) Yup. I did exactly this, albeit for a very different application. Unfortunately the code belongs to my employer so I can't post it. But if you look at the paper above and also read about the ContT monad you will get the right idea. Its a bit mind-bending, but you suspend a thread by getting its continuation (using callCC) and stuffing it into whatever data structure is being used to hold pending threads (e.g. a semaphore queue). Or you could use the existing concurrent threads mechanism, which is kludgier but less work. There's still one little problem though. The threads of control are for sequencing stuff. They are inherantly discrete; *add* this thing, *remove* this other thing, *send* this signal, *wait* to receive a signal, etc. But something like, say, rotating a line, is inherantly continuous. So there's a discrete system for sequencing stuff - which I seem to have worked out fairly well - and there also needs to be a continuous system for doing all the things with are smooth functions of time. Thats where Reactive stuff comes in. So maybe the continuous stuff should just be a type alias to a regular Haskell function? Ah, but wait... I said I might want to send a signal when an animation reaches a specific stage, right? So these functions need to do more than just map time to some other variable; they need to be able to send signals. And hey, actually, what are the chances of a time sample exactly lining up with the instant that the notable event occurs? How do I want to handle that? Events are part of reactive frameworks. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Data.Map.fromListWith
I've just been looking at the Data.Map function fromListWith. According to the docs, it has the type: * fromListWith* :: Ord http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Ord.html#t%3AOrd k = (a - a - a) - [(k, a)] - Map http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Map.html#t%3AMap k a I'd have thought that a better type would be * fromListWith* :: Ord http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Ord.html#t%3AOrd k = (a - b - b) - [(k, a)] - Map http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Map.html#t%3AMap k b This wouldn't break any existing code, but would allow things like fromListWith (:) to do the Right Thing. Would this be a sensible change (along with the other with functions in the module). Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Data.Map.fromListWith
Alexander Dunlap wrote: On Sat, Dec 6, 2008 at 12:22 PM, Paul Johnson [EMAIL PROTECTED] wrote: I've just been looking at the Data.Map function fromListWith. According to the docs, it has the type: * fromListWith* :: Ord http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Ord.html#t%3AOrd k = (a - a - a) - [(k, a)] - Map http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Map.html#t%3AMap k a I'd have thought that a better type would be * fromListWith* :: Ord http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Ord.html#t%3AOrd k = (a - b - b) - [(k, a)] - Map http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Map.html#t%3AMap k b This wouldn't break any existing code, but would allow things like fromListWith (:) to do the Right Thing. Would this be a sensible change (along with the other with functions in the module). Paul. Hi, I don't think that type makes sense. fromListWith takes a list of [(key,value)] and a combining function to combine the values when there are multiple pairs with the same key. Ahh yes. I was thinking that the job of fromListWith was analogous to foldr, but carrying out the fold on a per-key basis. However I see now that it is more like foldr1 than foldr because foldr needs a zero value. So we could have fromListWithZero :: Ord k = (a - b - b) - b - [(k, a)] - Map k b fromListWithZero combiner zero pairs = ... The first time a key is seen the combining function is called with zero as its second argument. E.g. fromListWithZero (:) [] xs Or is that too much trouble? Accumulating a collection of lists is the most obvious use of this function, and you can do that already (albeit rather clunkily) with fromListWith (++) $ map (\(k,v) - (k, [v]) $ xs The only time that fromListWithZero would be especially useful is when you want the fold to be eager. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Instances that shouldn't overlap
Hi, I'm trying to set up some operators for applicative versions of prelude types. For instance: -- | Applicative Equality. class (Eq a) = AppEq f a where (.==.), (./=.) :: f a - f a - f Bool instance (Applicative f, Eq a) = AppEq f a where (.==.) = liftA2 (==) (./=.) = liftA2 (/=) Hopefully the intention is fairly straightforward: if f is an instance of Applicative then the lifted implementation of the underlying type. Otherwise I can just give my own instance, which is useful for things that wrap prelude types but where fmap doesn't work. For instance: data (Ord a) = Interval a = Interval a a instance (Ord a) = AppEq Interval a where i1@(Interval _ u1) .==. i2@(Interval _ u2) | isSingleton i1 isSingleton i2 u1 == u2 = Interval True True | has i1 u2 || has i2 u1= Interval False True | otherwise = Interval False False i1 ./=. i2 = let Interval b1 b2 = (i1 .==. i2) in Interval (not b2) (not b1) isSingleton :: (Ord a) = Interval a - Bool isSingleton (Interval lower upper) = lower == upper has :: (Ord a) = Interval a - a - Bool has (Interval lower upper) v = v = lower v = upper You can't (easily) define fmap for Interval because the function given as an argument might not be monotonic. So instead you have to write custom implementations for each lifted function, as shown here for (.==.) and (./=.) . The same principle works for AppOrd, AppNum etc, but I'm trying to solve the problem for just AppEq for now. This compiles, but when I try to use it I get this in ghci: *Interval let i1 = Interval 4 5 *Interval let i2 = Interval 4 6 *Interval i1 .==. i2 interactive:1:0: Overlapping instances for AppEq Interval Integer arising from a use of `.==.' at interactive:1:0-9 Matching instances: instance (Ord a) = AppEq Interval a -- Defined at Interval.hs:(22,0)-(27,78) instance (Control.Applicative.Applicative f, Eq a) = AppEq f a -- Defined at AppPrelude.hs:(32,0)-(34,23) In the expression: i1 .==. i2 In the definition of `it': it = i1 .==. i2 I'm puzzled, because Interval is not an instance of Applicative, so the second instance doesn't apply. Can anyone help me out? I'm using ghc 6.8.3, so its possible that this was a bug fixed in 6.10. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Instances that shouldn't overlap
Paul Johnson wrote: Hi, I'm trying to set up some operators for applicative versions of prelude types. I forgot to mention, I'm using {-# OPTIONS_GHC -fallow-undecidable-instances -XFlexibleInstances -XMultiParamTypeClasses #-} Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell] Probably a trivial thing for people knowing Haskell
Friedrich wrote: Ok to be more concrete is the laziness hidden here? check_line line sum count = let match = matchRegex regexp line in case match of Just strs - (sum + read (head strs) :: Integer, count + 1) Nothing - (sum, count) Probably. I would guess that sum and count are not being forced (i.e. evaluated) until the end of the computation, so instead of computing the result of sum + read (head strs) your program is just creating a thunk. Because this is in a loop, you wind up with a chain of thunks. Try putting turning the Just line into something like Just strs - (seq sum $ sum + read (head strs) :: Integer, seq count $ count + 1) That would be my guess. But I could be wrong. Paul. ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
[Haskell-cafe] Re: [Haskell] Probably a trivial thing for people knowing Haskell
Friedrich wrote: Paul Johnson [EMAIL PROTECTED] writes: [...] Because file reading is lazy, each line is only read when it is to be processed, and then gets reaped by the garbage collector. So it all runs in constant memory. Would you mind to elaborate a bit about it. What's so terrible to open one file after the other, reading it line by line and close the file thereafter. Its not wrong, its just more work. Also from a structural point of view its better to separate the code that reads the files from the code that processes the text. The conventional way forces you to mix them. (By the way, putting in the top level type declarations helps a lot when you make a mistake.) Well I have my problems with that. Probably it comes from using Languages like Ruby and my special dislike of typing things comes especially from Java, C++ (well C is not innocent in that regard also. OK, its a matter of personal preference (although it really does help anyone else reading your code). However I find that if I leave out the top level definitions then type error messages at compile time are much harder to figure out, especially in a big program. So I find that the extra typing pays in the long run. :-/ Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell] Probably a trivial thing for people knowing Haskell
Friedrich wrote: I've written just a few programs in Haskell one in a comparison for a task I had nearly daily. The first thing I notice is that this is clearly a direct translation from something like Perl. Thats understandable, but I'd suggest rewriting it with something like this (untested, uncompiled code) -- Concatenate all the files into one big string. File reading is lazy, so this won't take all the memory. getAllFiles :: [String] - IO String getAllFiles paths = do contents - mapM getFile paths return $ concat contents Then use lines to split the result into individual lines and process them using filter, map and foldr. Because file reading is lazy, each line is only read when it is to be processed, and then gets reaped by the garbage collector. So it all runs in constant memory. (By the way, putting in the top level type declarations helps a lot when you make a mistake.) One thing you are doing right is keeping a (sum, count) pair. A gotcha with Haskell is to compute an average of a list of numbers like this: mean :: [Double] - Double mean xs = sum xs / fromIntegral (length xs) The problem with this is that it has to traverse the list twice, which means that the whole list has to be held in memory. So instead you have to write something like: mean xs = let (total, count) = foldr (\x (t, c) - (t + x, c+1)) (0.0, 0) xs in total / fromIntegral count This is a pain, but it does only traverse the list once. See how you get on. Paul. The code analyzes Apache logs and picks some certain stuff from it and after that calculates a bit around with it. Here's the code module Main where import System import System.IO import System.Directory import System.IO.Error import Text.Regex import Control.Monad regexp = mkRegex (([0-9]+) Windows ex) main = do files - show_dir [0-9].* (sum,count) - run_on_all_files (0,0) files let dd = (fromIntegral (sum::Integer))/ (fromIntegral (count::Int)) in putStr(Download = ++ show sum ++ in ++ show count ++ days are ++ show dd ++ downloads/day\n) run_on_all_files (a,b) [] = return (a,b) run_on_all_files (a,b) (x:xs) = do (s,c) - run_on(a,b) x run_on_all_files (s,c) xs run_on (a,b) file_name = do handle - openFile file_name ReadMode (sum,count) - for_each_line (a,b) handle hClose handle return ((sum,count)) for_each_line (sum,count) handle = do l - try (hGetLine handle) case l of Left err | isEOFError err - return(sum,count) | otherwise - ioError err Right line - do let (nsum, ncount) = check_line line sum count for_each_line (nsum,ncount) handle check_line line sum count = let match = matchRegex regexp line in case match of Just strs - (sum + read (head strs) :: Integer, count + 1) Nothing - (sum, count) show_dir regmatch = do files - getDirectoryContents . let reg = mkRegex regmatch in return(filter (\file_name - let fm = matchRegex reg file_name in case fm of Just strs - True Nothing - False) files) The point is this code works if there are just say a few files files to check. But it trashes my machine with around 1751 files. It sucks memory as wild and so it does not run as I think it should. I think I've overseen something which is bad written. Would you mind to tell me where I did extraordinarily bad. With best regards Friedrich ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell ___ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Re: [Haskell-cafe] Re: What I wish someone had told me...
Derek Elkins wrote: All you need is a T-shirt: http://www.cafepress.com/skicalc Or http://www.cafepress.com/l_revolution Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Health effects
Andrew Coppin wrote: Oh, no. The entire bar is 2 Kg, I wasn't actually planning to eat the whole thing! o_O My god, my pancreas would explode or something... My Dad once ate two bars of dark cooking chocolate. He said he got some odd visual distortions; flickering auras around things, and size distortions where small things looked big and big things looked small. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell stacktrace
Pieter Laeremans wrote: Hello, I've written a cgi script in haskell, it crashes sometimes with the error message Prelude . tail : empty list Yup, been there, done that. First, look for all the uses of tail in your program and think hard about all of them. Wrap them in assert or trace functions to see if there are any clues to be had. Then take a look at the GHC debugger documentation. Debuggers for lazy languages (or indeed any language with closures) is difficult because execution order isn't related to where the faulty data came from. So if I say somewhere x = tail ys and then later on print x the print will trigger the error, but the faulty data ys may no longer be in scope, so you can't see it. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] trying to understand monad transformers....
Daryoush Mehrtash wrote: The MaybeT transformer is defined as: newtype MaybeT m a = MaybeT {runMaybeT :: m (Maybe http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Maybe a)} instance Functor http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor m = Functor http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor (MaybeT m) where fmap http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap f x = MaybeT $ http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:. fmap http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap (fmap http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap f) $ http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:. runMaybeT x Question: What does runMaybeT x mean? All monads (except IO) have a run function. E.g. runST for the ST monad, runState for the state function, and so on. A monadic action is actually a function that (typically) takes extra arguments and returns extra results. In the monadic action form these extra data are hidden, and its up to the monad bind function to thread them from one action to the next. The runX function for some monad X converts a monadic action into the underlying function with that data exposed. In most cases the monad is defined as a newtype wrapper around the function, so the run function is just the inverse of the constructor. In the case of a monad transformer the result of the function is not a value, its an action in another monad. Thats what you see in the case of MaybeT. A MaybeT action is actually a monadic action that itself returns a Maybe value. So you use runMaybeT to turn your MaybeT action into an action in the inner monad, and then run that action using its run function to finally get a Maybe result. Make sense? Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is it usual to read a Maybe (IORef a) ?
minh thu wrote: Do you suggest I use data Thing = Thing | None and IORef Thing instead of data Thing = Thing and Maybe (IORef Thing) ? I'm writing a data structure that can hold Things (and that can be mutated) or nothing (there is a hole in the wrapping data). I'd have thought you wanted IORef (Maybe Thing), which says that the pointer always exists, but may not point to anything. On the other hand Maybe (IORef Thing) says that the pointer may or may not exist. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Calling Lockheed, Indra, Thales, Raytheon
This is a strange question, I know, but is there anyone working in any of the above companies on this mailing list? Everyone will no doubt be wondering what they have in common. I'm afraid I can't discuss that. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Calling Lockheed, Indra, Thales, Raytheon
Paul Johnson wrote: This is a strange question, I know, but is there anyone working in any of the above companies on this mailing list? Everyone will no doubt be wondering what they have in common. I'm afraid I can't discuss that. I will say that this is not a job search, and I'm not trying to sell anyone anything. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: QuickCheck [Architecturally flawed]
Ryan Ingram wrote: I think you can use the duality of Writer/Reader to help you here; you have the law that, for suitable dual computations r and w, run_reader r (run_writer (w x)) == x Then you can build up a list of rules specifying which computations are dual; read64 is dual to write64, for example. You can then have some laws like: if r1 is dual to w1, and r2 is dual to w2, then r1 = \x - r2 = \y - (x,y) is dual to \(x,y) - w1 x w2 y if r1 is dual to w1, and r2 is dual to w2, then read1 = \b - case b of True - liftM Left r1 ; False - liftM Right r2 is dual to \x - case x of Left l - w1 l; Right r - w2 r You can then use these to build up more complicated reader/writer duals and verify that the main identity law holds. It's a little bit tricky; QuickCheck is not good at dealing with polymorphic data, but you could generalize this to a simple term ADT: data SimpleTerm = Leaf Word8 Word32 | Pair SimpleTerm SimpleTerm | Switch (Either SimpleTerm SimpleTerm) deriving Eq and make a suitable arbitrary instance for SimpleTerm to test your reader/writer. Leaf would test readN/writeN, or you can make custom leaves to test the other operations. -- ryan On Fri, Jul 11, 2008 at 11:10 AM, Andrew Coppin [EMAIL PROTECTED] wrote: For starters, what would be a good set of properties to confirm that any monad is actually working correctly? More particularly, how about a state monad? It's easy to screw up the implementation and pass the wrong state around. How would you catch that? See http://www.cs.chalmers.se/~rjmh/Papers/QuickCheckST.ps on QuickCheck tests for monadic properties. The basic idea is to write a Gen action to generate a list of actions in your target monad. Secondly, the monads themselves. I started writing things like if X has the lowest bit set then the lowest bit of the final byte of the output should be set... but then all I'm really doing is reimplementing the algorithm as a property rather than a monad! If a property fails, is the program wrong or is the property wrong This is a fundamental issue with the way that QuickCheck, or any other automatic test generator, works. QuickCheck tests are a formal specification of the properties of your program, so they have the same fundamental complexity as your program. See http://en.wikipedia.org/wiki/Kolmogorov_complexity for more on this. The only exception is when a complicated algorithm produces a simple result, such as sorting or square roots. There are two ways of dealing with this: 1: Write abbreviated properties that only specify part of your program's behaviour, and trust to single-case tests and code inspection for the rest. For instance a test for reverse done this way might test that reverse abcd = dcba and otherwise just check that the input and output strings were the same length. 2: Accept that your tests are going to be as long as the program itself. When a test fails, just figure out which is at fault (you have to do this for any testing method anyway). You still gain reliability because you have implemented the algorithm in two different ways, so hopefully a defect in one will not have a matching defect in the other. I say hopefully because the history of N-version programming suggests that such errors are not independent, even when the versions are developed by different teams. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Learning GADT types to simulate dependent types
I'm trying to understand how to use GADT types to simulate dependent types. I'm trying to write a version of list that uses Peano numbers in the types to keep track of how many elements are in the list. Like this: {-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-} module Plist where infixr 3 :| data Zero data S a class Add n1 n2 t | n1 n2 - t, n1 t - n2 instance Add Zero n n instance Add (S n1) n2 (S t) data Plist n a where Nil :: Plist Zero a (:|) :: a - Plist n a - Plist (S n) a instance (Show a) = Show (Plist n a) where show Nil = Nil show (x :| xs) = show x ++ :| ++ show xs pHead :: Plist (S n) a - a pHead (x :| _) = x pTail :: Plist (S n) a - Plist n a pTail (_ :| xs) = xs pConcat Nil ys = ys pConcat (x :| xs) ys = x :| pConcat xs ys Everything works except the last function (pConcat). I figured that it should add the lengths of its arguments together, so I created a class Add as shown in the Haskell Wiki at http://www.haskell.org/haskellwiki/Type_arithmetic. But now I'm stuck. When I try to load this module I get: Plist.hs:32:8: GADT pattern match in non-rigid context for `Nil' Tell GHC HQ if you'd like this to unify the context In the pattern: Nil In the definition of `pConcat': pConcat Nil ys = ys Failed, modules loaded: none. (Line 32 is pConcat Nil ys = ys) So how do I do this? Am I on the right track? Can someone help improve my Oleg rating? Thanks, Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Learning GADT types to simulate dependent types
Daniel Fischer wrote: My Oleg rating isn't high either, and certainly you can do it more elegant, but class Concat l1 l2 l3 | l1 l2 - l3, l1 l3 - l2 where pConcat :: l1 a - l2 a - l3 a instance Concat (Plist Zero) (Plist n) (Plist n) where pConcat _ ys = ys instance Concat (Plist n1) (Plist n2) (Plist t) = Concat (Plist (S n1)) (Plist n2) (Plist (S t)) where pConcat (x :| xs) ys = x :| pConcat xs ys works, you don't even need the Add class then - btw, you'd want instance Add n1 n2 t = Add (S n1) n2 (S t) anyway. Thanks, and also thanks to Dan Doel who showed how to do it with the new type families. I'll stick with the Fundeps solution here for the moment until type families settle down, but that method is cleaner. I was also able to write this: class Concat p1 p2 p3 | p1 p2 - p3, p1 p3 - p2 where pConcat :: p1 a - p2 a - p3 a pBogus :: p1 a - p2 a - p3 a instance Concat (Plist Zero) (Plist n) (Plist n) where pConcat _ ys = ys pBogus _ ys = ys instance Concat (Plist n1) (Plist n2) (Plist t) = Concat (Plist (S n1)) (Plist n2) (Plist (S t)) where pConcat (x :| xs) ys = x :| pConcat xs ys pBogus xs ys = ys And indeed the second definition of pBogus gave me a compile-time type error because the length of the result didn't agree with the type length. I'm going to be doing a presentation on Haskell for my boss soon, and this should definitely impress (he has a solid coding background). Thanks again, Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Laziness leaks
Achim Schneider wrote: There won't ever be a space leak without a time leak nor a time leak without a space leak. I'd just call it a leak. Actually I think you can have a space leak without a time leak. For instance if every time around the main loop I cons data onto a linked list that never gets freed then I have a space leak. If the list never gets used (or more realistically, if the program only ever uses the first N entries) then there is no time leak. I agree that a time leak implies a space leak though. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Two-iteration optimisation (was: GHC Predictability)
We've had a big debate over mean xs = foldl' (+) 0 xs / fromIntegral (length xs) For anyone who didn't follow it, the problem is that mean needs to traverse its argument twice, so the entire list has to be held in memory. So if xs = [1..10] then mean xs uses all your memory, but foldl' (+) 0 xs and length xs by themselves do not. The solution is for the programmer to rewrite mean to accumulate a pair containing the running total and count together, then do the division. This makes me wonder: could there be a compiler optimisation rule for this, collapsing two iterations over a list into one. I've never tried writing GHC rules, but something like: f (foldl' g x) (foldl' h x) = (uncurry f) (foldl' (\i (gt,ht) - (g i gt, h i ht))) The first problem that occurs to me is the number of permutations of fold and map functions. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] GHC predictability
Jeff Polakow wrote: [...] This can be easily fixed by defining a suitable strict sum: sum' = foldl' (+) 0 and now sum' has constant space. We could try to redefine mean using sum': mean1 xs = sum' xs / fromIntegral (length xs) but this still gobbles up memory. The reason is that xs is used twice and cannot be discarded as it is generated. As an experiment I tried using pointfree to see if it would do something similar. $ pointfree \xs - foldl' (+) 0 xs / fromIntegral (length xs) ap ((/) . foldl' (+) 0) (fromIntegral . length) But when I try this in GHCi 6.8.2 I get: Prelude Data.List Control.Monad let mean2 = ap ((/) . foldl' (+) 0) (fromIntegral . length) interactive:1:12: No instance for (Monad ((-) [b])) arising from a use of `ap' at interactive:1:12-58 Possible fix: add an instance declaration for (Monad ((-) [b])) In the expression: ap ((/) . foldl' (+) 0) (fromIntegral . length) In the definition of `mean2': mean2 = ap ((/) . foldl' (+) 0) (fromIntegral . length) Any ideas? Would the auto-generated pointfree version be any better if it could be made to work? Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What's the difference?
PR Stanley wrote: Hi What is the difference between data T0 f a = MkT0 a instance Eq (T0 f a) where ... and data T0 f a = MkT0 a instance Eq a = Eq (T0 f a) where ... The second one says that TO f a is only an instance of Eq if a is, while the first says that TO f a is an instance regardless of the type of its arguments. You can regard an instance declaration as an inference rule for the type checker, with = meaning implies (though I don't think its the answer to your other question about names). ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Announce: Decimal arithmetic package
I've just uploaded version 0.1.0 of a decimal arithmetic package to Hackage. Decimal numbers are stored as an Integral mantissa and a Word8 exponent, where the number stored is mantissa * 10^(-exponent). In other words the exponent is the number of decimal places stored. There are also routines for partitioning a value such that the sum of the parts is equal to the original value. This is useful in financial arithmetic. This came out of my ongoing work on an AMQP binding for Haskell. Version 0-10 of the AMQP spec includes decimal fractions defined in this way for financial applications, so I thought I'd make a proper job of it. A darcs repository will be set up shortly. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Wumpus World
iliali16 wrote: Hi guys I have to build the wumpus world problem. I didn't start yet since this is the first time in my life I have to do something like that and I feel not confident in starting it. So I have basic idea of what prolog and haskell can do and I know a bit of Java. I am wandering if you can tell me which one is best to use to build this problem.Thanks couse I am really confused This sounds like a homework problem. Any of those languages will do. Of course Haskell will be shorter. Jump in, get started. The way to solve a problem you don't understand is to do any bit of it you do understand, and then look at the problem again. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] doctest for haskell -- a good project?
Shaun Cutts wrote: I note that there is a unit testing framework for Haskell, but I don't see any doctest module. Might this be a good project? I once looked at doing this, but I didn't get very far. Haddock is important here because you want to include the tests as part of the documentation. QuickCheck properties in particular closely resemble a formal specification. For a couple of examples, see my RangedSet package and Neil Mitchel's FilePath package. I manually copied the RangedSet tests into the Haddock documentation, while Neil wrote a small Haskell script to extract his tests from his documentation automatically. Unfortunately his script is tied to specific aspects of his FilePath package. Haddock does not contain a full Haskell parser, which makes it difficult to extend in a principled way (or maybe I'm just not a good enough programmer). The problem is you need to have several different new kinds of mark-up, and its not always clear what to do. You need to support QuickCheck and HUnit. Also possibly SmallCheck and some other similar unit testing cum specification frameworks. For QuickCheck you need to have type information for the tests. For instance the classic specification / test of reverse is: prop_reverse xs xy = (reverse xs ++ reverse ys) == reverse (ys ++ xs) Somewhere you need to flag that xs and ys are lists of integers. In the case of my RangedSets I needed to run the tests with both Integers and Doubles. I also looked at using the Haskell parser in the libraries, but that doesn't capture comments. Associating a comment with a particular construct is not that simple either. If you can manage this then it would be great. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] AMQP framing layer: design help requested.
Dean Herington wrote: At 6:41 PM -0700 3/21/08, Adam Langley wrote: Also getter - fmap (amqpGetTable !) getWord8 getter is just fmap (amqpGetTable !) getWord8 I don't think so. Aren't there two gettings: the first to get the type byte and the second to get the item? Yes. I didn't use it because it seemed obfuscated, but in fact the point-free version is fmap (amqpGetTable !) getWord8 = id And I've also got an AmqpWire class similar to Dean's AmqpValue class. But both of these miss the point (which is why I didn't clutter up my simplified explanation with them). I'm looking for an alternative to the honking big AmqpVariant and AmqpArray types. I think I want something along the lines of: class (Binary v) = VariantClass v where typeCode :: v - Word8 fromVariant :: AmqpVariant - Maybe v newtype AmqpVariant = forall a . (VariantClass a) = Variant a newtype AmqpArray = forall a . (VariantClass a) = AmqpArray [a] But I can't see how to write fromVariant. I'm also unsure what the amqpGet and amqpPut methods might look like. Or maybe these two types are actually the best design. They do let you pattern-match on the contents. Extracting the contents of a variant from the design above would be something like: processVariant (Variant v) = case typeCode v of 0x01 - processWord8 $ fromJust $ fromVariant v 0x02 - ... and so on. Compare this with: processVariant (VariantWord8 v) = processWord8 v processVariant (VariantWord16 v) = processWord16 v ... and so on. What do you think? Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] AMQP framing layer: design help requested.
I'm trying to implement the AMQP framing layer. This is the bottom layer of the protocol that packs and unpacks data in lazy ByteStrings. I'm using the Binary package with its Get and Put monads to do the unpacking, and that works well. But I've run into a problem and I can't find an elegant solution. I'm wondering if someone can help. The following contains a simplified version of my current design. I've mapped the AMQP basic types to Haskell types. Sometimes this is a basic mapping, sometimes to something more complex. Strings have several AMQP representations, so I've created corresponding newtype declarations and instances. Some AMQP types can contain tagged types. For instance a map contains (key, tag, value) triples, where the tag is a single byte indicating the type of the value. I've defined the following type: data AmqpVariant = AmqpVarWord8 Word8 | AmqpVarWord16 Word16 | AmqpVarStr8 Str8 -- And so on for about 20 more types instance Binary AmqpVariant where put (AmqpVarWord8 v)= putWord8 0x01 putWord8 v put (AmqpVarWord16 v) = putWord8 0x02 putWord16be v put (AmqpVarStr8 v) = putWord8 0x03 put v -- And so on for about 20 more types get = do getter - fmap (amqpGetTable !) getWord8 getter amqpGetTable :: Array Word8 (Get AmqpVariant) amqpGetTable = array (0,255) [ (0x01, fmap AmqpVarWord8 getWord8), (0x02, fmap AmqpVarWord16 getWord16be), (0x03, fmap AmqpVarStr8 get), -- And so on for about 20 more types ] This is a Brute Force and Ignorance solution, but it will probably work. But now I've come up against another type, which AMQP calls an array. This has a single type tag at the start, followed by N items of that type. I'm wondering how to do this. One option would be to declare data AmqpArray = AmqpArrWord8 [Word8] | AmqpArrWord16 [Word16] -- and so on This effectively duplicates the AmqpVariant solution. It would work, but it feels horrible. I get the feeling that there ought to be a better way, possibly using classes or existential types. Any suggestions? Thanks, Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Doubting Haskell
Alan Carter wrote: I've written up some reflections on my newbie experience together with both versions, which might be helpful to people interested in popularizing Haskell, at: http://the-programmers-stone.com/2008/03/04/a-first-haskell-experience/ Thank you for writing this. On the lack of simple examples showing, for example, file IO: I seem to recall a Perl book (maybe it was Edition 1 of the Camel Book) which had lots of very short programs each illustrating one typical job. Also the Wiki does have some pages of worked example programs. But I agree, we could do better. I'm surprised you found the significant whitespace difficult. Yes, the formal rules are a bit arcane, but I just read them as does the Right Thing, and it generally works for me. I didn't know about the significance of comments, but then I've never written an outdented comment. I had a look through your code, and although I admit I haven't done the work, I'm sure that there would be ways of factoring out all the commonality and thereby reducing the length. Finally, thanks for that little story about the BBC B. I had one of those, and I always wondered about that heatsink, and the stonking big resistor next to it. They looked out of scale with the rest of the board. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Parody of Darcs patch theory from 1981
I was looking through my old copy of The Devil's DP Dictionary by Stan Kelly-Bootle, and came across the entry for Stepwise Refinement. I thought I've seen this before: this is a parody of Darcs patch theory. It included the Null patch, chains of patches, inverse patches, and pseudo-inverse patches. But the book was published in 1981. I've got the pages scanned, but I can't upload them to Wikimedia because they are still in copyright. However I'm quite sure that limited distribution would fall into fair use (non-commercial, small part of work, no impact on market, academic relevance). The total file size is about 520kBytes. Assuming people would like to see them, does anyone have any ideas beyond email to requestors? Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Parody of Darcs patch theory from 1981
Miguel Mitrofanov wrote: Does it start with Any sequence of KLUDGES, not necessarily distinct or finite...? If so, it can be found in The Computer Contradictionary, by the same author, and probably illegal copy of the last book can be found in the net somewhere. Indeed. In fact I'm not even sure its illegal. Its at http://www.scribd.com/doc/264064/The-Computer-Contradictionary page 202. The typography has been considerably munged (tildes replaced by hyphens mostly), but you can still get a good idea of what its saying. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Binary IEEE floating point format for AMQP
I'm working on an implementation of the framing layer for AMQP (www.amqp.org). I almost had 0.9 finished when I found they had released the spec for 0.10, so I have to redo quite a lot of work. Amongst the new features of 0.10 are wire formats for floating point. These are the 4 and 8 byte IEEE formats. * Is there a principled way of converting a Haskell Float or Double (or Rational, for that matter) to and from IEEE format? * Since many computers use IEEE format natively, is there a quicker way of doing this on those architectures? Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: [Haskell] *** JOB OFFER *** [...]
Peter Verswyvelen wrote: PS: This job offer was already placed in the Haskell Café a while ago, but I was advised there to place it in the main Haskell list. I hope this is not considered as spam. I certainly don't see it as spam. One day there will be a dozen jobs for Haskell programmers on Monster or Jobserve, and at that point another such announcement *would* be spam. But at the moment it has rarity value. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Enterprise Haskell AMQP library initial start and would like to pass it off to someone.
Berlin Brown wrote: I started a AMQP library; there really isn't a lot there but at least I was able to connect to the server. Arrgh: I was hoping I would be the first to announce this. I've been working on one (on and off) for a few months now. I've got most of the translation from XML protocol definition to Haskell, but it sounds like you are way ahead of me. I'll take a look at what you have done and see if my code can be of any use. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Enterprise Haskell AMQP library initial start and would like to pass it off to someone.
Don Stewart wrote: berlin.brown: I started a AMQP library; there really isn't a lot there but at least I was able to connect to the server. Here is the code and hopefully someone else can continue with the project. Thanks! Would you like this packaged up for hackage.haskell.org, so others can find and improve it? (or maybe move the repo to code.haskell.org? As I said in an earlier message to Haskell Cafe, I've been working on AMQP as well. Berlin's approach seems to have been to hand-code a minimum client and then expand from there, whereas I have been working on an automatic translation from the XML protocol spec to the framing layer of AMQP. The two efforts ought to be merged, although I haven't got the content message type implemented yet. I believe I have a Haskell.org account, although I'm not sure how to use darcs with it. Perhaps Don could advise me on the steps I would need to take to get my code into a repository on the server. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
The programming language market (was Re: [Haskell-cafe] Why functional programming matters
Evan Laforge wrote: Java's just wordy like that. In python you'd say max(foos, key=lambda x: x.update_time). While this is true, I was also thinking of the typical audience SPJ specified: senior technical people and managers. Most of these people have heard of Python and Ruby, but see them as scripting languages that are not suitable for Real Work. Most of the ones I have met seem to regard a static type system and compilation to native code as prerequisites for real programming languages (although Java has greatly weakened the second prejudice). More importantly, these people have not read Beating the Averages. They see the programming language market as a Keynsian Beauty Contest, in which the judges get rewarded for voting for the most popular candidate. Therefore the trick to winning the contest is not persuading the judges that you are the most beautiful, but that you are the one that most of the other judges are going to vote for. Paradoxically this is best done by emphasising your similarity with what they already know. The message is I'm just like her, only better. In the case of Haskell ways to do this would include: * Outline (single Powerpoint slide) a mapping between UML class diagrams and Haskell data and class types. Mention that Haskell classes and data types correspond roughly to Java interface and implementation classes respectively. * Emphasise that Haskell *is* statically type checked, its just that type inference means you don't have to declare the type of every single thing. Repeat this point three or four times during the talk to make sure it sticks. * Mention the covariance type hole in Java and say that Haskell doesn't have it. In Haskell static type system means what it says. * Hackage does what Doxygen and Javadoc do. The ones who know about automatic documentation will get a warm fuzzy feeling. The ones who don't will find it interesting. Also mention Hunit. Mention QuickCheck in passing, but don't dwell on it because its not what they know. * Mention that there is an Eclipse plug-in for Haskell. * Talk at length about the Haskell library and package mechanisms. Large projects often have multi-version configuration management issues, so talk about how library versions can be selected at compile time by a configuration file. * Talk about the FFI interface. Most of these people have big important monoliths of legacy code that they don't like to talk about in public. * Trying to dereference null is a significant source of bugs, so explain that null references are impossible in Haskell. If you have x :: Foo then x can never be null; it *has* to refer to a Foo object. If we want a possible null value then we say Maybe Foo to signal this, and type safety means you have to account for possible Nothing values. * Say computers are cheap but programmers are expensive whenever explaining a correctness or productivity feature. The best way to demonstrate the innate productivity improvement in Haskell is using numbers. Haskell projects to re-implement existing code routinely report 4-fold or better code reduction. The 1993 paper on Ada vs Awk vs C++ vs Haskell... is still good ammunition, as are the GetOpts implementations in C and Haskell. A lot of this is to demonstrate that the normal development infrastructure is actually available. This is another thing that these people expect to see in a real language. Its not that this is important for productivity, its just stuff you have to have to be considered a real language. Maybe I should write a Real Programming Languages Eat Lots of Quiche piece. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: The programming language market (was Re: [Haskell-cafe] Why functional programming matters
Tim Chevalier wrote: On 1/26/08, Paul Johnson [EMAIL PROTECTED] wrote: * Say computers are cheap but programmers are expensive whenever explaining a correctness or productivity feature. This is true only if talking to people in high-income nations. Even in low-income nations, its only false in the short term. If you have skilled programmers with computers and Internet connections then their wages inflate to the world norm. IIRC India is seeing 20%/year wage inflation for comp-sci graduates. And thats without the impact of H1-B and related programmes around the world. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why functional programming matters
Simon Peyton-Jones wrote: 1. Small examples of actual code. The goal here is (a) to convey a visceral idea of what functional programming *is*, rather than just assume the audience knows (they don't), and (b) to convey an idea of why it might be good. Here is one I came across in the last few days. I was reviewing some code in Java, and it contained a function that looked through a list of Foo instances for the latest update. I don't actually speak Java, but it went something like this: // Get the Foo that was most recently updated. Foo latestUpdate (Iterator Foo iterator) { long latestTimeSoFar = 0; Foo latestFooSoFar = Null; while (iterator.hasNext()) { item = iterator.getNext(); if (item.updateTime latestTimeSoFar) { latestTimeSoFar = item.updateTime; latestFooSoFar = item; } } return latestFooSoFar; } This takes an iterator over some collection of Foos and finds the one with the highest value of updateTime. 9 lines of code, or 12 with the closing curly brackets. In Haskell this is so short and obvious you probably wouldn't bother declaring it as a function, but if you did, here it is: -- Find the Foo that was most recently updated. latestUpdate :: [Foo] - Foo latestUpdate foos = maximumBy (comparing updateTime) foos Of course you could always write it in point-free format, but I think that would be over-egging things. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Hangman game
Ronald Guida wrote: Hi, I'm interested in learning how to program games. Since I have to start somewhere, I decided to write a simple Hangman game. I'm wondering if anyone can look at my code and give me some feedback. Nicely written. The design reads very much like a straight translation from the imperative style, which is why so much of it is in the IO monad. There is nothing wrong with this for a simple game like Hangman, but for larger games it doesn't scale. So here are a few pointers to ways of rewriting it to keep the IO to the top level and the actual work in a functional style: 1: Your GameState type can itself be made into a monad. Take a look at the All About Monads tutorial, especially the State monad. Think about the invariants in GameState; can you produce a new monad that guarantees these invariants through a limited set of actions. How do these actions correspond to user perceptions? 2: You can layer monads by using monad transformers. Extend the solution to part 1 by using StateT IO instead of just State. 3: Your current design uses a random number generator in the IO monad. Someone already suggested moving that into the GameState. But you can also generate an infinite list of random numbers. Can you make your game a function of a list of random numbers? 4: User input can also be considered as a list. Haskell has lazy input, meaning that you can treat user input as a list that actually only gets read as it is required. Can you make your game a function of the list of user inputs? How does this interact with the need to present output to the user? What about the random numbers? Good luck, Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] QuickCheck properties: export or not?
I was recently sent a patch for my Ranged Sets library which exported all the QuickCheck properties. I'd left them unexported on the grounds that they clutter up the documentation (although simplified versions are included in the documentation) and you can easily run them with the standard quickcheck script. The contributor, [EMAIL PROTECTED] suggested an explicit test harness instead. I'm not unduly bothered one way or the other, but I thought I'd ask the community: what is the best practice here? Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Problem with own written monad
Michael Roth wrote: Yes, I have done: push, pop, top, nop, count, clear, isolate and binop. All pretty easy, once I understand that Stack a b thing. Now you are ready to write your monad tutorial. This is a standard rite of passage (or should that be write a passage) for new Haskell programmers. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Problem with own written monad
Miguel Mitrofanov wrote: Yes. It's simply impossible. The Stack data type can't be turned into a monad. Why not? Surely this is just a variation on the theme of a state monad? Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Trying to fix space leak
Ben Challenor wrote: Hi I'm learning Haskell through writing a compiler. I'm seeing huge memory use in a function which converts the dataflow graph to the form required by Data.Graph. [...] I assume the allocation is being garbage-collected pretty quickly, because a) 6,616,297,296 bytes is stupid (!) and b) Process Explorer informs me that the peak private bytes of the program is not more than a couple of MB. Thats not a space leak. A space leak is when you find that all 6 GB of that allocation is being retained. You are correct that the GC is recovering this space as fast as it gets allocated. The profiler records how much memory is allocated from within various bits of your program to help you understand its performance and where optimisable hotspots are. I haven't looked at your code, but I imagine that you are traversing lazy data structures, which means that bits of the structure are consumed and deallocated as fast as they are created. The profiler also has options to help you understand what is being retained where. I'd advise against trying to make your program stricter because you might suddenly find yourself building an entire 6GB structure in memory before traversing it, which would not be a Good Thing. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Interesting data structure
Tim Docker wrote: I found it worthwhile to try and visualise what's going on here. Let's say I have 4 calculations that I want to run in parallel. The first doesn't need a request; the second needs to make a single request (A1); the third needs to make two requests where the second (B2) depends on the result of the first (B1), etc. The resulting parallel operations will be done in 3 batches, looking like: This sounds similar to futures, where a request for a parallel computation returns immediately, but the value returned is just a placeholder for the result, which will be filled in when it becomes available. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Functions are first class values in C
Cristian Baboi wrote: Let me show you an example to prove it. This reminds me of arguments in the late 80s and early 90s that C could do OO programming via function pointers, so there was no need for OO languages. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] #haskell works
Andrew Coppin wrote: Program with no particular optimisations: 0.35 seconds. Program with stream fusion [and GHC HEAD]: 0.25 seconds. Program with stream fusion and ByteString: 0.05 seconds. Surely you'd have to work pretty hard to get that kind of speed even in C. ;-) ...erm, actually no. Somebody sat down and wrote something in five minutes that takes 0.005 seconds. Oops! You may also be paying a fixed cost penalty in GHC run-time initialization. Try increasing N and see what happens. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe