From mhasan at cs.cornell.edu Sat Mar 1 01:50:55 2008 From: mhasan at cs.cornell.edu (Milos Hasan) Date: Sat Mar 1 01:48:36 2008 Subject: [Haskell-cafe] Generating a random list Message-ID: <47C8FCCF.1050209@cs.cornell.edu> Hi, so let's say I want to generate a list of N random floats. The elegant way of doing it would be to create an infinite lazy list of floats and take the first N, but for N = 1,000,000 or more, this overflows the stack. The reason is apparently that the take function is not tail-recursive, and so it uses O(N) stack space.. What is the right way to do this? Sure, I could write my own tail-recursive generator function. But this seems to be an instance of a more general problem - how to avoid algorithms linear in stack space when dealing with large lists. Thanks a lot! Milos From lrpalmer at gmail.com Sat Mar 1 02:18:57 2008 From: lrpalmer at gmail.com (Luke Palmer) Date: Sat Mar 1 02:16:38 2008 Subject: [Haskell-cafe] Generating a random list In-Reply-To: <47C8FCCF.1050209@cs.cornell.edu> References: <47C8FCCF.1050209@cs.cornell.edu> Message-ID: <7ca3f0160802292318j4c978820j824329ce67e013d9@mail.gmail.com> On Sat, Mar 1, 2008 at 6:50 AM, Milos Hasan wrote: > Hi, > > so let's say I want to generate a list of N random floats. The elegant > way of doing it would be to create an infinite lazy list of floats and > take the first N, but for N = 1,000,000 or more, this overflows the > stack. The reason is apparently that the take function is not > tail-recursive, and so it uses O(N) stack space.. Not too likely. take should not be tail recursive, because that is not lazy (you have to compute all n elements to get the first one) and thus uses O(n) space, whereas the take in the Prelude is lazy, so uses O(1) space. The prelude take is the one you want. It's likely that the stack overflow is occurring elsewhere in your program. For example, if you are adding together all the random numbers using foldl or foldr, that will eat up your stack (the right solution in that case is to use the strict foldl'). Perhaps you could post your code, or a minimal example of what you're experiencing. Luke > What is the right way to do this? Sure, I could write my own > tail-recursive generator function. But this seems to be an instance of a > more general problem - how to avoid algorithms linear in stack space > when dealing with large lists. > > Thanks a lot! > Milos > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From bos at serpentine.com Sat Mar 1 02:21:10 2008 From: bos at serpentine.com (Bryan O'Sullivan) Date: Sat Mar 1 02:18:55 2008 Subject: [Haskell-cafe] Generating a random list In-Reply-To: <47C8FCCF.1050209@cs.cornell.edu> References: <47C8FCCF.1050209@cs.cornell.edu> Message-ID: <47C903E6.7090204@serpentine.com> Milos Hasan wrote: > so let's say I want to generate a list of N random floats. The elegant > way of doing it would be to create an infinite lazy list of floats and > take the first N, but for N = 1,000,000 or more, this overflows the > stack. The reason is apparently that the take function is not > tail-recursive, and so it uses O(N) stack space.. You might want to post your code. The reason take isn't tail recursive is that it will be evaluated lazily, so it will not consume O(n) stack space. However, using take is the wrong approach anyway, as the user of the random numbers needs to return the unconsumed portion of the list so that the next user can consume them. This is why code that uses random numbers is usually written in the context of a state monad, such as MonadRandom: http://www.haskell.org/haskellwiki/New_monads/MonadRandom References: <47C8FCCF.1050209@cs.cornell.edu> <7ca3f0160802292318j4c978820j824329ce67e013d9@mail.gmail.com> Message-ID: <47C9116F.8060707@cs.cornell.edu> Hi, thanks for the reply.. >> Hi, >> >> so let's say I want to generate a list of N random floats. The elegant >> way of doing it would be to create an infinite lazy list of floats and >> take the first N, but for N = 1,000,000 or more, this overflows the >> stack. The reason is apparently that the take function is not >> tail-recursive, and so it uses O(N) stack space.. >> > > Not too likely. take should not be tail recursive, because that is > not lazy (you have to compute all n elements to get the first one) and > thus uses O(n) space, whereas the take in the Prelude is lazy, so uses > O(1) space. The prelude take is the one you want. > > It's likely that the stack overflow is occurring elsewhere in your > program. For example, if you are adding together all the random > numbers using foldl or foldr, that will eat up your stack (the right > solution in that case is to use the strict foldl'). Perhaps you could > post your code, or a minimal example of what you're experiencing Summing the list works fine, it uses both O(1) stack space and O(1) heap space (so the laziness of foldl is not the problem here). The problem is that I'm not just trying to sum the list, nor any similar producer-consumer scenario that could be done in O(1) heap space. What I was really trying to do is create a nearest-neighbor search tree with a large number of random points. So I really need the list to physically materialize in memory, and I don't mind it taking O(N) heap space. The problem I was trying to avoid was using O(N) *stack* space in the process of creating the list. Here's a minimal summing example that illustrates the difference. The following works fine, since the elements are generated lazily and summed on the fly, as expected: randFloats :: [Float] randFloats = randoms (mkStdGen 0) main = do let xs = take 1000000 randFloats print $ sum xs But this overflows, because the list is created before being summed, and the take function goes into awfully deep recursion: randFloats :: [Float] randFloats = randoms (mkStdGen 0) main = do xs <- return $ take 1000000 randFloats print $ sum xs Is there a clean way to avoid this problem? Thanks, Milos From mhasan at cs.cornell.edu Sat Mar 1 03:31:51 2008 From: mhasan at cs.cornell.edu (Milos Hasan) Date: Sat Mar 1 03:29:33 2008 Subject: [Haskell-cafe] Generating a random list In-Reply-To: <47C903E6.7090204@serpentine.com> References: <47C8FCCF.1050209@cs.cornell.edu> <47C903E6.7090204@serpentine.com> Message-ID: <47C91477.8080708@cs.cornell.edu> Bryan O'Sullivan wrote: > Milos Hasan wrote: > > >> so let's say I want to generate a list of N random floats. The elegant >> way of doing it would be to create an infinite lazy list of floats and >> take the first N, but for N = 1,000,000 or more, this overflows the >> stack. The reason is apparently that the take function is not >> tail-recursive, and so it uses O(N) stack space.. >> > > You might want to post your code. The reason take isn't tail recursive > is that it will be evaluated lazily, so it will not consume O(n) stack > space. > > Yup, see the code I sent to Luke Palmer. The problem is that I really need the whole list to do further processing on it, instead of just consuming the elements one-by-one as they are produced by the random generator. I'm trying to build a search tree, but for simplicity you might assume that I just need to sort the list (or any other operation that is not a simple fold). > However, using take is the wrong approach anyway, as the user of the > random numbers needs to return the unconsumed portion of the list so > that the next user can consume them. This is why code that uses random > numbers is usually written in the context of a state monad, such as > MonadRandom: http://www.haskell.org/haskellwiki/New_monads/MonadRandom > That sounds interesting, but I'm not sure it's the randomness that's the problem here. I could as well have a completely deterministic function f :: Int -> Float, and I could try to produce the list "map f [1..1000000]", hitting the same issue. Cheers, Milos From mhasan at cs.cornell.edu Sat Mar 1 04:04:05 2008 From: mhasan at cs.cornell.edu (Milos Hasan) Date: Sat Mar 1 04:01:47 2008 Subject: [Haskell-cafe] Generating a random list In-Reply-To: <47C903E6.7090204@serpentine.com> References: <47C8FCCF.1050209@cs.cornell.edu> <47C903E6.7090204@serpentine.com> Message-ID: <47C91C05.90608@cs.cornell.edu> So, I did one more experiment, and the following overflows too: import System.Random import Data.List randFloats :: [Float] randFloats = randoms (mkStdGen 0) main = print $ sum $ sort $ take 1000000 randFloats Could it be that Data.List.sort is the culprit that uses O(n) stack space here? If so, is this avoidable? Thanks a lot, Milos From kalman.noel at bluebottle.com Sat Mar 1 05:52:46 2008 From: kalman.noel at bluebottle.com (Kalman Noel) Date: Sat Mar 1 05:50:06 2008 Subject: [Haskell-cafe] Generating a random list In-Reply-To: <47C9116F.8060707@cs.cornell.edu> References: <47C8FCCF.1050209@cs.cornell.edu> <7ca3f0160802292318j4c978820j824329ce67e013d9@mail.gmail.com> <47C9116F.8060707@cs.cornell.edu> Message-ID: <200803011052.m21AqOxt030491@mi0.bluebottle.com> Milos Hasan wrote: > Here's a minimal summing example that illustrates the difference. The > following works fine, since the elements are generated lazily and summed > on the fly, as expected: > > randFloats :: [Float] > randFloats = randoms (mkStdGen 0) > > main = do > let xs = take 1000000 randFloats > print $ sum xs > > But this overflows, because the list is created before being summed, and > the take function goes into awfully deep recursion: > > randFloats :: [Float] > randFloats = randoms (mkStdGen 0) > > main = do > xs <- return $ take 1000000 randFloats > print $ sum xs > > Is there a clean way to avoid this problem? There is, and it has already been mentioned: It's the behaviour of Prelude.sum that is bugging you. ?sum? will build an expression like this, which is responsible for the stack overflow: ((((...(n1 + n2) + n3) + n4) + ...) + nm) ^ evaluation will start here ^ But this is the first addition to be performed Instead, just use sum', which is defined just like sum, but with a strict left fold instead of a lazy left fold: import Data.List sum' :: (Num a) => [a] -> a sum' = foldl' (+) 0 I don't know exactly why there is a difference between both programs. I suppose that in the first one, the strictness analyzer can optimize sum into sum', but in the second one it cannot. Kalman ---------------------------------------------------------------------- Get a free email address with REAL anti-spam protection. http://www.bluebottle.com/tag/1 From lrpalmer at gmail.com Sat Mar 1 11:15:03 2008 From: lrpalmer at gmail.com (Luke Palmer) Date: Sat Mar 1 11:12:43 2008 Subject: [Haskell-cafe] Generating a random list In-Reply-To: <47C9116F.8060707@cs.cornell.edu> References: <47C8FCCF.1050209@cs.cornell.edu> <7ca3f0160802292318j4c978820j824329ce67e013d9@mail.gmail.com> <47C9116F.8060707@cs.cornell.edu> Message-ID: <7ca3f0160803010815u12187549xf712bcaea6b0d02d@mail.gmail.com> On Sat, Mar 1, 2008 at 8:18 AM, Milos Hasan wrote: > Here's a minimal summing example that illustrates the difference. The > following works fine, since the elements are generated lazily and summed > on the fly, as expected: > > randFloats :: [Float] > randFloats = randoms (mkStdGen 0) > > main = do > let xs = take 1000000 randFloats > print $ sum xs > > But this overflows, because the list is created before being summed, and > the take function goes into awfully deep recursion: > > randFloats :: [Float] > randFloats = randoms (mkStdGen 0) > > main = do > xs <- return $ take 1000000 randFloats > print $ sum xs It is definitely the strictness analyzer biting you here. In ghci, the behavior of these two programs is identical (stack overflow). As kalman said, if you replate sum with foldl' (+) 0 in each of these programs, the behavior is still identical (correct). As a side note, one of the monad laws is this: return x >>= f = f x So your two programs are semantically equivalent (there's nothing about IO that forces the evaluation of the list). If you're building some sort of tree out of these values, you're going to want to make sure that whatever fold you do (be it using foldl' or recursion) is strict, so that you don't get a huge thunk that doesn't have any information. Luke From apfelmus at quantentunnel.de Sat Mar 1 11:45:43 2008 From: apfelmus at quantentunnel.de (apfelmus) Date: Sat Mar 1 11:43:29 2008 Subject: [Haskell-cafe] Re: Generating a random list In-Reply-To: <47C91C05.90608@cs.cornell.edu> References: <47C8FCCF.1050209@cs.cornell.edu> <47C903E6.7090204@serpentine.com> <47C91C05.90608@cs.cornell.edu> Message-ID: Milos Hasan wrote: > import System.Random > import Data.List > > randFloats :: [Float] > randFloats = randoms (mkStdGen 0) > > main = print $ sum $ sort $ take 1000000 randFloats > > Could it be that Data.List.sort is the culprit that uses O(n) stack > space here? If so, is this avoidable? sum is not tail-recursive. Sometimes, GHCs strictness analyzer is able to optimize that away. Regards, apfelmus From martine at danga.com Sat Mar 1 13:39:37 2008 From: martine at danga.com (Evan Martin) Date: Sat Mar 1 13:37:19 2008 Subject: [Haskell-cafe] runInteractiveCommand dying uncatchably? Message-ID: <3a6f89fc0803011039s239c1426y770d1a947fc4e991@mail.gmail.com> If I run the following program, it never prints "done". If I uncomment the commented line, it does. import Prelude hiding (catch) import Control.Exception import System.Process import System.IO demo = do putStrLn "starting" (inp,out,err,pid) <- runInteractiveCommand "nonesuchcommand" putStrLn "writing to in on bad command" hPutStr inp "whatever" -- putStr "flushing" hFlush inp `catch` \e -> do print e; return () putStrLn "done" main = demo `catch` \e -> do print e; return () On my machine the output is: $ runhaskell test.hs starting writing to in on bad command $ It appears to exit at the hFlush call. (hClose has the same behavior.) I find this surprising -- I'd expect, even if I'm using an API incorrectly, to get an exception. From trebla at vex.net Sat Mar 1 16:43:38 2008 From: trebla at vex.net (Albert Y. C. Lai) Date: Sat Mar 1 16:41:21 2008 Subject: [Haskell-cafe] Generating a random list In-Reply-To: <47C91C05.90608@cs.cornell.edu> References: <47C8FCCF.1050209@cs.cornell.edu> <47C903E6.7090204@serpentine.com> <47C91C05.90608@cs.cornell.edu> Message-ID: <47C9CE0A.4010600@vex.net> The following is in ghci 6.8.2 with default options (e.g., default heap and stack). "G>" denotes the ghci prompt. At some points ghci will use 500MB of memory. Be sure you have enough physical memory. G> :m + Data.List System.Random G> let f n = take n randoms (mkStdGen 0)) :: [Float] I define f to take a parameter so that thunks are created fresh every time I use it. G> sum (f 1000000) *** Exception: stack overflow This overflow is known, and its solution too: G> foldl' (+) 0 (f 1000000) 499985.38 The more interesting part is when we also sort: G> foldl' (+) 0 (sort (f 1000000)) *** Exception: stack overflow At this point everyone hastens to assign blames according to his/her mental model. But some mental models are more mistaken than others. When a mental model is shown to be mistaken by another example, we have a name for the feeling that ensues: "my brain has exploded". And here is an example that likely causes your brain to explode (it also causes ghci to use 500MB of memory): G> foldl' (+) 0 (sort (reverse (f 1000000))) 499992.0 (Don't worry about the different sum. We all know that re-ordering floating point numbers changes the sum.) Some brains haven't exploded yet. They believe that reverse helps by forcing all 1000000 cons cells before sorting. To burst them, let's reverse twice: G> foldl' (+) 0 (sort (reverse (reverse (f 1000000)))) *** Exception: stack overflow You can also reverse 3 times, 4 times... In general, even number of times overflows, odd number of times works. It is now clear that order before sorting matters. But why should it? I now give some hints and step down. I invite you to contemplate and discuss further. * Suppose f 6 is [a,b,c,d,e,f]. What is the size of thunk f? Compare to the size of thunk a, b, etc. Also note how much is shared among them. If you want, the source code of System.Random is at http://www.haskell.org/ghc/docs/latest/html/libraries/random/src/System-Random.html If that is too complicated, a simpler model is available at http://haskell.org/onlinereport/random.html For our present purpose, the simpler model is accurate enough. * Based on that knowledge, you're in a similar situation as http://www.haskell.org/haskellwiki/Stack_overflow#Scans Thus for example "last (f 1000000)" overflows, while "print (f 1000000)" works just fine (if you have the patience). * Debug.Trace.trace is great for verifying relative order of evaluation. If I construct this list [trace "0" a, trace "1" b, trace "2" c, ...] and pass it to sort, I can see which item is forced in what order when sort compares items. This command does: G> :m + Debug.Trace G> sort (zipWith (trace . show) [0..] (f 6)) What do you see? What do you think? Bump up the number 6 to 10, 20... to verify what you guess. * If you are interested in finding out in detail why sort does that, the source code is at http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-List.html Note the code of "merge": merge cmp xs [] = xs merge cmp [] ys = ys merge cmp (x:xs) (y:ys) = ... Suppose you re-order the first two lines, i.e., make it merge cmp [] ys = ys merge cmp xs [] = xs merge cmp (x:xs) (y:ys) = ... what will happen? * Prove that the sorting algorithm is only responsible for O(n log n) time and O(log n) stack. Thus any extra stack pressure must come from thunks in the list items. From mhasan at cs.cornell.edu Sat Mar 1 16:53:52 2008 From: mhasan at cs.cornell.edu (Milos Hasan) Date: Sat Mar 1 16:51:34 2008 Subject: [Haskell-cafe] Generating a random list In-Reply-To: <7ca3f0160803010815u12187549xf712bcaea6b0d02d@mail.gmail.com> References: <47C8FCCF.1050209@cs.cornell.edu> <7ca3f0160802292318j4c978820j824329ce67e013d9@mail.gmail.com> <47C9116F.8060707@cs.cornell.edu> <7ca3f0160803010815u12187549xf712bcaea6b0d02d@mail.gmail.com> Message-ID: <47C9D070.6010708@cs.cornell.edu> > It is definitely the strictness analyzer biting you here. In ghci, > the behavior of these two programs is identical (stack overflow). As > kalman said, if you replate sum with foldl' (+) 0 in each of these > programs, the behavior is still identical (correct). > > OK, I could replicate that result. Awesome, thanks a lot! > As a side note, one of the monad laws is this: > > return x >>= f = f x > > So your two programs are semantically equivalent (there's nothing > about IO that forces the evaluation of the list). > > OK, thanks, this is an important point. So maybe I should have done this? main = print $ foldl1' (+) $! take 1000000 randFloats My intuition tells me that the $! (and `seq`) just reduces one level (to WHNF?). If so, is there a way to force complete evaluation (so that nothing is reducible anymore)? Thanks, Milos From vigalchin at gmail.com Sat Mar 1 17:25:40 2008 From: vigalchin at gmail.com (Galchin Vasili) Date: Sat Mar 1 17:23:20 2008 Subject: [Haskell-cafe] .cabal problem Message-ID: <5ae4f2ba0803011425ybc4bbeatae9501116a8d1169@mail.gmail.com> Hello, I am trying to install a package on my Linux Ubuntu machine. It chokes build-depends: base, directory because directory dependency is unresolvable. Do I have to specify "extra-libs" so that correct library space is searched? Actually I tried this and it didn't help. ?? Regards, Vasya -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080301/e24e5eaf/attachment.htm From tgdavies at gmail.com Sat Mar 1 18:41:51 2008 From: tgdavies at gmail.com (Tom Davies) Date: Sat Mar 1 18:39:46 2008 Subject: [Haskell-cafe] STAMP benchmark in Haskell? Message-ID: I'm experimenting with STM (in CAL[1] rather than Haskell) and want to run the STAMP[2] benchmarks. Is there a Haskell translation available, or can anyone suggest a better/different benchmark suite for STM? Thanks, Tom [1] http://openquark.org/Open_Quark/Welcome.html [2] http://stamp.stanford.edu/ From gtener at gmail.com Sat Mar 1 19:21:42 2008 From: gtener at gmail.com (=?ISO-8859-2?Q?Krzysztof_Skrz=EAtnicki?=) Date: Sat Mar 1 19:19:22 2008 Subject: [Haskell-cafe] coerce (safe!) Message-ID: <220e47b40803011621u2a87ddc3t5cdb162b3d543b42@mail.gmail.com> Well, it is simply > coerce :: a -> b > coerce _ = undefined so coerce is simply empty function. But still, it is possible to write a function of type (a->b). Well, possibly I didn't write anything particularly new, but please excuse me for I'm still in sort of a shock after I've discovered it. Yet this function reminds me how little I know so I have a question for you. I didn't took any lectures in Category Theory (for I'm still just a student, and I won't for there are none in my institute), but are there any good (e)books you would recommend for a (future) computer scientist? Regards Christopher Skrz?tnicki -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080302/2c68a5b8/attachment.htm From allbery at ece.cmu.edu Sat Mar 1 19:25:35 2008 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Sat Mar 1 19:23:16 2008 Subject: [Haskell-cafe] runInteractiveCommand dying uncatchably? In-Reply-To: <3a6f89fc0803011039s239c1426y770d1a947fc4e991@mail.gmail.com> References: <3a6f89fc0803011039s239c1426y770d1a947fc4e991@mail.gmail.com> Message-ID: <9DEB257F-1B39-4082-8AEF-E2CFDB2B6E1D@ece.cmu.edu> On Mar 1, 2008, at 13:39 , Evan Martin wrote: > If I run the following program, it never prints "done". If I > uncomment the commented line, it does. The exception it's getting is a UNIX signal (SIGPIPE), whose default action if not caught is to silently kill the process. Establish a signal handler for sigPIPE, or ignore it (which will silently convert it to an error EPIPE which will raise a normal I/O exception). -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH From nominolo at googlemail.com Sat Mar 1 19:58:21 2008 From: nominolo at googlemail.com (Thomas Schilling) Date: Sat Mar 1 19:56:05 2008 Subject: [Haskell-cafe] coerce (safe!) In-Reply-To: <220e47b40803011621u2a87ddc3t5cdb162b3d543b42@mail.gmail.com> References: <220e47b40803011621u2a87ddc3t5cdb162b3d543b42@mail.gmail.com> Message-ID: <71E4E973-7F64-4CF3-B06A-9C319E6BD132@googlemail.com> On 2 mar 2008, at 01.21, Krzysztof Skrz?tnicki wrote: > Well, it is simply > > > coerce :: a -> b > > coerce _ = undefined > > so coerce is simply empty function. But still, it is possible to > write a function of type (a->b). > Well, possibly I didn't write anything particularly new, but please > excuse me for I'm still in > sort of a shock after I've discovered it. > > Yet this function reminds me how little I know so I have a question > for you. > I didn't took any lectures in Category Theory (for I'm still just a > student, and I won't for there are none in my institute), > but are there any good (e)books you would recommend for a (future) > computer scientist? For your particular problem you might want to start with this thread (and the linked paper): http://lambda-the-ultimate.org/node/2003 From agl at imperialviolet.org Sat Mar 1 21:02:04 2008 From: agl at imperialviolet.org (Adam Langley) Date: Sat Mar 1 20:59:44 2008 Subject: [Haskell-cafe] .cabal problem In-Reply-To: <5ae4f2ba0803011425ybc4bbeatae9501116a8d1169@mail.gmail.com> References: <5ae4f2ba0803011425ybc4bbeatae9501116a8d1169@mail.gmail.com> Message-ID: <396556a20803011802o5eed8aack8131205c28a17f9@mail.gmail.com> 2008/3/1 Galchin Vasili : > I am trying to install a package on my Linux Ubuntu machine. It chokes > build-depends: base, directory because directory dependency is > unresolvable. Do I have to specify "extra-libs" so that correct library > space is searched? Actually I tried this and it didn't help. ?? So, here's[1] the package "directory", however it ships with GHC, so you very probably already have it installed. Try `ghc-pkg describe directory` to check. Also, run `ghc --version` to see what version of GHC you are running. If it's < 6.8, you may have problems because the directory package didn't exist before then, I believe the same modules were in the base package. In that case, the easy solution is probably to upgrade GHC. [1] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/directory-1.0.0.0 AGL -- Adam Langley agl@imperialviolet.org http://www.imperialviolet.org From chaddai.fouche at gmail.com Sat Mar 1 21:48:00 2008 From: chaddai.fouche at gmail.com (=?ISO-8859-1?Q?Chadda=EF_Fouch=E9?=) Date: Sat Mar 1 21:45:42 2008 Subject: [Haskell-cafe] Generating a random list In-Reply-To: <47C9D070.6010708@cs.cornell.edu> References: <47C8FCCF.1050209@cs.cornell.edu> <7ca3f0160802292318j4c978820j824329ce67e013d9@mail.gmail.com> <47C9116F.8060707@cs.cornell.edu> <7ca3f0160803010815u12187549xf712bcaea6b0d02d@mail.gmail.com> <47C9D070.6010708@cs.cornell.edu> Message-ID: 2008/3/1, Milos Hasan : > OK, thanks, this is an important point. So maybe I should have done this? > > main = print $ foldl1' (+) $! take 1000000 randFloats > > My intuition tells me that the $! (and `seq`) just reduces one level (to > WHNF?). If so, is there a way to force complete evaluation (so that > nothing is reducible anymore)? In fact with this code you won't have any problem since the foldl1' will consume strictly the elements as soon as take produce them, avoiding any accumulation of thunk by randoms. Now if you were to put a sort in there (supposedly to do something else than a simple sum...), you could have a need for a function that reduce the list and its elements : > forceList [] = () > forceList (x:xs) = x `seq` forceList xs > > main = print $ foldl1' (+) $ (\xs -> forceList xs `seq` sort xs) $ take 1000000 randFloats In Ghci it don't work (probably because the tail call in forceList isn't optimised) but compiled it will work fine. -- Jeda? From mhasan at cs.cornell.edu Sat Mar 1 23:06:51 2008 From: mhasan at cs.cornell.edu (Milos Hasan) Date: Sat Mar 1 23:04:34 2008 Subject: [Haskell-cafe] Re: Generating a random list Message-ID: <47CA27DB.4020208@cs.cornell.edu> OK, you convinced me that sort is not the problem. After all, "last (f 1000000)" overflows too, and last is a very innocent function. I don't know how you found the size (or structure) of the thunks (I'm not aware of a ghci functionality that can tell me that), could you let me know? Anyway, the problem seems to be that the values pulled from the list are not final float values, but instead they're thunks that grow larger and larger as more floats are pulled from the list. That's why last and sort don't work, but print and foldl' do work. Also, an odd number of reverses helps since sort evaluates the elements from the end of the list first. So I forced those values, and it fixed the problem: -- this function returns n random floats (no thunks) f :: Int -> [Float] f n = take n $ randFloats $ mkStdGen 0 where randFloats g = x `seq` x : randFloats g' where (x, g') = random g main = print $ foldl1' (+) $ sort $ f 1000000 This works without overflow, and so does "last (f 1000000)". Would it make sense for System.Random to do this forcing by default, too? Thanks, Milos From vigalchin at gmail.com Sun Mar 2 00:02:43 2008 From: vigalchin at gmail.com (Galchin Vasili) Date: Sun Mar 2 00:00:33 2008 Subject: [Haskell-cafe] .cabal problem In-Reply-To: <396556a20803011802o5eed8aack8131205c28a17f9@mail.gmail.com> References: <5ae4f2ba0803011425ybc4bbeatae9501116a8d1169@mail.gmail.com> <396556a20803011802o5eed8aack8131205c28a17f9@mail.gmail.com> Message-ID: <5ae4f2ba0803012102x54a20400v14b6c8a25cfccc75@mail.gmail.com> exactly .. I have version 6.6.1 ... question is how do I get the Unbuntu package for version 6.8? V. On Sat, Mar 1, 2008 at 8:02 PM, Adam Langley wrote: > 2008/3/1 Galchin Vasili : > > I am trying to install a package on my Linux Ubuntu machine. It > chokes > > build-depends: base, directory because directory dependency is > > unresolvable. Do I have to specify "extra-libs" so that correct library > > space is searched? Actually I tried this and it didn't help. ?? > > So, here's[1] the package "directory", however it ships with GHC, so > you very probably already have it installed. Try `ghc-pkg describe > directory` to check. Also, run `ghc --version` to see what version of > GHC you are running. If it's < 6.8, you may have problems because the > directory package didn't exist before then, I believe the same modules > were in the base package. In that case, the easy solution is probably > to upgrade GHC. > > > [1] > http://hackage.haskell.org/cgi-bin/hackage-scripts/package/directory-1.0.0.0 > > > AGL > > -- > Adam Langley agl@imperialviolet.org http://www.imperialviolet.org > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080301/e6401862/attachment.htm From aaltman at pdx.edu Sun Mar 2 02:16:53 2008 From: aaltman at pdx.edu (Aaron Altman) Date: Sun Mar 2 02:14:30 2008 Subject: [Haskell-cafe] "Wrong kind" when attempting to build a monad for a circular list of functions In-Reply-To: References: <47C66283.7000509@pdx.edu> Message-ID: <47CA5465.2040300@pdx.edu> A big thanks to you all for the discussion. I have determined that a monad is actually not the best representation of a circular list of functions. I was able to implement it without any special syntax or unusual typing. For the curious: -------------------------------------------------- funcList :: [Int -> Int] funcList = [\_ -> 1, \_ -> 2, \_ -> 3] iterateCircularFL :: [a -> b] -> (a -> b, [a -> b]) iterateCircularFL (x:xs) = (x, concat [xs, [x]]) applyCircularFL :: a -> [a -> b] -> (b, [a -> b]) applyCircularFL arg fList = let (currentFunc, iteratedList) = iterateCircularFL fList in (currentFunc arg, iteratedList) testTraversal i l | i == 0 = putStr "Done." | i > 0 = do { putStr "Execution "; putStr (show i); putStr " returned "; putStr (show val); putStr ".\n"; testTraversal (i - 1) newList } where (val, newList) = applyCircularFL i l main = do testTraversal 5 funcList From roma at ro-che.info Sun Mar 2 03:49:37 2008 From: roma at ro-che.info (Roman Cheplyaka) Date: Sun Mar 2 03:47:22 2008 Subject: [Haskell-cafe] coerce (safe!) In-Reply-To: <220e47b40803011621u2a87ddc3t5cdb162b3d543b42@mail.gmail.com> References: <220e47b40803011621u2a87ddc3t5cdb162b3d543b42@mail.gmail.com> Message-ID: <20080302084937.GA4045@home.ro-che.info> * Krzysztof Skrz?tnicki [2008-03-02 01:21:42+0100] > Well, it is simply > > > coerce :: a -> b > > coerce _ = undefined > > so coerce is simply empty function. But still, it is possible to write a > function of type (a->b). > Well, possibly I didn't write anything particularly new, but please excuse > me for I'm still in > sort of a shock after I've discovered it. Also there's nice possibility of defining Maybe a without ADT. type Maybe a = (a, Bool) just x = (x, True) nothing = (undefined, False) -- Roman I. Cheplyaka :: http://ro-che.info/ ...being in love is totally punk rock... -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 307 bytes Desc: Digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20080302/b1901cd9/attachment.bin From jon.fairbairn at cl.cam.ac.uk Sun Mar 2 04:19:35 2008 From: jon.fairbairn at cl.cam.ac.uk (Jon Fairbairn) Date: Sun Mar 2 04:17:21 2008 Subject: [Haskell-cafe] Re: coerce (safe!) References: <220e47b40803011621u2a87ddc3t5cdb162b3d543b42@mail.gmail.com> Message-ID: "Krzysztof Skrz?tnicki" writes: > Well, it is simply > >> coerce :: a -> b >> coerce _ = undefined > > so coerce is simply empty function. But still, it is possible to write a > function of type (a->b). > Well, possibly I didn't write anything particularly new, but please excuse > me for I'm still in > sort of a shock after I've discovered it. You have to remember that types in Haskell all have undefined as a member (this is an inevitable consequence of allowing arbitrary recursion). So your coerce is returning something that is in the type claimed by the result, so there's nothing shocking about it! -- J?n Fairbairn Jon.Fairbairn@cl.cam.ac.uk From vandijk.roel at gmail.com Sun Mar 2 08:21:29 2008 From: vandijk.roel at gmail.com (Roel van Dijk) Date: Sun Mar 2 08:19:06 2008 Subject: [Haskell-cafe] "Wrong kind" when attempting to build a monad for a circular list of functions In-Reply-To: <47CA5465.2040300@pdx.edu> References: <47C66283.7000509@pdx.edu> <47CA5465.2040300@pdx.edu> Message-ID: Looks good! A few tips: > funcList :: [Int -> Int] > funcList = [\_ -> 1, \_ -> 2, \_ -> 3] funcList = [const 1, const 2, const 3] > > iterateCircularFL :: [a -> b] -> (a -> b, [a -> b]) > iterateCircularFL (x:xs) = (x, concat [xs, [x]]) {- If you use cycle in main then you do not need this function at all. -} > applyCircularFL :: a -> [a -> b] -> (b, [a -> b]) > applyCircularFL arg fList = > let > (currentFunc, iteratedList) = iterateCircularFL fList > in (currentFunc arg, iteratedList) {- If the list of functions is infinite then we do not have to worry about exhausting it, although an empty list will still cause a pattern match failure. -} applyCircularFL :: a -> [a -> b] -> (b, [a -> b]) applyCircularFL arg (f:fs) = (f arg, fs) >testTraversal i l > | i == 0 = putStr "Done." > | i > 0 = do { > putStr "Execution "; > putStr (show i); > putStr " returned "; > putStr (show val); > putStr ".\n"; > testTraversal (i - 1) newList > } > where (val, newList) = applyCircularFL i l {- Transform funcList into an infinite list to simplify things -} main = testTraversal 5 $ cycle funcList I hope these tips are usefull :-) Roel From paul at cogito.org.uk Sun Mar 2 11:53:09 2008 From: paul at cogito.org.uk (Paul Johnson) Date: Sun Mar 2 11:50:57 2008 Subject: [Haskell-cafe] Parody of Darcs patch theory from 1981 Message-ID: <47CADB75.1040707@cogito.org.uk> 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. From miguelimo38 at yandex.ru Sun Mar 2 12:09:40 2008 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Sun Mar 2 12:07:24 2008 Subject: [Haskell-cafe] Parody of Darcs patch theory from 1981 In-Reply-To: <47CADB75.1040707@cogito.org.uk> References: <47CADB75.1040707@cogito.org.uk> Message-ID: <9C02143A-2D54-4130-8063-5B0C62326CD1@yandex.ru> 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. On 2 Mar 2008, at 19:53, Paul Johnson wrote: > 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 From apfelmus at quantentunnel.de Sun Mar 2 12:17:09 2008 From: apfelmus at quantentunnel.de (apfelmus) Date: Sun Mar 2 12:15:03 2008 Subject: [Haskell-cafe] Re: Generating a random list In-Reply-To: <47C9CE0A.4010600@vex.net> References: <47C8FCCF.1050209@cs.cornell.edu> <47C903E6.7090204@serpentine.com> <47C91C05.90608@cs.cornell.edu> <47C9CE0A.4010600@vex.net> Message-ID: Albert Y. C. Lai wrote: > Note the code of "merge": > > merge cmp xs [] = xs > merge cmp [] ys = ys > merge cmp (x:xs) (y:ys) = ... > > Suppose you re-order the first two lines, i.e., make it > > merge cmp [] ys = ys > merge cmp xs [] = xs > merge cmp (x:xs) (y:ys) = ... > > what will happen? Oh, so the mergesort in the library doesn't behave as nicely as I'd have expected. I'd consider the first definition a strictness bug; the general etiquette is to force arguments from left to right. Regards, apfelmus From catamorphism at gmail.com Sun Mar 2 12:26:55 2008 From: catamorphism at gmail.com (Tim Chevalier) Date: Sun Mar 2 12:24:39 2008 Subject: [Haskell-cafe] Parody of Darcs patch theory from 1981 In-Reply-To: <47CADB75.1040707@cogito.org.uk> References: <47CADB75.1040707@cogito.org.uk> Message-ID: <4683d9370803020926g1ceac551v3d8c398ad645943@mail.gmail.com> On 3/2/08, Paul Johnson wrote: > 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"? I would be entertained, but perhaps this might be more on-topic on the darcs-users mailing list (and interested parties might be more likely to see it there, since not everyone can keep up with haskell-cafe) :-) Cheers, Tim -- Tim Chevalier * http://cs.pdx.edu/~tjc * Often in error, never in doubt "Imagine if every Thursday your shoes exploded if you tied them the usual way. This happens to us all the time with computers, and nobody thinks of complaining." -- Jeff Raskin From newsham at lava.net Sun Mar 2 14:12:34 2008 From: newsham at lava.net (Tim Newsham) Date: Sun Mar 2 14:10:13 2008 Subject: [Haskell-cafe] A mini haskell (in 244 lines of python) Message-ID: For education and fun I wrote a small untyped non-strict lambda calculus evaluator in python. One of the goals was to keep it fairly small and simple, and to do most of the work in the implemented scripting language itself. For that reason, I added macros to allow things like "let" and "letrec" to be defined as syntactic sugar easily outside of the evaluation engine itself. The result is 244 lines of python, a small prelude that implements tuples, lists and the state monad, and some small example scripts. The prelude and scripts are heavily influenced by Haskell, the main differences being a much simpler syntax, lack of pattern matching and lack of a type system. Data structures aren't supported but are implemented fairly easily using lambda expressions as described in http://www.cs.nott.ac.uk/~nhn/TFP2006/Papers/03-JansenKoopmanPlasmeijer-EfficientInterpretation.pdf This is all available at http://www.thenewsh.com/%7Enewsham/lambda/ as extracted package and .tgz. The README file has documentation including small examples. Accompanying scripts provide more complete examples, such as: [WITHLIST [LET from2 (iter (add 1) 2) [LET primes (nubBy (\x \y (eq (mod y x) 0)) from2) (traceList Val (take 10 primes)) ]]] which calculates the first 10 primes. Exercise to the reader: I bet the evaluator could all be written much more compactly in Haskell. Tim Newsham http://www.thenewsh.com/~newsham/ From paul at cogito.org.uk Sun Mar 2 14:32:40 2008 From: paul at cogito.org.uk (Paul Johnson) Date: Sun Mar 2 14:30:20 2008 Subject: [Haskell-cafe] Parody of Darcs patch theory from 1981 In-Reply-To: <9C02143A-2D54-4130-8063-5B0C62326CD1@yandex.ru> References: <47CADB75.1040707@cogito.org.uk> <9C02143A-2D54-4130-8063-5B0C62326CD1@yandex.ru> Message-ID: <47CB00D8.2000800@cogito.org.uk> 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. From jmaessen at alum.mit.edu Sun Mar 2 14:36:34 2008 From: jmaessen at alum.mit.edu (Jan-Willem Maessen) Date: Sun Mar 2 14:34:11 2008 Subject: [Haskell-cafe] STAMP benchmark in Haskell? In-Reply-To: References: Message-ID: <45697B5E-F37B-436D-8DC1-06B72AEF6601@alum.mit.edu> On Mar 1, 2008, at 6:41 PM, Tom Davies wrote: > I'm experimenting with STM (in CAL[1] rather than Haskell) > and want to run the STAMP[2] benchmarks. Hmm, I don'tknow of a particularly good STM-in-Haskell benchmark, but I'd say that the STAMP benchmarks are written in a rather imperative, object-oriented style. You wouldn't get very meaningful data about anything if you were to naively translate them to Haskell; you'd instead have to rewrite them completely (at which point head-to-head comparisons are difficult). > Is there a Haskell translation available, or can anyone > suggest a better/different benchmark suite for STM? Good question. Because we tend to eschew mutable state in Haskell, I'd expect the characteristics of such an application to be *very* different. -Jan-Willem Maessen > > > Thanks, > Tom > > [1] http://openquark.org/Open_Quark/Welcome.html > [2] http://stamp.stanford.edu/ > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From lrpalmer at gmail.com Sun Mar 2 16:30:22 2008 From: lrpalmer at gmail.com (Luke Palmer) Date: Sun Mar 2 16:27:59 2008 Subject: [Haskell-cafe] coerce (safe!) In-Reply-To: <20080302084937.GA4045@home.ro-che.info> References: <220e47b40803011621u2a87ddc3t5cdb162b3d543b42@mail.gmail.com> <20080302084937.GA4045@home.ro-che.info> Message-ID: <7ca3f0160803021330gb7e7ed3td1f5fe8ff7e76d15@mail.gmail.com> 2008/3/2 Roman Cheplyaka : > * Krzysztof Skrz?tnicki [2008-03-02 01:21:42+0100] > > > Well, it is simply > > > > > coerce :: a -> b > > > coerce _ = undefined > > > > so coerce is simply empty function. But still, it is possible to write a > > function of type (a->b). > > Well, possibly I didn't write anything particularly new, but please excuse > > me for I'm still in > > sort of a shock after I've discovered it. > > Also there's nice possibility of defining Maybe a without ADT. > type Maybe a = (a, Bool) > just x = (x, True) > nothing = (undefined, False) That's a hack. This is my favorite: type Maybe a = forall b. (a -> b) -> b -> b just x = \j n -> j x nothing = \j n -> n Luke From k.kosciuszkiewicz+haskell at gmail.com Sun Mar 2 21:23:19 2008 From: k.kosciuszkiewicz+haskell at gmail.com (Krzysztof =?utf-8?Q?Ko=C5=9Bciuszkiewicz?=) Date: Sun Mar 2 21:21:05 2008 Subject: [Haskell-cafe] Space leak - help needed Message-ID: <20080303022318.GE29085@localdomain> Dear Haskellers, Another story from an (almost) happy Haskell user that finds himself overwhelmed by laziness/space leaks. I'm trying to parse a large file (>600MB) with a single S-expression like structure. With the help of ByteStrings I'm down to 4min processing time in constant space. However, when I try to wrap the parse results in a data structure, the heap blows up - even though I never actually inspect the structure being built! This bugs me, so I come here looking for answers. Parser follows: > module Main where > > import qualified Data.ByteString.Lazy.Char8 as B > import Text.ParserCombinators.Parsec > import Text.ParserCombinators.Parsec.Pos > import System.Environment > import System.Exit > import qualified Data.Map as M > import Lexer > > type XdlParser a = GenParser Token XdlState a > > -- Parser state > type XdlState = Counts > > type Counts = M.Map Count Integer > > data Count = ListCount | SymbolCount > deriving (Eq, Ord, Show) > > emptyXdlState = M.empty > > incCount :: Count -> (Counts -> Counts) > incCount c = M.insertWith' (+) c 1 > > -- handling tokens > myToken :: (Token -> Maybe a) -> XdlParser a > myToken test = token showTok posTok testTok > where > showTok = show > posTok = const (initialPos "") > testTok = test > > -- Syntax of expressions > data Exp = Sym !B.ByteString | List ![Exp] > deriving (Eq, Show) > > expr = list <|> symbol > > rparen = myToken $ \t -> case t of > RParen -> Just () > other -> Nothing > > lparen = myToken $ \t -> case t of > LParen -> Just () > other -> Nothing > > name = myToken $ \t -> case t of > Name n -> Just n > other -> Nothing > > list = do > updateState $ incCount ListCount > lparen > xs <- many1 expr > rparen > return () > -- return $! (List xs) > > symbol = do > updateState $ incCount SymbolCount > name >> return () > -- Sym `fmap` name > > -- Top level parser > top :: XdlParser XdlState > top = do > l <- many1 list > eof > getState > > main = do > args <- getArgs > case args of > [fname] -> do > text <- B.readFile fname > let result = runParser top emptyXdlState fname (tokenize text) > putStrLn $ either show show result > _ -> putStrLn "usage: parse filename" >> exitFailure And the Lexer: > module Lexer (Token(..), tokenize) where > > import qualified Data.ByteString.Lazy.Char8 as B > import Control.Monad > import Data.Char > import Data.List > import System.Environment > import System.Exit > > data Token = LParen > | RParen > | Name B.ByteString > deriving (Ord, Eq, Show) > > type Input = B.ByteString > > -- Processor returns Nothing if it can't process the Input > type Processor = Input -> Maybe ([Token], Input) > > -- Tokenize ends the list when all processors return Nothing > tokenize :: Input -> [Token] > tokenize = concat . unfoldr processAll > where > processors = [doSpaces, doComment, doParens, doName] > processAll :: Processor > processAll bs = if B.null bs > then Nothing > else foldr mminus Nothing $ map ($ bs) processors > mminus a@(Just _) _ = a > mminus Nothing b = b > > doSpaces :: Processor > doSpaces bs = > if B.null sp > then Nothing > else Just ([], nsp) > where > (sp, nsp) = B.span isSpace bs > > doComment :: Processor > doComment bs = > if B.pack "# " `B.isPrefixOf` bs > then Just ([], B.dropWhile (/= '\n') bs) > else Nothing > > doParens :: Processor > doParens bs = case B.head bs of > '(' -> Just ([LParen], B.tail bs) > ')' -> Just ([RParen], B.tail bs) > _ -> Nothing > > doName :: Processor > doName bs = > if B.null nsp > then Nothing > else Just ([Name nsp], sp) > where > (nsp, sp) = B.span (not . isRest) bs > isRest c = isSpace c || c == ')' || c == '(' Regards, -- Krzysztof Ko?ciuszkiewicz Skype: dr.vee, Gadu: 111851, Jabber: kokr@jabberpl.org "Simplicity is the ultimate sophistication" -- Leonardo da Vinci From lrpalmer at gmail.com Sun Mar 2 22:03:12 2008 From: lrpalmer at gmail.com (Luke Palmer) Date: Sun Mar 2 22:00:47 2008 Subject: [Haskell-cafe] Space leak - help needed In-Reply-To: <20080303022318.GE29085@localdomain> References: <20080303022318.GE29085@localdomain> Message-ID: <7ca3f0160803021903t1b2d69ecsa208cbdd12fbe1b0@mail.gmail.com> On Mon, Mar 3, 2008 at 2:23 AM, Krzysztof Ko?ciuszkiewicz wrote: > Dear Haskellers, > > Another story from an (almost) happy Haskell user that finds himself > overwhelmed by laziness/space leaks. > > I'm trying to parse a large file (>600MB) with a single S-expression > like structure. With the help of ByteStrings I'm down to 4min processing > time in constant space. However, when I try to wrap the parse results > in a data structure, the heap blows up - even though I never actually > inspect the structure being built! This bugs me, so I come here looking > for answers. Well, I haven't read this through, but superficially, it looks like you're expecting the data structure to be constructed lazily. But... > > -- Syntax of expressions > > data Exp = Sym !B.ByteString | List ![Exp] > > deriving (Eq, Show) It is declared as strict, so it's not going to be constructed lazily... Luke From bertram.felgenhauer at googlemail.com Sun Mar 2 23:20:09 2008 From: bertram.felgenhauer at googlemail.com (Bertram Felgenhauer) Date: Sun Mar 2 23:17:52 2008 Subject: [Haskell-cafe] Space leak - help needed In-Reply-To: <20080303022318.GE29085@localdomain> References: <20080303022318.GE29085@localdomain> Message-ID: <20080303042009.GB4363@zombie.inf.tu-dresden.de> Krzysztof Ko?ciuszkiewicz wrote: > Another story from an (almost) happy Haskell user that finds himself > overwhelmed by laziness/space leaks. > > I'm trying to parse a large file (>600MB) with a single S-expression > like structure. With the help of ByteStrings I'm down to 4min processing > time in constant space. However, when I try to wrap the parse results > in a data structure, the heap blows up - even though I never actually > inspect the structure being built! This bugs me, so I come here looking > for answers. Note that Parsec has to parse the whole file before it can decide whether to return a result (Left _) or an error (Right _). ghc would have to be quite smart to eliminate the creation of the expression tree entirely. The polyparse library (http://www.cs.york.ac.uk/fp/polyparse/) offers some lazy parsers, maybe one of those fits your needs. Text.ParserCombinators.Poly.StateLazy is the obvious candidate. HTH, Bertram From bjpop at csse.unimelb.edu.au Mon Mar 3 00:23:52 2008 From: bjpop at csse.unimelb.edu.au (Bernie Pope) Date: Mon Mar 3 00:16:55 2008 Subject: [Haskell-cafe] coerce (safe!) In-Reply-To: <7ca3f0160803021330gb7e7ed3td1f5fe8ff7e76d15@mail.gmail.com> References: <220e47b40803011621u2a87ddc3t5cdb162b3d543b42@mail.gmail.com> <20080302084937.GA4045@home.ro-che.info> <7ca3f0160803021330gb7e7ed3td1f5fe8ff7e76d15@mail.gmail.com> Message-ID: <77A44F60-51A9-4E9B-83DD-F00307066CBB@csse.unimelb.edu.au> On 03/03/2008, at 8:30 AM, Luke Palmer wrote: > 2008/3/2 Roman Cheplyaka : >> * Krzysztof Skrz?tnicki [2008-03-02 01:21:42 >> +0100] >> >>> Well, it is simply >>> >>>> coerce :: a -> b >>>> coerce _ = undefined >>> >>> so coerce is simply empty function. But still, it is possible to >>> write a >>> function of type (a->b). >>> Well, possibly I didn't write anything particularly new, but >>> please excuse >>> me for I'm still in >>> sort of a shock after I've discovered it. >> >> Also there's nice possibility of defining Maybe a without ADT. >> type Maybe a = (a, Bool) >> just x = (x, True) >> nothing = (undefined, False) > > That's a hack. This is my favorite: > > type Maybe a = forall b. (a -> b) -> b -> b > just x = \j n -> j x > nothing = \j n -> n For something slightly different, I've always enjoyed lists (or integer indexed structures) as functions: type List a = Integer -> Maybe a You've got to watch out for non-contiguous lists. It's a good challenge to write head, tail, nil and cons for this type. Then write conversions to/ from normal lists. Bernie. From sulzmann at comp.nus.edu.sg Mon Mar 3 03:41:52 2008 From: sulzmann at comp.nus.edu.sg (Martin Sulzmann) Date: Mon Mar 3 03:39:33 2008 Subject: [Haskell-cafe] STAMP benchmark in Haskell? In-Reply-To: <45697B5E-F37B-436D-8DC1-06B72AEF6601@alum.mit.edu> References: <45697B5E-F37B-436D-8DC1-06B72AEF6601@alum.mit.edu> Message-ID: <18379.47568.399751.427783@suna0.comp.nus.edu.sg> Some Haskell-STM benchmarks can be found here: Dissecting Transactional Executions in Haskell Cristian Perfumo et al http://www.cs.rochester.edu/meetings/TRANSACT07/ Martin -Willem Maessen writes: > > On Mar 1, 2008, at 6:41 PM, Tom Davies wrote: > > > I'm experimenting with STM (in CAL[1] rather than Haskell) > > and want to run the STAMP[2] benchmarks. > > Hmm, I don'tknow of a particularly good STM-in-Haskell benchmark, but > I'd say that the STAMP benchmarks are written in a rather imperative, > object-oriented style. You wouldn't get very meaningful data about > anything if you were to naively translate them to Haskell; you'd > instead have to rewrite them completely (at which point head-to-head > comparisons are difficult). > > > Is there a Haskell translation available, or can anyone > > suggest a better/different benchmark suite for STM? > > Good question. Because we tend to eschew mutable state in Haskell, > I'd expect the characteristics of such an application to be *very* > different. > > -Jan-Willem Maessen > > > > > > > Thanks, > > Tom > > > > [1] http://openquark.org/Open_Quark/Welcome.html > > [2] http://stamp.stanford.edu/ > > > > _______________________________________________ > > Haskell-Cafe mailing list > > Haskell-Cafe@haskell.org > > http://www.haskell.org/mailman/listinfo/haskell-cafe > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From icfp.publicity at googlemail.com Mon Mar 3 10:03:10 2008 From: icfp.publicity at googlemail.com (Matthew Fluet (ICFP Publicity Chair)) Date: Mon Mar 3 10:00:47 2008 Subject: [Haskell-cafe] ICFP08 Final CFP Message-ID: <53ff55480803030703p618af6cexe2710c7773648a7c@mail.gmail.com> Final Call for Papers ICFP 2008: International Conference on Functional Programming Victoria, BC, Canada, 22-24 September 2008 http://www.icfpconference.org/icfp2008 Submission deadline: 2 April 2008 ICFP 2008 seeks original papers on the art and science of functional programming. Submissions are invited on all topics from principles to practice, from foundations to features, from abstraction to application. The scope includes all languages that encourage functional programming, including both purely applicative and imperative languages, as well as languages with objects and concurrency. Particular topics of interest include * Applications and Domain-Specific Languages * Foundations * Design * Implementation * Transformation and Analysis * Software-development Techniques * Functional Pearls * Practice and Experience Important Dates (at 09:00 Apia time, UTC-11) ~~~~~~~~~~~~~~~ Submission: 2 April 2008 Author response: 21 May 2008 Notification: 16 June 2008 Final papers due: 7 July 2008 Call for Papers (full text) ~~~~~~~~~~~~~~~ http://www.icfpconference.org/icfp2008/cfp/cfp.html The submission URL will be available from the above page shortly. Program Chair ~~~~~~~~~~~~~ Peter Thiemann Albert-Ludwigs-Universit?t Georges-K?hler-Allee 079 79110 Freiburg, Germany Email: icfp08@informatik.uni-freiburg.de Phone: +49 761 203 8051 Fax: +49 761 203 8052 Mail sent to the address above is filtered for spam. If you send mail and do not receive a prompt response, particularly if the deadline is looming, feel free to telephone and reverse the charges. From jefferson.r.heard at gmail.com Mon Mar 3 11:14:42 2008 From: jefferson.r.heard at gmail.com (Jefferson Heard) Date: Mon Mar 3 11:12:56 2008 Subject: [Haskell-cafe] Failing to make `par` Message-ID: <4165d3a70803030814j4bfe7d1by3b417dd7851ecd1@mail.gmail.com> I've used Control.Parallel and Control.Parallel.Strategies extensively in the past, and I thought I knew what I was doing. I declared the following function: findSupernodes' :: S.Set Name -> Int -> Tree -> Protein.Tree -> S.Set Name findSupernodes' set size (Node i _ _ s il ir) (Protein.Node _ pl pr _ g) | S.size g > size = (Name (fromIntegral i)) `S.insert` set | otherwise = leftNodes `S.union` rightNodes where leftNodes = (findSupernodes' set size il pl) rightNodes = (findSupernodes' set size il pl) findSupernodes' set size (Leaf _ _) (Protein.Gene _ _ _) = set and then simply wrote the following as an initial stab at parallelizing it, because actually calling this function causes the program to execute an absurd number of string comparisons: findSupernodes = findSupernodes' S.empty findSupernodes' :: S.Set Name -> Int -> Tree -> Protein.Tree -> S.Set Name findSupernodes' set size (Node i _ _ s il ir) (Protein.Node _ pl pr _ g) | S.size g > size = (Name (fromIntegral i)) `S.insert` set | otherwise = leftNodes `par` rightNodes `seq` leftNodes `S.union` rightNodes where leftNodes = (findSupernodes' set size il pl) rightNodes = (findSupernodes' set size il pl) findSupernodes' set size (Leaf _ _) (Protein.Gene _ _ _) = set The thing is, these two functions don't return the same thing. The parallel version is returning an empty set, while the sequential version returns what it should return. Any clue what I did wrong? -- Jeff -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080303/33193347/attachment.htm From hpacheco at gmail.com Mon Mar 3 12:35:06 2008 From: hpacheco at gmail.com (Hugo Pacheco) Date: Mon Mar 3 12:32:41 2008 Subject: [Haskell-cafe] Issues(Bugs?) with GHC Type Families Message-ID: <7b92c2840803030935t6ed5d2a6ne63d5f8b3d5fe917@mail.gmail.com> Hi all, I have recently tried to replicate some examples from in the articles about type families but found some possible bugs. In [2], the example class C a where type S a (k :: * -> *) :: * instance C [a] where type S [a] k = (a,k a) does not compile under the claim that the type variable k is not in scope. However, if we extract the type family from the class type family S a (k :: * -> *) :: * type instance S [a] k = (a, k a) class C a it compiles correctly. According to [3], the difference is purely syntactic sugar, does that mean that both examples should compile and behave the same or is there some subtlety that justifies the class example not to compile? Another issue is that data kinds (used in both [2] and [3]) do not seem to be supported at all by the compiler, are they already implemented in GHC? Simple examples such as datakind Nat = Zero or datakind Nat = Zero | Succ Nat fail to compile. Perhaps some of these should be submitted to the GHC Bug Tracker. I have tested both GHC 6.8.2 and 6.9.20080218. References: 1. Associated Types with Class. Manuel M. T. Chakravarty, Gabriele Keller, Simon Peyton Jones, and Simon Marlow. In *Proceedings of The 32nd Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (POPL'05)*, pages 1-13, ACM Press, 2005. 2. Associated Type Synonyms. Manuel M. T. Chakravarty, Gabriele Keller, and Simon Peyton Jones. In *Proceedings of The Tenth ACM SIGPLAN International Conference on Functional Programming *, ACM Press, pages 241-253, 2005. 3. Towards Open Type Functions for Haskell. Tom Schrijvers, Martin Sulzmann, Simon Peyton-Jones, and Manuel M. T. Chakravarty. Unpublished manuscript, 2007. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080303/30db966f/attachment.htm From ryani.spam at gmail.com Mon Mar 3 13:33:23 2008 From: ryani.spam at gmail.com (Ryan Ingram) Date: Mon Mar 3 13:30:57 2008 Subject: [Haskell-cafe] Issues(Bugs?) with GHC Type Families In-Reply-To: <7b92c2840803030935t6ed5d2a6ne63d5f8b3d5fe917@mail.gmail.com> References: <7b92c2840803030935t6ed5d2a6ne63d5f8b3d5fe917@mail.gmail.com> Message-ID: <2f9b2d30803031033w46e956bdt13ec45d154579db4@mail.gmail.com> 2008/3/3 Hugo Pacheco : > class C a where > type S a (k :: * -> *) :: * > instance C [a] where > type S [a] k = (a,k a) > > does not compile under the claim that the type variable k is not in scope. It's not entirely syntactical sugar; I believe that when a type family is a member of a type-class it makes the assertion that only the class variables are part of the "function". In the class declaration: > class C a where > type S a (k :: * -> *) :: * there are two arguments to the type function S, but the class C only provides one. Contrast with the following > type Pair a k = (a, k a) > class C a where > type S a :: (* -> *) -> * > instance C [a] where > type S [a] = Pair a > datakind Nat = Zero > or > datakind Nat = Zero | Succ Nat datakinds are listed under "future work" in the papers I have read; they aren't implemented yet. -- ryan From dons at galois.com Mon Mar 3 17:22:59 2008 From: dons at galois.com (Don Stewart) Date: Mon Mar 3 17:20:40 2008 Subject: [Haskell-cafe] Re: static constants -- ideas? Message-ID: <20080303222259.GM12508@scytale.galois.com> jason.dusek: > I have an awkward programming problem -- I need to take a > dictionary, parse it, build a bunch of intermediate lists and > then make maps and tries out of the list. A "programming > problem" because it's taken me a fair amount of effort to pull > together the parser and list generator -- and "awkward" > because a 69000 item list, [(String, [(String, String)])], > does not compile under GHC (stack overflow). (It's not likely > to compile under anything else, either!) Here's an example of the approach Bryan outlined, which does seem to work for files as large as gcc can handle: * generate your big Haskell Map * serialise it with Data.Binary, and Codec.Compression.GZip to a file * compile the data into a C const array, and link that into Haskell * decode it on startup, ressurecting the Haskell data. The C source looks like: const uint8_t beowulf[] = { 31, 139, 8, 0, 0, 0, 0, 0, 0, 3, 124, 189, 75, 150, 46, 54, 93, 193, 96, 144, 241, 168, 172, 238, 214, 0, ... http://code.haskell.org/~dons/code/compiled-constants/cbits/constants.c which is the gzip, Data.Binary encoded version of a Map ByteString Int. Then the Haskell code need only access this array as a Ptr Word8, wrap that as a Bytestring, then run Data.Binary over the result to rebuild the Map. As you can see here: http://code.haskell.org/~dons/code/compiled-constants/Constants.hs I've put a couple of examples of how to access C-side serialised Haskell values in a package here: http://code.haskell.org/~dons/code/compiled-constants/ Cheers, Don From jgbailey at gmail.com Mon Mar 3 19:43:57 2008 From: jgbailey at gmail.com (Justin Bailey) Date: Mon Mar 3 19:41:30 2008 Subject: [Haskell-cafe] Annotating GHC assembler output? Message-ID: I'm interested in seeing what kind of assembler my functions turn into. Is there a means of annotating assembler output, similar to the {#- CORE -#} pragma? Is there a trickier way of doing it? Justin From gtener at gmail.com Mon Mar 3 19:45:44 2008 From: gtener at gmail.com (=?ISO-8859-2?Q?Krzysztof_Skrz=EAtnicki?=) Date: Mon Mar 3 19:43:23 2008 Subject: [Haskell-cafe] (flawed?) benchmark : sort Message-ID: <220e47b40803031645y3ca02ecbjc745604a2dc2e0b4@mail.gmail.com> Hi I was playing with various versions of sorting algorithms. I know it's very easy to create flawed benchmark and I don't claim those are good ones. However, it really seems strange to me, that sort - library function - is actually the worse measured function. I can hardly belive it, and I'd rather say I have made a mistake preparing it. The overall winner seems to be qsort_iv - which is nothing less but old sort replaced by mergesort now. Any clues? Regards Christopher Skrz?tnicki --- cut here --- [Tener@laptener haskell]$ ghc -O2 --make qsort.hs && ./qsort +RTS -sstderr -RTS > /dev/null [1 of 1] Compiling Main ( qsort.hs, qsort.o ) Linking qsort ... ./qsort +RTS -sstderr (1.0,"iv") (1.1896770400256864,"v") (1.3091609772011856,"treeSort") (1.592515715933153,"vii") (1.5953543402198838,"vi") (1.5961286512637272,"iii") (1.8175480563244177,"i") (1.8771604568641642,"ii") (2.453160634439497,"mergeSort") (2.6627090768870216,"sort") 26,094,674,624 bytes allocated in the heap 12,716,656,224 bytes copied during GC (scavenged) 2,021,104,592 bytes copied during GC (not scavenged) 107,225,088 bytes maximum residency (140 sample(s)) 49773 collections in generation 0 ( 21.76s) 140 collections in generation 1 ( 23.61s) 305 Mb total memory in use INIT time 0.00s ( 0.00s elapsed) MUT time 20.39s ( 20.74s elapsed) GC time 45.37s ( 46.22s elapsed) EXIT time 0.00s ( 0.00s elapsed) Total time 65.76s ( 66.96s elapsed) %GC time 69.0% (69.0% elapsed) Alloc rate 1,279,723,644 bytes per MUT second Productivity 31.0% of total user, 30.5% of total elapsed --- cut here --- {-# OPTIONS_GHC -O2 #-} module Main where import System.CPUTime import System.IO import System.Environment import System.Random import Data.List( partition, sort ) data Tree a = Node (Tree a) a (Tree a) | Leaf qsort_i [] = [] qsort_i (x:xs) = qsort_i (filter (< x) xs) ++ [x] ++ qsort_i (filter (>= x) xs) qsort_ii [] = [] qsort_ii (x:xs) = let (ls,gt) = partition (< x) xs in qsort_ii ls ++ [x] ++ qsort_ii gt qsort_iii xs = qsort_iii' [] xs qsort_iii' acc [] = acc qsort_iii' acc (x:xs) = let (ls,gt) = partition (< x) xs in let acc' = (x:(qsort_iii' acc gt)) in qsort_iii' acc' ls qsort_v [] = [] qsort_v (x:xs) = let (xlt, xgt ) = foldl (\ (lt,gt) el -> case compare x el of GT -> (el:lt, gt) _ -> (lt, el:gt) ) ([],[]) xs in qsort_v xlt ++ [x] ++ qsort_v xgt -- zmodyfikowany i qsort_vi [] = [] qsort_vi (x:xs) = qsort_vi (filter (\y-> compare x y == GT) xs) ++ [x] ++ qsort_vi (filter (\y-> compare x y /= GT) xs) -- zmodyfikowany iii qsort_vii xs = qsort_vii' [] xs qsort_vii' acc [] = acc qsort_vii' acc (x:xs) = let (ls,gt) = partition (\y-> compare x y == GT) xs in let acc' = (x:(qsort_vii' acc gt)) in qsort_vii' acc' ls -- qsort is stable and does not concatenate. qsort_iv xs = qsort_iv' (compare) xs [] qsort_iv' _ [] r = r qsort_iv' _ [x] r = x:r qsort_iv' cmp (x:xs) r = qpart cmp x xs [] [] r -- qpart partitions and sorts the sublists qpart cmp x [] rlt rge r = -- rlt and rge are in reverse order and must be sorted with an -- anti-stable sorting rqsort_iv' cmp rlt (x:rqsort_iv' cmp rge r) qpart cmp x (y:ys) rlt rge r = case cmp x y of GT -> qpart cmp x ys (y:rlt) rge r _ -> qpart cmp x ys rlt (y:rge) r -- rqsort is as qsort but anti-stable, i.e. reverses equal elements rqsort_iv' _ [] r = r rqsort_iv' _ [x] r = x:r rqsort_iv' cmp (x:xs) r = rqpart cmp x xs [] [] r rqpart cmp x [] rle rgt r = qsort_iv' cmp rle (x:qsort_iv' cmp rgt r) rqpart cmp x (y:ys) rle rgt r = case cmp y x of GT -> rqpart cmp x ys rle (y:rgt) r _ -> rqpart cmp x ys (y:rle) rgt r -- code by Orcus -- Zadanie 9 - merge sort mergeSort :: Ord a => [a] -> [a] mergeSort [] = [] mergeSort [x] = [x] mergeSort xs = let(l, r) = splitAt (length xs `quot` 2) xs in mergeSortP (mergeSort l) (mergeSort r) -- funkcja pomocnicza scalaj??ca dwie listy uporz??dkowane w jedn?? mergeSortP :: Ord a => [a] -> [a] -> [a] mergeSortP xs [] = xs mergeSortP [] ys = ys mergeSortP (x:xs) (y:ys) | x <= y = x:(mergeSortP xs (y:ys)) | otherwise = y:(mergeSortP (x:xs) ys) -- Zadanie 10 - tree sort treeSort :: Ord a => [a] -> [a] -- pointless po raz drugi treeSort = (treeSortInorder . treeSortToTree) treeSortToTree :: Ord a => [a] -> Tree a treeSortToTree [] = Leaf treeSortToTree (x:xs) = let (xlt, xgt) = foldl (\ (lt,gt) el -> case compare x el of GT -> (el:lt, gt) _ -> (lt, el:gt) ) ([],[]) xs in Node (treeSortToTree xlt) x (treeSortToTree xgt) treeSortInorder :: Ord a => Tree a -> [a] treeSortInorder Leaf = [] treeSortInorder (Node l x r) = (treeSortInorder l) ++ [x] ++ (treeSortInorder r) -- end code by Orcus -- big_number = 1000000 :: Int main = do gen <- getStdGen let xs' = randomRs (1::Int, big_number) gen xs <- return (take big_number xs') t1 <- getCPUTime print (qsort_i xs) -- i t2 <- getCPUTime print (qsort_ii xs) -- ii t3 <- getCPUTime print (qsort_iii xs) -- iii t4 <- getCPUTime print (qsort_iv xs) -- iv t5 <- getCPUTime print (qsort_v xs) -- v t6 <- getCPUTime print (qsort_vi xs) -- vi t7 <- getCPUTime print (qsort_vii xs) -- vii t8 <- getCPUTime print (sort xs) -- sort t9 <- getCPUTime print (mergeSort xs) -- mergeSort t10 <- getCPUTime print (treeSort xs) -- treeSort t11 <- getCPUTime let getTimes xs = zipWith (-) (tail xs) xs let timers = [t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11] let times = getTimes timers let table = zip times ["i","ii","iii","iv", "v", "vi", "vii", "sort","mergeSort","treeSort"] let sorted = sort table let scaled = map (\(x,n) -> (((fromIntegral x / (fromIntegral $ fst (head sorted)))::Double),n)) sorted let toShow = concatMap (\x-> show x ++ "\n") scaled hPutStr stderr toShow main_small = do gen <- getStdGen let xs' = randomRs (1::Int, 100000) gen xs <- return (take big_number xs') t1 <- getCPUTime print (qsort_iv xs) -- iv t2 <- getCPUTime print (sort xs) -- sort t3 <- getCPUTime print (mergeSort xs) -- mergeSort t4 <- getCPUTime print (treeSort xs) -- treeSort t5 <- getCPUTime let getTimes xs = zipWith (-) (tail xs) xs let timers = [t1,t2,t3,t4,t5] let times = getTimes timers let table = zip times ["iv", "sort","mergeSort","treeSort"] let sorted = sort table let scaled = map (\(x,n) -> (((fromIntegral x / (fromIntegral $ fst (head sorted)))::Double),n)) sorted let toShow = concatMap (\x-> show x ++ "\n") scaled hPutStr stderr toShow hPrint stderr times --- cut here --- -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080304/3d912e5d/attachment.htm From Ben.Lippmeier at anu.edu.au Mon Mar 3 20:41:13 2008 From: Ben.Lippmeier at anu.edu.au (Ben Lippmeier) Date: Mon Mar 3 20:38:52 2008 Subject: [Haskell-cafe] Annotating GHC assembler output? In-Reply-To: References: Message-ID: <47CCA8B9.5080506@anu.edu.au> Hi Justin. try: ghc -c -ddump-to-file -ddump-asm You should get a .dump.asm file in the same place as which still has symbols named after the source functions. Keep in mind though that the continuation passing style (CPS) conversion done in the back end of GHC causes the code not to look like something you might get out of, say GCC. Ben. Justin Bailey wrote: > I'm interested in seeing what kind of assembler my functions turn > into. Is there a means of annotating assembler output, similar to the > {#- CORE -#} pragma? Is there a trickier way of doing it? > > Justin > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From Ben.Lippmeier at anu.edu.au Mon Mar 3 20:50:28 2008 From: Ben.Lippmeier at anu.edu.au (Ben Lippmeier) Date: Mon Mar 3 20:48:03 2008 Subject: [Haskell-cafe] Annotating GHC assembler output? In-Reply-To: References: Message-ID: <47CCAAE4.1080702@anu.edu.au> And to answer your actual question.. No - notes in the core language get stripped out during conversion to STG. Ben. Justin Bailey wrote: > I'm interested in seeing what kind of assembler my functions turn > into. Is there a means of annotating assembler output, similar to the > {#- CORE -#} pragma? Is there a trickier way of doing it? > > Justin > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From chak at cse.unsw.edu.au Mon Mar 3 21:36:07 2008 From: chak at cse.unsw.edu.au (Manuel M T Chakravarty) Date: Mon Mar 3 21:33:50 2008 Subject: [Haskell-cafe] Issues(Bugs?) with GHC Type Families In-Reply-To: <7b92c2840803030935t6ed5d2a6ne63d5f8b3d5fe917@mail.gmail.com> References: <7b92c2840803030935t6ed5d2a6ne63d5f8b3d5fe917@mail.gmail.com> Message-ID: Hugo Pacheco: > I have recently tried to replicate some examples from in the > articles about type families but found some possible bugs. > > In [2], the example > > class C a where > type S a (k :: * -> *) :: * > instance C [a] where > type S [a] k = (a,k a) > > does not compile under the claim that the type variable k is not in > scope. > > However, if we extract the type family from the class > > type family S a (k :: * -> *) :: * > type instance S [a] k = (a, k a) > class C a > > it compiles correctly. > According to [3], the difference is purely syntactic sugar, does > that mean that both examples should compile and behave the same or > is there some subtlety that justifies the class example not to > compile? I am sorry for the confusion this causes, but we wrote the paper before the implementation in GHC was finalised. Hence, the implementation deviates from the paper in some aspects. Generally, please use http://haskell.org/haskellwiki/GHC/Type_families (which will be integrated into GHC's Users Manual for 6.10) as the definite guide to the implementation. Here a brief rational for this change in design. We originally intended to distinguish between type parameters that do use type indexing (the a in (S a k)) and those that do not (the k in (S a k)). However, we found later that this leads to implementation problems. The new rule is that any explicitly named parmeters, eg, s and k in type family S a (k :: * -> *) :: * are indexed. If you don't want to use the second parameter as an index, write type S a :: (* -> *) -> * This is also simpler to explain, as simply *all* explicitly named parameters in a type family declaration are indicies. > Another issue is that data kinds (used in both [2] and [3]) do not > seem to be supported at all by the compiler, are they already > implemented in GHC? > > Simple examples such as > > datakind Nat = Zero > or > datakind Nat = Zero | Succ Nat > > fail to compile. No, datakinds aren't supported yet. We still intend to add them, but our first priority is to thoroughly debug the existing functionality and especially to make sure the interaction with GADTs works well. Thanks for the feedback. Manuel From baseballfurlife at gmail.com Mon Mar 3 21:55:03 2008 From: baseballfurlife at gmail.com (adekoba) Date: Mon Mar 3 21:57:35 2008 Subject: [Haskell-cafe] ID3 tagging Message-ID: I was wondering if there are any haskell packages for tagging ID3 frames in mp3 files. Or perhaps if there were any plans for developing them... From dons at galois.com Mon Mar 3 23:07:21 2008 From: dons at galois.com (Don Stewart) Date: Mon Mar 3 23:04:56 2008 Subject: [Haskell-cafe] ID3 tagging In-Reply-To: References: Message-ID: <20080304040721.GA23086@scytale.galois.com> baseballfurlife: > I was wondering if there are any haskell packages for tagging ID3 frames in mp3 > files. Or perhaps if there were any plans for developing them... hpodder includes the ability to write id3 tags, iirc, http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hpodder if you can't find a specific library for it, an id3 binding would make a great introductory haskell programming exercise. -- Don From vigalchin at gmail.com Mon Mar 3 23:56:55 2008 From: vigalchin at gmail.com (Galchin Vasili) Date: Mon Mar 3 23:54:27 2008 Subject: [Haskell-cafe] automagically? Message-ID: <5ae4f2ba0803032056l18979319t384c527a337899b3@mail.gmail.com> Hello, Say i am building package X that depends on A, H, D. How can I automagically check to A, H, D need to "darcs get" down and built/install before X? If this feature is not available it should be, i.e. an integration of darcs and cabal. Regards, Vasya -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080303/757f96cf/attachment.htm From dons at galois.com Mon Mar 3 23:59:21 2008 From: dons at galois.com (Don Stewart) Date: Mon Mar 3 23:56:57 2008 Subject: [Haskell-cafe] automagically? In-Reply-To: <5ae4f2ba0803032056l18979319t384c527a337899b3@mail.gmail.com> References: <5ae4f2ba0803032056l18979319t384c527a337899b3@mail.gmail.com> Message-ID: <20080304045921.GB23086@scytale.galois.com> vigalchin: > Hello, > > Say i am building package X that depends on A, H, D. How can I > automagically check to A, H, D need to "darcs get" down and built/install > before X? If this feature is not available it should be, i.e. an > integration of darcs and cabal. > There are a couple of tools to do this ("searchpath" distributed with HAppS is one such tool). For enterprise Haskell, better to rely on hackage.haskell.org, stable releases of code, and using the "cabal-install" tool to gather and install dependencies. -- Don From alangcarter at gmail.com Tue Mar 4 01:29:24 2008 From: alangcarter at gmail.com (Alan Carter) Date: Tue Mar 4 01:26:57 2008 Subject: [Haskell-cafe] Doubting Haskell In-Reply-To: <2608b8a80802210523v55dd8588n7b10511a1e25d74a@mail.gmail.com> References: <56a54d4d0802161405l774ff97djada856fbccdb8b08@mail.gmail.com> <89ca3d1f0802190648s230c67cet40a9612397dd482f@mail.gmail.com> <56a54d4d0802191727h4a2a64a3xcd532ccf86e5a9a@mail.gmail.com> <89ca3d1f0802200158g5f1b884eua5b4ea5634471d9b@mail.gmail.com> <2608b8a80802210523v55dd8588n7b10511a1e25d74a@mail.gmail.com> Message-ID: <56a54d4d0803032229t6b2456c2ka920d99cd8ef377d@mail.gmail.com> Many thanks for the explanations when I was first experimenting with Haskell. I managed to finish translating a C++ wxWidgets program into Haskell wxHaskell, and am certainly impressed. 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/ Regards, Alan -- ... the PA system was moaning unctuously, like a lady hippopotamus reading A. E. Housman ..." -- James Blish, "They Shall Have Stars" From magnus at therning.org Tue Mar 4 03:10:04 2008 From: magnus at therning.org (Magnus Therning) Date: Tue Mar 4 03:07:40 2008 Subject: [Haskell-cafe] CABAL: conditional executable? Message-ID: <47CD03DC.3000402@therning.org> I'm putting together a package consisting of 2 executables. Only one of them is pure Haskell and thus buildable on all platforms, the other relies on Windows API calls and can only be built on that platform. I found the ?if os(...)? conditional in the CABAL docs but I'm having problems getting it to do what I want. if os(mingw32) executable foo ... Results in the error ?Section expected?. Swapping the two lines like this executable foo if os(mingw32) ... results in ?Setup.hs: Error: No 'Main-Is' field found for executable foo?. Is there a way to get CABAL to do what I want or should I raise a feature request on the CABAL trac? /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?gmail?com http://therning.org/magnus What if I don't want to obey the laws? Do they throw me in jail with the other bad monads? -- Daveman -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: OpenPGP digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20080304/6486e72f/signature.bin From nominolo at googlemail.com Tue Mar 4 03:54:55 2008 From: nominolo at googlemail.com (Thomas Schilling) Date: Tue Mar 4 03:52:33 2008 Subject: [Haskell-cafe] CABAL: conditional executable? In-Reply-To: <47CD03DC.3000402@therning.org> References: <47CD03DC.3000402@therning.org> Message-ID: <6D5A5CD1-080A-4874-87DE-6CA4D64B9230@googlemail.com> executable foo main-is: bla if !os(windows): buildable: false Unfortunately this gives rather unhelpful error messages when used with flags, but it works well enough for now. / Thomas On 4 mar 2008, at 09.10, Magnus Therning wrote: > I'm putting together a package consisting of 2 executables. Only > one of > them is pure Haskell and thus buildable on all platforms, the other > relies on Windows API calls and can only be built on that platform. I > found the ?if os(...)? conditional in the CABAL docs but I'm > having > problems getting it to do what I want. > > if os(mingw32) > executable foo > ... > > Results in the error ?Section expected?. Swapping the two lines > like this > > executable foo > if os(mingw32) > ... > > results in ?Setup.hs: Error: No 'Main-Is' field found for > executable foo?. > > Is there a way to get CABAL to do what I want or should I raise a > feature request on the CABAL trac? > > /M > > -- > Magnus Therning (OpenPGP: 0xAB4DFBA4) > magnus?therning?org Jabber: magnus?therning? > gmail?com > http://therning.org/magnus > > What if I don't want to obey the laws? Do they throw me in jail with > the other bad monads? > -- Daveman > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From lemming at henning-thielemann.de Tue Mar 4 04:18:12 2008 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Tue Mar 4 04:14:36 2008 Subject: [Haskell-cafe] CABAL: conditional executable? In-Reply-To: <47CD03DC.3000402@therning.org> References: <47CD03DC.3000402@therning.org> Message-ID: On Tue, 4 Mar 2008, Magnus Therning wrote: > I'm putting together a package consisting of 2 executables. Only one of > them is pure Haskell and thus buildable on all platforms, the other > relies on Windows API calls and can only be built on that platform. I > found the ???if os(...)??? conditional in the CABAL docs but I'm having > problems getting it to do what I want. > > if os(mingw32) > executable foo > ... > > Results in the error ???Section expected???. Swapping the two lines like this > > executable foo > if os(mingw32) > ... > > results in ???Setup.hs: Error: No 'Main-Is' field found for executable foo???. It sounds like another instance of the case that parts of a package cannot be build under some circumstances. Keep in mind that other packages might rely on the installed second executable if they find that the package is installed. Thus, I guess it's better to extract the second executable to a different package for Window's only stuff. From magnus at therning.org Tue Mar 4 04:58:36 2008 From: magnus at therning.org (Magnus Therning) Date: Tue Mar 4 04:56:09 2008 Subject: [Haskell-cafe] CABAL: conditional executable? In-Reply-To: References: <47CD03DC.3000402@therning.org> Message-ID: On 3/4/08, Henning Thielemann wrote: > > > On Tue, 4 Mar 2008, Magnus Therning wrote: > > > I'm putting together a package consisting of 2 executables. Only one of > > them is pure Haskell and thus buildable on all platforms, the other > > relies on Windows API calls and can only be built on that platform. I > > > found the ? if os(...)? conditional in the CABAL docs but I'm having > > > problems getting it to do what I want. > > > > if os(mingw32) > > executable foo > > ... > > > > > Results in the error ? Section expected? . Swapping the two lines > like this > > > > > executable foo > > if os(mingw32) > > ... > > > > > results in ? Setup.hs: Error: No 'Main-Is' field found for executable > foo? . > > It sounds like another instance of the case that parts of a package cannot > be build under some circumstances. Keep in mind that other packages might > rely on the installed second executable if they find that the package is > installed. Thus, I guess it's better to extract the second executable to a > different package for Window's only stuff. Good point. Does CABAL 1.2 have support for multiple .cabal files in the same directory? If not then I'm not too happy with this solution. /M -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080304/e5112d0b/attachment.htm From nominolo at googlemail.com Tue Mar 4 05:03:05 2008 From: nominolo at googlemail.com (Thomas Schilling) Date: Tue Mar 4 05:00:49 2008 Subject: [Haskell-cafe] CABAL: conditional executable? In-Reply-To: References: <47CD03DC.3000402@therning.org> Message-ID: On 4 mar 2008, at 10.58, Magnus Therning wrote: > > > Good point. Does CABAL 1.2 have support for multiple .cabal files > in the same directory? If not then I'm not too happy with this > solution. No. Eventually, Cabal will support something like this, but it's unlikely that Cabal 1.4 will. From magnus at therning.org Tue Mar 4 05:37:09 2008 From: magnus at therning.org (Magnus Therning) Date: Tue Mar 4 05:34:41 2008 Subject: [Haskell-cafe] CABAL: conditional executable? In-Reply-To: <6D5A5CD1-080A-4874-87DE-6CA4D64B9230@googlemail.com> References: <47CD03DC.3000402@therning.org> <6D5A5CD1-080A-4874-87DE-6CA4D64B9230@googlemail.com> Message-ID: On 3/4/08, Thomas Schilling wrote: > > executable foo > main-is: bla > if !os(windows): > buildable: false > > Unfortunately this gives rather unhelpful error messages when used > with flags, but it works well enough for now. > > / Thomas Hmmm, I don't seem to get this to work the way I want it. I get a "Parse of field 'buildable' failed:" which means configure failed and then I can't proceed to build the second executable, bar, in the same package. /M -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080304/427a7f3c/attachment.htm From paul at cogito.org.uk Tue Mar 4 05:48:34 2008 From: paul at cogito.org.uk (Paul Johnson) Date: Tue Mar 4 05:46:08 2008 Subject: [Haskell-cafe] Doubting Haskell In-Reply-To: <56a54d4d0803032229t6b2456c2ka920d99cd8ef377d@mail.gmail.com> References: <56a54d4d0802161405l774ff97djada856fbccdb8b08@mail.gmail.com> <89ca3d1f0802190648s230c67cet40a9612397dd482f@mail.gmail.com> <56a54d4d0802191727h4a2a64a3xcd532ccf86e5a9a@mail.gmail.com> <89ca3d1f0802200158g5f1b884eua5b4ea5634471d9b@mail.gmail.com> <2608b8a80802210523v55dd8588n7b10511a1e25d74a@mail.gmail.com> <56a54d4d0803032229t6b2456c2ka920d99cd8ef377d@mail.gmail.com> Message-ID: <47CD2902.2070608@cogito.org.uk> 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. From nominolo at googlemail.com Tue Mar 4 06:08:49 2008 From: nominolo at googlemail.com (Thomas Schilling) Date: Tue Mar 4 06:06:37 2008 Subject: [Haskell-cafe] CABAL: conditional executable? In-Reply-To: References: <47CD03DC.3000402@therning.org> <6D5A5CD1-080A-4874-87DE-6CA4D64B9230@googlemail.com> Message-ID: <889D9BE0-29FC-4F34-A574-7BDD32AF8F11@googlemail.com> On 4 mar 2008, at 11.37, Magnus Therning wrote: > On 3/4/08, Thomas Schilling wrote: > executable foo > main-is: bla > if !os(windows): > buildable: false > > Unfortunately this gives rather unhelpful error messages when used > with flags, but it works well enough for now. > > / Thomas > > Hmmm, I don't seem to get this to work the way I want it. I get a > "Parse of field 'buildable' failed:" which means configure failed > and then I can't proceed to build the second executable, bar, in > the same package. Oh, right. That's a bug in Cabal 1.2 (fixed in HEAD). Use: buildable: False HTH From ketil at malde.org Tue Mar 4 06:16:45 2008 From: ketil at malde.org (Ketil Malde) Date: Tue Mar 4 06:14:12 2008 Subject: [Haskell-cafe] Doubting Haskell In-Reply-To: <47CD2902.2070608@cogito.org.uk> (Paul Johnson's message of "Tue\, 04 Mar 2008 10\:48\:34 +0000") References: <56a54d4d0802161405l774ff97djada856fbccdb8b08@mail.gmail.com> <89ca3d1f0802190648s230c67cet40a9612397dd482f@mail.gmail.com> <56a54d4d0802191727h4a2a64a3xcd532ccf86e5a9a@mail.gmail.com> <89ca3d1f0802200158g5f1b884eua5b4ea5634471d9b@mail.gmail.com> <2608b8a80802210523v55dd8588n7b10511a1e25d74a@mail.gmail.com> <56a54d4d0803032229t6b2456c2ka920d99cd8ef377d@mail.gmail.com> <47CD2902.2070608@cogito.org.uk> Message-ID: <87zlte7n8i.fsf@nmd9999.imr.no> Paul Johnson writes: > I'm surprised you found the significant whitespace difficult. I wonder if this has something to do with the editor one uses? I use Emacs, and just keep hitting TAB, cycling through possible alignments, until things align sensibly. I haven't really tried, but I can imagine lining things up manually would be more painful, especially if mixing tabs and spaces. -k -- If I haven't seen further, it is by standing in the footprints of giants From lrpalmer at gmail.com Tue Mar 4 06:44:56 2008 From: lrpalmer at gmail.com (Luke Palmer) Date: Tue Mar 4 06:42:26 2008 Subject: [Haskell-cafe] Doubting Haskell In-Reply-To: <87zlte7n8i.fsf@nmd9999.imr.no> References: <56a54d4d0802161405l774ff97djada856fbccdb8b08@mail.gmail.com> <89ca3d1f0802190648s230c67cet40a9612397dd482f@mail.gmail.com> <56a54d4d0802191727h4a2a64a3xcd532ccf86e5a9a@mail.gmail.com> <89ca3d1f0802200158g5f1b884eua5b4ea5634471d9b@mail.gmail.com> <2608b8a80802210523v55dd8588n7b10511a1e25d74a@mail.gmail.com> <56a54d4d0803032229t6b2456c2ka920d99cd8ef377d@mail.gmail.com> <47CD2902.2070608@cogito.org.uk> <87zlte7n8i.fsf@nmd9999.imr.no> Message-ID: <7ca3f0160803040344r5f9efad5o38ed9204dba30e8a@mail.gmail.com> On Tue, Mar 4, 2008 at 4:16 AM, Ketil Malde wrote: > Paul Johnson writes: > > > I'm surprised you found the significant whitespace difficult. > > I wonder if this has something to do with the editor one uses? I use > Emacs, and just keep hitting TAB, cycling through possible alignments, > until things align sensibly. I haven't really tried, but I can > imagine lining things up manually would be more painful, especially > if mixing tabs and spaces. Especially if mixing tabs and spaces indeed. Haskell does the Python thing of assuming that a tab is 8 spaces, which IMO is a mistake. The sensible thing to do if you have a whitespace-sensitive language that accepts both spaces in tabs is to make them incomparable to each other; i.e. main = do putStrLn $ "Hello" ++ "World" -- compiles fine main = do putStrLn $ "Hello" ++ "World" -- error, can't tell how indented '++ "World"' is... Luke From lemming at henning-thielemann.de Tue Mar 4 09:04:01 2008 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Tue Mar 4 09:00:24 2008 Subject: [Haskell-cafe] Markup bug in HaskellWiki Message-ID: In the Wiki article http://haskell.org/haskellwiki/Comparison_chain there is the piece unzip">unzip which is improperly formatted. From dougal at dougalstanton.net Tue Mar 4 10:10:19 2008 From: dougal at dougalstanton.net (Dougal Stanton) Date: Tue Mar 4 10:07:54 2008 Subject: [Haskell-cafe] Markup bug in HaskellWiki In-Reply-To: References: Message-ID: <2d3641330803040710u4b2a2951wbfc84c5f05b0330a@mail.gmail.com> On 04/03/2008, Henning Thielemann wrote: > > In the Wiki article > > http://haskell.org/haskellwiki/Comparison_chain > > there is the piece > > unzip">unzip > > which is improperly formatted. I guess the wiki uses GeSHi, and it's because of a bug in the keyword list. I reported it to the maintainer a few weeks ago (when I wrote this [1]) but I haven't heard any word back. It's dead easy to fix if someone has access to the PHP source. There's a file called, IIRC, haskell.php with a large list of keywords. Two of them, 'unzip' and 'unzip3' appear twice. Delete one of each and it all works fine again. [1] -- Dougal Stanton dougal@dougalstanton.net // http://www.dougalstanton.net From p.f.moore at gmail.com Tue Mar 4 10:18:46 2008 From: p.f.moore at gmail.com (Paul Moore) Date: Tue Mar 4 10:16:17 2008 Subject: [Haskell-cafe] Doubting Haskell In-Reply-To: <56a54d4d0803032229t6b2456c2ka920d99cd8ef377d@mail.gmail.com> References: <56a54d4d0802161405l774ff97djada856fbccdb8b08@mail.gmail.com> <89ca3d1f0802190648s230c67cet40a9612397dd482f@mail.gmail.com> <56a54d4d0802191727h4a2a64a3xcd532ccf86e5a9a@mail.gmail.com> <89ca3d1f0802200158g5f1b884eua5b4ea5634471d9b@mail.gmail.com> <2608b8a80802210523v55dd8588n7b10511a1e25d74a@mail.gmail.com> <56a54d4d0803032229t6b2456c2ka920d99cd8ef377d@mail.gmail.com> Message-ID: <79990c6b0803040718q507f84a2gd8692bb4038be73a@mail.gmail.com> On 04/03/2008, Alan Carter wrote: > http://the-programmers-stone.com/2008/03/04/a-first-haskell-experience/ That was an interesting read. Thanks for posting it. I also liked the tale of the BBC ULA - it reminded me of a demo I saw once at an Acorn show, where they had a RISC PC on show, with a (IBM) PC card in it. They were demonstrating how hot the PC chip runs compared to the ARM RISC chip by using it to make toast. I dread to think what you could do with one of today's monsters :-) Paul. From bjorn at bringert.net Tue Mar 4 10:31:41 2008 From: bjorn at bringert.net (Bjorn Bringert) Date: Tue Mar 4 10:29:18 2008 Subject: [Haskell-cafe] Connection helpers: for people interested in network code In-Reply-To: <396556a20802291150y683a8ca5q1065e87a48b6e518@mail.gmail.com> References: <396556a20802291150y683a8ca5q1065e87a48b6e518@mail.gmail.com> Message-ID: On Fri, Feb 29, 2008 at 8:50 PM, Adam Langley wrote: > I generally find that I'm wrapping sockets in the same functions a lot > and now I'm looking writings code which works with both Sockets and > SSL connections. So I wrote a module, presumptuously called > Network.Connection, although I'm not actually going to try and take > that name (even in Hackage) unless I get a general agreement that this > is a good thing. > > So, any comments on the interface, similar things that I should look at etc? > > http://www.imperialviolet.org/binary/network-connection/Network-Connection.html > > I made the BaseConnection an ADT, rather than a class because I wanted > to avoid hitting the monomorphism restriction in code. That might have > been a mistake, I'm not sure yet. > > If it doesn't excite anyone enough to reply, I'll change the name and > put it in Hackage, mostly as is. Then I'll tie HsOpenSSL into it so > that SSL connections work transparently. Hi Adam, you may want to have a look at the socket abstraction used in the HTTP package: http://hackage.haskell.org/packages/archive/HTTP/3001.0.4/doc/html/Network-Stream.html It would be great to get HTTPS support going! /Bjorn From vikrant.patil at gmail.com Tue Mar 4 10:45:47 2008 From: vikrant.patil at gmail.com (Vikrant) Date: Tue Mar 4 10:43:19 2008 Subject: [Haskell-cafe] problem in using wash Message-ID: Hi, I was trying to use wash to learn it. I am using ubuntu and I have ghc6.6.1 installed on my system. I have also installed the package libghc6-wash-dev but in my code when i write "import WASH.CGI" it gives me following error firstCGI.hs:5:7: Could not find module `WASH.CGI': locations searched: WASH/CGI.hs WASH/CGI.lhs Failed, modules loaded: none. can somebody help me in this? Regards, Vikrant -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080304/dc5afef4/attachment.htm From agl at imperialviolet.org Tue Mar 4 11:15:24 2008 From: agl at imperialviolet.org (Adam Langley) Date: Tue Mar 4 11:12:56 2008 Subject: [Haskell-cafe] Connection helpers: for people interested in network code In-Reply-To: References: <396556a20802291150y683a8ca5q1065e87a48b6e518@mail.gmail.com> Message-ID: <396556a20803040815i13c70459gdcaf4b1469403f13@mail.gmail.com> On Tue, Mar 4, 2008 at 7:31 AM, Bjorn Bringert wrote: > you may want to have a look at the socket abstraction used in the HTTP package: > > http://hackage.haskell.org/packages/archive/HTTP/3001.0.4/doc/html/Network-Stream.html > > It would be great to get HTTPS support going! I should have mentioned that I had seen this in the original email. I think the major problem with this interface was that it was written in the time before ByteStrings. Now that we have ByteStrings I think that it makes a lot of sense for networking to use them. However, it shouldn't be too hard to wrap HsOpenSSL in this interface. I might try this this week. Then HTTPS should Just Work (maybe ;) AGL -- Adam Langley agl@imperialviolet.org http://www.imperialviolet.org From g9ks157k at acme.softbase.org Tue Mar 4 11:15:37 2008 From: g9ks157k at acme.softbase.org (Wolfgang Jeltsch) Date: Tue Mar 4 11:14:14 2008 Subject: [Haskell-cafe] Markup bug in HaskellWiki In-Reply-To: <2d3641330803040710u4b2a2951wbfc84c5f05b0330a@mail.gmail.com> References: <2d3641330803040710u4b2a2951wbfc84c5f05b0330a@mail.gmail.com> Message-ID: <200803041715.37919.g9ks157k@acme.softbase.org> Am Dienstag, 4. M?rz 2008 16:10 schrieb Dougal Stanton: > [?] > There's a file called, IIRC, haskell.php with a large list of > keywords. Two of them, 'unzip' and 'unzip3' appear twice. Delete one > of each and it all works fine again. Why do they appear at all? They are not keywords. Best wishes, Wolfgang From cgibbard at gmail.com Tue Mar 4 11:21:15 2008 From: cgibbard at gmail.com (Cale Gibbard) Date: Tue Mar 4 11:18:47 2008 Subject: [Haskell-cafe] Doubting Haskell In-Reply-To: <7ca3f0160803040344r5f9efad5o38ed9204dba30e8a@mail.gmail.com> References: <56a54d4d0802161405l774ff97djada856fbccdb8b08@mail.gmail.com> <89ca3d1f0802190648s230c67cet40a9612397dd482f@mail.gmail.com> <56a54d4d0802191727h4a2a64a3xcd532ccf86e5a9a@mail.gmail.com> <89ca3d1f0802200158g5f1b884eua5b4ea5634471d9b@mail.gmail.com> <2608b8a80802210523v55dd8588n7b10511a1e25d74a@mail.gmail.com> <56a54d4d0803032229t6b2456c2ka920d99cd8ef377d@mail.gmail.com> <47CD2902.2070608@cogito.org.uk> <87zlte7n8i.fsf@nmd9999.imr.no> <7ca3f0160803040344r5f9efad5o38ed9204dba30e8a@mail.gmail.com> Message-ID: <89ca3d1f0803040821v2a679207vbbc6e748bcffcc79@mail.gmail.com> On 04/03/2008, Luke Palmer wrote: > On Tue, Mar 4, 2008 at 4:16 AM, Ketil Malde wrote: > > Paul Johnson writes: > > > > > I'm surprised you found the significant whitespace difficult. > > > > I wonder if this has something to do with the editor one uses? I use > > Emacs, and just keep hitting TAB, cycling through possible alignments, > > until things align sensibly. I haven't really tried, but I can > > imagine lining things up manually would be more painful, especially > > if mixing tabs and spaces. > > > Especially if mixing tabs and spaces indeed. Haskell does the Python > thing of assuming that a tab is 8 spaces, which IMO is a mistake. The > sensible thing to do if you have a whitespace-sensitive language that > accepts both spaces in tabs is to make them incomparable to each > other; i.e. I honestly think that tab characters occurring anywhere but in a comment should be considered a lexical error and rejected by the compiler outright. More problems are caused by trying to continue with only tabs, or some mixture of tabs and spaces than just getting one's editor to expand tabs automatically. - Cale From jgbailey at gmail.com Tue Mar 4 11:28:20 2008 From: jgbailey at gmail.com (Justin Bailey) Date: Tue Mar 4 11:25:53 2008 Subject: [Haskell-cafe] Annotating GHC assembler output? In-Reply-To: <47CCA8B9.5080506@anu.edu.au> References: <47CCA8B9.5080506@anu.edu.au> Message-ID: On Mon, Mar 3, 2008 at 5:41 PM, Ben Lippmeier wrote: > Hi Justin. > > try: ghc -c -ddump-to-file -ddump-asm > Thanks, that does it. I also tried the -keep-s-files (possibly new to 6.8) and found it produces the same output. Justin From lemming at henning-thielemann.de Tue Mar 4 11:28:39 2008 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Tue Mar 4 11:26:17 2008 Subject: [Haskell-cafe] Markup bug in HaskellWiki In-Reply-To: <200803041715.37919.g9ks157k@acme.softbase.org> References: <2d3641330803040710u4b2a2951wbfc84c5f05b0330a@mail.gmail.com> <200803041715.37919.g9ks157k@acme.softbase.org> Message-ID: On Tue, 4 Mar 2008, Wolfgang Jeltsch wrote: > Am Dienstag, 4. M?rz 2008 16:10 schrieb Dougal Stanton: > > [?] > > > There's a file called, IIRC, haskell.php with a large list of > > keywords. Two of them, 'unzip' and 'unzip3' appear twice. Delete one > > of each and it all works fine again. > > Why do they appear at all? They are not keywords. They link to the online Haddock documentation of Prelude. From dougal at dougalstanton.net Tue Mar 4 12:03:59 2008 From: dougal at dougalstanton.net (Dougal Stanton) Date: Tue Mar 4 12:01:33 2008 Subject: [Haskell-cafe] Markup bug in HaskellWiki In-Reply-To: <200803041715.37919.g9ks157k@acme.softbase.org> References: <2d3641330803040710u4b2a2951wbfc84c5f05b0330a@mail.gmail.com> <200803041715.37919.g9ks157k@acme.softbase.org> Message-ID: <2d3641330803040903w424270bck84072070b4e449bd@mail.gmail.com> On 04/03/2008, Wolfgang Jeltsch wrote: > Am Dienstag, 4. M?rz 2008 16:10 schrieb Dougal Stanton: > > [?] > > > > There's a file called, IIRC, haskell.php with a large list of > > keywords. Two of them, 'unzip' and 'unzip3' appear twice. Delete one > > of each and it all works fine again. > > > Why do they appear at all? They are not keywords. Well, keywords is a bit of a misnomer. Geshi isn't very smart, it just recognises the standard prelude and adds in links to the online API. D -- Dougal Stanton dougal@dougalstanton.net // http://www.dougalstanton.net From devriese at cs.tcd.ie Tue Mar 4 12:16:40 2008 From: devriese at cs.tcd.ie (Edsko de Vries) Date: Tue Mar 4 12:14:11 2008 Subject: [Haskell-cafe] Functional programmer's intuition for adjunctions? Message-ID: <20080304171640.GC32511@netsoc.tcd.ie> Hi, Is there an intuition that can be used to explain adjunctions to functional programmers, even if the match isn't necessary 100% perfect (like natural transformations and polymorphic functions?). Thanks, Edsko From chaddai.fouche at gmail.com Tue Mar 4 12:47:27 2008 From: chaddai.fouche at gmail.com (=?ISO-8859-1?Q?Chadda=EF_Fouch=E9?=) Date: Tue Mar 4 12:45:02 2008 Subject: [Haskell-cafe] (flawed?) benchmark : sort In-Reply-To: <220e47b40803031645y3ca02ecbjc745604a2dc2e0b4@mail.gmail.com> References: <220e47b40803031645y3ca02ecbjc745604a2dc2e0b4@mail.gmail.com> Message-ID: 2008/3/4, Krzysztof Skrz?tnicki : > Hi > > I was playing with various versions of sorting algorithms. I know it's very > easy to create flawed benchmark and I don't claim those are good ones. > However, it really seems strange to me, that sort - library function - is > actually the worse measured function. I can hardly belive it, and I'd rather > say I have made a mistake preparing it. > > The overall winner seems to be qsort_iv - which is nothing less but old sort > replaced by mergesort now. > > Any clues? Part of what you may be missing : -- cut here -- module Main where import Control.Parallel.Strategies import Control.Arrow import System.CPUTime import System.IO import System.Environment import System.Random import Data.List( partition, sort ) data Tree a = Node (Tree a) a (Tree a) | Leaf qsort_i [] = [] qsort_i (x:xs) = qsort_i (filter (< x) xs) ++ [x] ++ qsort_i (filter (>= x) xs) qsort_ii [] = [] qsort_ii (x:xs) = let (ls,gt) = partition (< x) xs in qsort_ii ls ++ [x] ++ qsort_ii gt qsort_iii xs = qsort_iii' [] xs qsort_iii' acc [] = acc qsort_iii' acc (x:xs) = let (ls,gt) = partition (< x) xs in let acc' = (x:(qsort_iii' acc gt)) in qsort_iii' acc' ls qsort_v [] = [] qsort_v (x:xs) = let (xlt, xgt ) = foldl (\ (lt,gt) el -> case compare x el of GT -> (el:lt, gt) _ -> (lt, el:gt) ) ([],[]) xs in qsort_v xlt ++ [x] ++ qsort_v xgt -- zmodyfikowany i qsort_vi [] = [] qsort_vi (x:xs) = qsort_vi (filter (\y-> compare x y == GT) xs) ++ [x] ++ qsort_vi (filter (\y-> compare x y /= GT) xs) -- zmodyfikowany iii qsort_vii xs = qsort_vii' [] xs qsort_vii' acc [] = acc qsort_vii' acc (x:xs) = let (ls,gt) = partition (\y-> compare x y == GT) xs in let acc' = (x:(qsort_vii' acc gt)) in qsort_vii' acc' ls -- qsort is stable and does not concatenate. qsort_iv xs = qsort_iv' (compare) xs [] qsort_iv' _ [] r = r qsort_iv' _ [x] r = x:r qsort_iv' cmp (x:xs) r = qpart cmp x xs [] [] r -- qpart partitions and sorts the sublists qpart cmp x [] rlt rge r = -- rlt and rge are in reverse order and must be sorted with an -- anti-stable sorting rqsort_iv' cmp rlt (x:rqsort_iv' cmp rge r) qpart cmp x (y:ys) rlt rge r = case cmp x y of GT -> qpart cmp x ys (y:rlt) rge r _ -> qpart cmp x ys rlt (y:rge) r -- rqsort is as qsort but anti-stable, i.e. reverses equal elements rqsort_iv' _ [] r = r rqsort_iv' _ [x] r = x:r rqsort_iv' cmp (x:xs) r = rqpart cmp x xs [] [] r rqpart cmp x [] rle rgt r = qsort_iv' cmp rle (x:qsort_iv' cmp rgt r) rqpart cmp x (y:ys) rle rgt r = case cmp y x of GT -> rqpart cmp x ys rle (y:rgt) r _ -> rqpart cmp x ys (y:rle) rgt r -- code by Orcus -- Zadanie 9 - merge sort mergeSort :: Ord a => [a] -> [a] mergeSort [] = [] mergeSort [x] = [x] mergeSort xs = let(l, r) = splitAt (length xs `quot` 2) xs in mergeSortP (mergeSort l) (mergeSort r) -- funkcja pomocnicza scalaj??ca dwie listy uporz??dkowane w jedn?? mergeSortP :: Ord a => [a] -> [a] -> [a] mergeSortP xs [] = xs mergeSortP [] ys = ys mergeSortP (x:xs) (y:ys) | x <= y = x:(mergeSortP xs (y:ys)) | otherwise = y:(mergeSortP (x:xs) ys) -- Zadanie 10 - tree sort treeSort :: Ord a => [a] -> [a] -- pointless po raz drugi treeSort = (treeSortInorder . treeSortToTree) treeSortToTree :: Ord a => [a] -> Tree a treeSortToTree [] = Leaf treeSortToTree (x:xs) = let (xlt, xgt) = foldl (\ (lt,gt) el -> case compare x el of GT -> (el:lt, gt) _ -> (lt, el:gt) ) ([],[]) xs in Node (treeSortToTree xlt) x (treeSortToTree xgt) treeSortInorder :: Ord a => Tree a -> [a] treeSortInorder Leaf = [] treeSortInorder (Node l x r) = (treeSortInorder l) ++ [x] ++ (treeSortInorder r) -- end code by Orcus -- begin benchmark making code makeBenchs benchs xs = do let (funcNames, funcs) = unzip benchs tBegin <- getCPUTime timers <- mapM (\f-> print (f xs) >> getCPUTime) funcs let times = zipWith (-) timers (tBegin:timers) sortedResults = sort $ zip times funcNames minT = fromIntegral $ fst $ head sortedResults scaled = map (((/minT) . fromIntegral) *** id) sortedResults hPutStr stderr $ unlines $ map show scaled onRandom eltCnt = do gen <- getStdGen let xs = take eltCnt (randomRs (1::Int, bigNum) gen) `using` rnf xs `seq` return xs onSorted eltCnt = do gen <- getStdGen let xs = take eltCnt (randomRs (1::Int, bigNum) gen) `using` rnf sxs = sort xs `using` rnf xs `seq` sxs `seq` return sxs bigNum = 1000000 :: Int -- end of benchmark making code main = makeBenchs [("i",qsort_i), ("ii",qsort_ii), ("iii",qsort_iii), ("iv",qsort_iv), ("v",qsort_v), ("vi",qsort_vi), ("vii",qsort_vii), ("sort",sort), ("mergeSort",mergeSort), ("treeSort",treeSort)] =<< onSorted . read . head =<< getArgs -- cut here -- It could probably be improved (with classics solution (better selection of the pivot...)), but the mergesort is only 3 times slower in worse case, and much more regular, if someone needs a faster sort in a specific case, it isn't hard to code. -- Jeda? From ndmitchell at gmail.com Tue Mar 4 12:54:21 2008 From: ndmitchell at gmail.com (Neil Mitchell) Date: Tue Mar 4 12:51:51 2008 Subject: [Haskell-cafe] (flawed?) benchmark : sort In-Reply-To: References: <220e47b40803031645y3ca02ecbjc745604a2dc2e0b4@mail.gmail.com> Message-ID: <404396ef0803040954uac20b35ua55aa7510ac07e21@mail.gmail.com> Hi > -- Zadanie 9 - merge sort > mergeSort :: Ord a => [a] -> [a] > mergeSort [] = [] > mergeSort [x] = [x] > mergeSort xs = let(l, r) = splitAt (length xs `quot` 2) xs > in mergeSortP (mergeSort l) (mergeSort r) splitAt is not a particularly good way to split a list, since you recurse over the list twice. Try instead: split (x:xs) = (x:b,a) where (a,b) = split xs split [] = ([], []) Perhaps adding some strictness annotations and turning the where into a case. Also remember that a standard benchmark for sorting is an ordered/reverse ordered list, as that causes quicksort to go to O(n^2) given a bad pivot choice. If the sort in the standard libraries can be improved on, it should be replaced. Thanks Neil From derek.a.elkins at gmail.com Tue Mar 4 12:58:38 2008 From: derek.a.elkins at gmail.com (Derek Elkins) Date: Tue Mar 4 12:56:20 2008 Subject: [Haskell-cafe] Functional programmer's intuition for adjunctions? In-Reply-To: <20080304171640.GC32511@netsoc.tcd.ie> References: <20080304171640.GC32511@netsoc.tcd.ie> Message-ID: <1204653519.5706.13.camel@derek-laptop> On Tue, 2008-03-04 at 17:16 +0000, Edsko de Vries wrote: > Hi, > > Is there an intuition that can be used to explain adjunctions to > functional programmers, even if the match isn't necessary 100% perfect > (like natural transformations and polymorphic functions?). Well when you pretend Hask is Set, many things can be discussed fairly directly. F is left adjoint to U, F -| U, if Hom(FA,B) is naturally isomorphic to Hom(A,UB), natural in A and B. A natural transformation over Set is just a polymorphic function. So we have an adjunction if we have two functions: phi :: (F a -> b) -> (a -> U b) and phiInv :: (a -> U b) -> (F a -> b) such that phi . phiInv = id and phiInv . phi = id and F and U are instances of Functor. The unit and counit respectively is then just phi id and phiInv id. You can work several examples using this framework, though it gets difficult when it is difficult to model other categories. Also discussing and proving some properties of adjunctions (namely continuity properties) would help. Of course, this is a concrete example using basic ideas of programming and not some "intuitive analogy". I feel comfortable working with adjunctions, but I don't have some general analogy that I use. From devriese at cs.tcd.ie Tue Mar 4 13:30:05 2008 From: devriese at cs.tcd.ie (Edsko de Vries) Date: Tue Mar 4 13:28:07 2008 Subject: [Haskell-cafe] Functional programmer's intuition for adjunctions? In-Reply-To: <1204653519.5706.13.camel@derek-laptop> References: <20080304171640.GC32511@netsoc.tcd.ie> <1204653519.5706.13.camel@derek-laptop> Message-ID: <20080304183005.GA29033@netsoc.tcd.ie> On Tue, Mar 04, 2008 at 11:58:38AM -0600, Derek Elkins wrote: > On Tue, 2008-03-04 at 17:16 +0000, Edsko de Vries wrote: > > Hi, > > > > Is there an intuition that can be used to explain adjunctions to > > functional programmers, even if the match isn't necessary 100% perfect > > (like natural transformations and polymorphic functions?). > > Well when you pretend Hask is Set, many things can be discussed fairly > directly. > > F is left adjoint to U, F -| U, if Hom(FA,B) is naturally isomorphic to > Hom(A,UB), natural in A and B. A natural transformation over Set is > just a polymorphic function. So we have an adjunction if we have two > functions: > > phi :: (F a -> b) -> (a -> U b) > and > phiInv :: (a -> U b) -> (F a -> b) > > such that phi . phiInv = id and phiInv . phi = id and F and U are > instances of Functor. > > The unit and counit respectively is then just phi id and phiInv id. Sure, but that doesn't really explain what an adjunction *is*. For me, it helps to think of a natural transformation as a polymorphic function: it gives me an intuition about what a natural transformation is. Specializing the definition of an adjunction for Hask (or Set) helps understanding the *definitions*, but not the *intention*, if that makes any sense.. Edsko From miguelimo38 at yandex.ru Tue Mar 4 13:45:59 2008 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Tue Mar 4 13:43:42 2008 Subject: [Haskell-cafe] Functional programmer's intuition for adjunctions? In-Reply-To: <20080304183005.GA29033@netsoc.tcd.ie> References: <20080304171640.GC32511@netsoc.tcd.ie> <1204653519.5706.13.camel@derek-laptop> <20080304183005.GA29033@netsoc.tcd.ie> Message-ID: <4014B004-2644-43A9-95D0-14508A3454B0@yandex.ru> Well, we have at least one very useful example of adjunction. It's called "curry". See, if X is some arbitrary type, you can define type F = (,X) instance Functor F where fmap f (a,x) = (fa,x) type G = (->) X instance Functor G where fmap f h = \x -> f (h x) Now, we have the adjunction: phi :: ((a,X) -> b) -> (a -> (X -> b)) phi = curry phiInv :: (a -> (X -> b)) -> ((a,X) -> b) phiInv = uncurry On 4 Mar 2008, at 21:30, Edsko de Vries wrote: > On Tue, Mar 04, 2008 at 11:58:38AM -0600, Derek Elkins wrote: >> On Tue, 2008-03-04 at 17:16 +0000, Edsko de Vries wrote: >>> Hi, >>> >>> Is there an intuition that can be used to explain adjunctions to >>> functional programmers, even if the match isn't necessary 100% >>> perfect >>> (like natural transformations and polymorphic functions?). >> >> Well when you pretend Hask is Set, many things can be discussed >> fairly >> directly. >> >> F is left adjoint to U, F -| U, if Hom(FA,B) is naturally >> isomorphic to >> Hom(A,UB), natural in A and B. A natural transformation over Set is >> just a polymorphic function. So we have an adjunction if we have two >> functions: >> >> phi :: (F a -> b) -> (a -> U b) >> and >> phiInv :: (a -> U b) -> (F a -> b) >> >> such that phi . phiInv = id and phiInv . phi = id and F and U are >> instances of Functor. >> >> The unit and counit respectively is then just phi id and phiInv id. > > Sure, but that doesn't really explain what an adjunction *is*. For me, > it helps to think of a natural transformation as a polymorphic > function: > it gives me an intuition about what a natural transformation is. > Specializing the definition of an adjunction for Hask (or Set) helps > understanding the *definitions*, but not the *intention*, if that > makes > any sense.. > > Edsko > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From qdunkan at gmail.com Tue Mar 4 13:52:52 2008 From: qdunkan at gmail.com (Evan Laforge) Date: Tue Mar 4 13:50:23 2008 Subject: [Haskell-cafe] Doubting Haskell In-Reply-To: <7ca3f0160803040344r5f9efad5o38ed9204dba30e8a@mail.gmail.com> References: <56a54d4d0802161405l774ff97djada856fbccdb8b08@mail.gmail.com> <89ca3d1f0802190648s230c67cet40a9612397dd482f@mail.gmail.com> <56a54d4d0802191727h4a2a64a3xcd532ccf86e5a9a@mail.gmail.com> <89ca3d1f0802200158g5f1b884eua5b4ea5634471d9b@mail.gmail.com> <2608b8a80802210523v55dd8588n7b10511a1e25d74a@mail.gmail.com> <56a54d4d0803032229t6b2456c2ka920d99cd8ef377d@mail.gmail.com> <47CD2902.2070608@cogito.org.uk> <87zlte7n8i.fsf@nmd9999.imr.no> <7ca3f0160803040344r5f9efad5o38ed9204dba30e8a@mail.gmail.com> Message-ID: <2518b95d0803041052g882a9edxd1898c6487722323@mail.gmail.com> > Especially if mixing tabs and spaces indeed. Haskell does the Python > thing of assuming that a tab is 8 spaces, which IMO is a mistake. The FWIW, most people in python land think the same thing, and the -t flag makes mixed tabs and spaces a warning or error. At the least, -Wall could report mixed usage. At the most, make it an error. From dominic.steinitz at blueyonder.co.uk Tue Mar 4 14:01:16 2008 From: dominic.steinitz at blueyonder.co.uk (Dominic Steinitz) Date: Tue Mar 4 13:59:00 2008 Subject: [Haskell-cafe] Re: Functional programmer's intuition for adjunctions? References: <20080304171640.GC32511@netsoc.tcd.ie> <1204653519.5706.13.camel@derek-laptop> <20080304183005.GA29033@netsoc.tcd.ie> <4014B004-2644-43A9-95D0-14508A3454B0@yandex.ru> Message-ID: > Well, we have at least one very useful example of adjunction. It's > called "curry". See, if X is some arbitrary type, you can define > This adjunction is the one that makes a category cartesian closed. Dominic. From mlandman at face2interface.com Tue Mar 4 14:06:59 2008 From: mlandman at face2interface.com (Marty Landman) Date: Tue Mar 4 14:04:54 2008 Subject: [Haskell-cafe] Haskell & Perl architecture question Message-ID: <20080304190452.A0499324333@www.haskell.org> I'm looking at a production system running Perl & Haskell in an Apache environment and trying to get a handle on the system architecture. Are there online resources anyone could recommend I start with? Thanks in advance, Marty -- Marty Landman, Face 2 Interface Inc. 845-679-9387 Drupal Development Blog: http://drupal.face2interface.com/ Free Database Search App: http://face2interface.com/Products/FormATable.shtml From dpiponi at gmail.com Tue Mar 4 16:24:34 2008 From: dpiponi at gmail.com (Dan Piponi) Date: Tue Mar 4 16:22:04 2008 Subject: [Haskell-cafe] Functional programmer's intuition for adjunctions? In-Reply-To: <20080304171640.GC32511@netsoc.tcd.ie> References: <20080304171640.GC32511@netsoc.tcd.ie> Message-ID: <625b74080803041324t42d392f8uff4f09c4da9e1df5@mail.gmail.com> Edsko asked: > Is there an intuition that can be used to explain adjunctions to > functional programmers, even if the match isn't necessary 100% perfect > (like natural transformations and polymorphic functions?). I think there's a catch because many interesting examples of adjunctions involve multiple distinct categories. So there's a sense in which you have to go outside of programming to explain what they are, apart from a few simple examples like currying. But if you're familiar with the category of monoids and monoid homomorphisms, then we can generate another example: One intuition is the notion of trying to approximate an object in one category using objects in another. For example, consider the category of monoids. How best can we approximate an arbitrary type in a monoid? Suppose our type, T, has elements a,b and c. We could try to represent this as a monoid. But monoids should have products and an identity. So if the monoid contains a,b and c it should also contain 1, ab, bc, abcba and so on. And what should ab equal? Might it be the same as bc? The simplest strategy is to assume that all of these products are distinct and approximate the type T with the monoid containing 1, a, b and c and assuming no element equals any other unless the monoid laws say so (ie. 1a=a1=a). This is called the *f*ree monoid generated by T, and we can write it F(T). Now go the other way: given a monoid, S, how can we map it back to a type? There's an obvious idea, just make a type whose elements are the *u*nderlying elements of the monoid, discarding the multiplication rule. Call this U(S). (We're treating Hask like Set here.) So what's U(F(T))? T gets mapped to the free monoid generated by T, and mapped back to the elements of this monoid. In other words, the elements of U(F(T)) are (possibly non-empty) strings of elements of T. So UF is the list type constructor. Any homomorphism, f, between monoids is completely determined once you know where a set of generators of the monoid map under the homomorphism, and vice versa. All of the other elements can be deduced using f(1) = 1 and f(xy)=f(x)f(y). So if F(a) is the free monoid generated by a, then a homomorphism F(a)->b is completely determined by a function a->U(b), and vice versa. We have an isomorphism (F(a)->b) <-> (a->U(b)) and (F,U) forms an adjunction, according to Derek's definition. So intuitively, what's going on is that Haskell lists emerge as a result of an attempt to approximate types with monoids and adjunctions formalise what we mean by 'approximation'. When we go from a type, to a monoid, and back again, we don't end up where we started, but at a new type. Other adjunctions can be seen in this way. But because different examples use different categories, it's hard to picture a uniform way of viewing adjunctions that spans them all. It's also no coincidence now that lists form a monad... -- Dan From hjgtuyl at chello.nl Tue Mar 4 17:01:43 2008 From: hjgtuyl at chello.nl (hjgtuyl@chello.nl) Date: Tue Mar 4 16:59:13 2008 Subject: [Haskell-cafe] Doubting Haskell In-Reply-To: <56a54d4d0803032229t6b2456c2ka920d99cd8ef377d@mail.gmail.com> References: <56a54d4d0802161405l774ff97djada856fbccdb8b08@mail.gmail.com> <89ca3d1f0802190648s230c67cet40a9612397dd482f@mail.gmail.com> <56a54d4d0802191727h4a2a64a3xcd532ccf86e5a9a@mail.gmail.com> <89ca3d1f0802200158g5f1b884eua5b4ea5634471d9b@mail.gmail.com> <2608b8a80802210523v55dd8588n7b10511a1e25d74a@mail.gmail.com> <56a54d4d0803032229t6b2456c2ka920d99cd8ef377d@mail.gmail.com> Message-ID: About the line length needed for Haskell programs, there was a discussion about this some time ago, that could be regarded as a tutorial for reducing indentation: http://haskell.org/pipermail/haskell-cafe/2007-July/028787.html As for the idle core you mention: I keep one core fully occupied with a program that searches for a cure against cancer, see: http://www.computeagainstcancer.org/ The example you gave for the use of "map" can be simplified: map func (take (10 [0..])) -- should actually be: map func