[Haskell-cafe] Poor Parsec error message
Hi folks, I'm using Parsec to parse a stream of tokens. The token primitive takes, among other arguments, a function to print tokens. However, this function is not always applied. Try the code below: - import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec.Pos(newPos) mytoken :: (Eq t, Show t) = t - GenParser (SourcePos,t) () t mytoken x = token showTok posFromTok testTok where showTok (pos,t) = ++ show t ++ posFromTok (pos,t) = pos testTok (pos,t) = if (x == t) then Just t else Nothing main = do putStrLn case parse the123Parser [(newPos 1 n, n) | n - [1,2,3,4]] of (Left err) - putStrLn (show err) (Right _) - putStrLn parsed correctly putStrLn case parse the123Parser [(newPos 1 n, n) | n - [1,3,4]] of (Left err) - putStrLn (show err) (Right _) - putStrLn parsed correctly the123Parser = do mytoken 1 mytoken 2 mytoken 3 eof return 123 --- The output I get looks like this: (line 1, column 4): unexpected [((line 1, column 4),4)] expecting end of input (line 1, column 3): unexpected 3 In the second parse case, it correctly uses my showTok function to show the token. But in the first case, it just uses the regular show method. I guess that's because the eof parser doesn't know anything about how to show the token it sees. Any ideas on how I can get the error message in the first case to look more like the second case? Thanks, Lyle ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] use of the GHC universal quantifier
Hi Ryan, Please see below. Vasili On Wed, Jul 9, 2008 at 4:03 AM, Ryan Ingram [EMAIL PROTECTED] wrote: Try {-# LANGUAGE RankNTypes #-}? [EMAIL PROTECTED]:~/FTP/Haskell/hsql-1.7$ runhaskell Setup.lhs build Preprocessing library hsql-1.7... Building hsql-1.7... [1 of 2] Compiling Database.HSQL.Types ( Database/HSQL/Types.hs, dist/build/Database/HSQL/Types.o ) Database/HSQL/Types.hs:67:0: Can't make a derived instance of `Typeable SqlError' (You need -XDeriveDataTypeable to derive an instance for this class) In the data type declaration for `SqlError' forall does denote a universal quantifier, but because the 'implies' of the function arrow, in logic, includes negation, you can use it to emulate existential quantifiers. data Existential = forall a. Ex a The type of the constructor Ex: Ex :: forall a. a - Existential Classical logic opposed to intuitionistic logic? Pattern matching on Ex brings a back into scope (with no information about it, so this type isn't that useful on its own): use (Ex x) = 0 -- can't recover any useful information about x sample = Ex sample However, you can use existential types to encode additional information about the included data; for example: -- Ex2 :: forall a. Show a = a - Exist2 data Exist2 = forall a. Show a = Ex2 a Now, pattern matching on Ex2 brings the Show instance into scope as well: sample2 = Ex2 sample2 use2 (Ex2 x) = show x You can also use higher rank polymorphism to encode existential types: -- Ex3 :: (forall a. (forall b. Show b = b - a) - a) - Exist3 -- note the rank-3 type on Ex3! newtype Exist3 = Ex3 (forall a. (forall b. Show b = b - a) - a) sample3 = Ex3 (\k - k sample3) use3 (Ex3 f) = f (\x - show x) -- ryan 2008/7/8 Galchin, Vasili [EMAIL PROTECTED]: Hello, It seems to me by its name that forall denotes a logical universal quantifier. In any case, hsql-1.7/Database/HSQL/Types.hs uses forall at line #134. I got a nasty build so I added {-# LANGUAGE ExistentialQuantification #-} at the top of the module. Now I get the following a coupleof lines up: Database/HSQL/Types.hs:131:5: Illegal polymorphic or qualified type: forall a. Int - FieldDef - FieldDef - CString - Int - IO a - IO a In the definition of data constructor `Statement' In the data type declaration for `Statement' If seems that GHC doesn't like a. Why? Kind regards, Vasili ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] More idiomatic use of strictness
Hi all, Is there a less ugly way of avoiding laziness in the code pasted below then the use of seq in the last line? The program is supposed to split a large input file into chunks and check in how many of those chunks each of a list of words appear, as well as the total number of chunks. Without the seq it consumes huge amounts of memory. Thanks! Grzegorz {-# LANGUAGE BangPatterns, PatternGuards #-} import Data.List (foldl') split delim s | [] - rest = [token] | otherwise = token : split delim (tail rest) where (token,rest) = span (/=delim) s main = do putStrLn = fmap (show . stats [the,a,and] . split DOC . words) getContents stats ws docs = foldl' f ((map (const 0) ws),0) docs where f (dfs,n) d = let dfs' = zipWith (\w df - (df + fromEnum (w `elem` d))) ws dfs in sum dfs' `seq` (dfs',n+1) -- View this message in context: http://www.nabble.com/More-idiomatic-use-of-strictness-tp18379800p18379800.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] More idiomatic use of strictness
Hi all, Op Thursday 10 July 2008 12:16:25 schreef Grzegorz Chrupala: Is there a less ugly way of avoiding laziness in the code pasted below then the use of seq in the last line? You could replace the list dfs' with a strict list type, like: data StrictList a = Cons !a !(StrictList a) | Nil Then you wouldn't have to make useless calls to sum and seq to force strictness. It would be more work though because you'd have to define your own higher order functions to work with the strict list. Reinier signature.asc Description: This is a digitally signed message part. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FPGA / Lava and haskell
Hi Marc, The Chalmers Lava homepage tells abouta Xilinx version which should be merged in soon. But on the xilinx homepage there was no reference to neither Lava nor haskell.. I'm thinking about designing a similar tool to www.combimouse.com. you also might consider using a PIC or some such microcontroller for this kind of project. I don't think there is a Haskell library for PIC programming, but it would be fun to make one! For somewhat related work, see issues 6 and 7 of The Monad.Reader (http://www.haskell.org/haskellwiki/The_Monad.Reader), especially Russell O'Conner's article. As mentioned in issue 7, I did use Lava to program an RCX microcontroller, but in general the techniques I used are much better suited to hardware. Also, there is PICBIT: A Scheme System for the PIC Microcontroller by Marc Feeley (http://www.iro.umontreal.ca/~feeley/papers/sw03.pdf) which might be of interest. Regarding Lava, there is a version on Satnam Singh's website (http://raintown.org/lava/). I use Emil Axelsson's version of Chalmers Lava (http://www.cs.chalmers.se/~emax/darcs/Lava2000/) that works with the latest GHC. I made some mods to target the Xilinx toolset and to provide very basic support for block RAMs (http://www.cs.york.ac.uk/fp/darcs/reduceron2/Lava2000/). I wish I had time to work more on this, and make it more accessible to others! Nevertheless, Chalmers Lava as it stands is already very usable. It is also very hacker-friendly, so I can recommend diving in! As an aside: I'm currently finishing off a document about my uses of Lava and its capabilities/weaknesses. Hopefully this will be publicly available soon. Matt. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Lazy IO
On Wed, Jul 09, 2008 at 11:05:47PM -0400, Ronald Guida wrote: Question: If I can't change my function f (in this case, accumulator), then is it possible to get the effect I want without having to resort to unsafeInterleaveIO? Here's a possibility; you may or may not like it. module Main where import Control.Concurrent import Control.Concurrent.Chan import Control.Concurrent.MVar import Control.Monad {- promptInt, accumulator, makeAccPrompt as before -} main :: IO () main = do inChan - newChan outMVar - newEmptyMVar forkIO $ (getChanContents inChan) = (mapM_ (putMVar outMVar) . accumulator) let go = do p - takeMVar outMVar m - promptInt (makeAccPrompt p) case m of Just n - do writeChan inChan n ns - go return $ n:ns Nothing - return [] xs - go print xs The unsafeInterleaveIO is now hidden inside getChanContents. (I have an outMVar rather than an outChan just in case accumulator could produce lots of output before consuming much of its input.) Regards, Reid Barton ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Combining Wouter's expressions with extensible records
On Wed, Jul 9, 2008 at 11:01 PM, Antoine Latter [EMAIL PROTECTED] wrote: It isn't immediately obvious to me that the Typeable family of classes deal at all with higher-kinded type constructors, but I didn't look that hard. Yes, that's what I'm worried about. For people's fun and amusement, I've attached the file. The trailing comments show what I'm trying to accomplish (getName, setName, and so forth). -Ron WouterTest.hs Description: Binary data ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Combining Wouter's expressions with extensible records
Or, if people have easy-enough extensible records that /will/ work with funky types, I'd be happy to use those! -Ron On Thu, Jul 10, 2008 at 10:29 AM, Ron Alford [EMAIL PROTECTED] wrote: On Wed, Jul 9, 2008 at 11:01 PM, Antoine Latter [EMAIL PROTECTED] wrote: It isn't immediately obvious to me that the Typeable family of classes deal at all with higher-kinded type constructors, but I didn't look that hard. Yes, that's what I'm worried about. For people's fun and amusement, I've attached the file. The trailing comments show what I'm trying to accomplish (getName, setName, and so forth). -Ron ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Poor Parsec error message
I figured it out, but it's not pretty. The problem is that the eof parser had no awareness of the showTok function. To fix the problem, I had to replace eof with its definition in terms of notFollowedBy, then replace notFollowedBy with its definition in terms of try and unexpected. Then, I changed the show [c] into showToken c. Passing a token shower to the token function isn't a very robust way of guaranteeing your tokens display properly in error messages, because the other combinators don't take the same option. Of course, you can implement a Show instance for your tokens as you like. But, if you make the Show instance show the pretty version for the user, you lose the ability to see the real structure you get from a derived Show instance. In my real code, I want debugging to show tokens using a derived Show instance, so I can see all the structure. But when I show them to the user, I don't want them to see the embedded SourcePos, or the constructor names - I just want them to see a representation of what was lexed in order to produce that token. I think there should be a class called Token, with a method called showToken, or unlex, or display, or displayInError, something like that. This class should be a precondition of all the GenParser combinators. It should use the provided method to show the token in error messages. Here's the working version: import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec.Pos(newPos) showToken (pos,t) = ++ show t ++ myToken :: (Eq t, Show t) = (t - Bool) - GenParser (SourcePos,t) () (SourcePos,t) myToken q = token showToken posFromTok testTok where posFromTok (pos,t) = pos testTok (pos,t) = if (q t) then Just (pos,t) else Nothing main = do putStrLn case parse the123Parser [(newPos 1 n, n) | n - [1,2,3,4]] of (Left err) - putStrLn (show err) (Right _) - putStrLn parsed correctly putStrLn case parse the123Parser [(newPos 1 n, n) | n - [1,3,4]] of (Left err) - putStrLn (show err) (Right _) - putStrLn parsed correctly the123Parser = do myToken (==1) myToken (==2) myToken (==3) try (do{ c - myToken (const True); unexpected (showToken c) } | return ()) notFollowedBy (myToken (==4)) return 123 - Lyle ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Newbie: Appending arrays?
What is the best way to extend array? I would use a list instead of array as it is easy to append, but need to have random access to its elements later. So in fact I need to start with an integer array of size 1. Next I may need to add new elements to this array or modify values of the existing ones. Function: array :: (Ix a) = (a,a) - [(a,b)] - Array a b allows construct an array of a fixed size. How to add more elements to the array later? Thanks! -- Dmitri O. Kondratiev [EMAIL PROTECTED] http://www.geocities.com/dkondr ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Newbie: Appending arrays?
2008/7/10 Dmitri O.Kondratiev [EMAIL PROTECTED]: allows construct an array of a fixed size. How to add more elements to the array later? I can't really answer your question, however I bet that it would require allocating another, bigger array and copying the old elements over, at least from time to time. So you may want to take a look at Data.Sequence[1], supporting O(1) append on both sides and (sort of) O(log i) for accessing the i-th element. [1] http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Sequence.html HTH, -- Felipe. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Profiling nested case
2008/7/9 Mitar [EMAIL PROTECTED]: And it took 15 s. And also the profiling was like I would anticipate. Calculating points coordinates and checking spheres takes almost all time. So any suggestions how could I build a list of objects to check at runtime and still have this third performance? Why this big difference? I think the speed difference really comes from using a list to hold the spheres in your first two examples, to referring to them directly in case statements in your last example. Lists are going to introduce indirections and therefore are slower than referring directly to the values themselves. Maybe you would have better luck using arrays? Template Haskell is also an option - if you want to hard code your scene in another module, TH can turn it into that kind of case statement. Of course, as the scenes get more complex a series of nested cases isn't going to be too effecient. Justin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] More idiomatic use of strictness
On Thu, 2008-07-10 at 03:16 -0700, Grzegorz Chrupala wrote: Hi all, Is there a less ugly way of avoiding laziness in the code pasted below then the use of seq in the last line? The program is supposed to split a large input file into chunks and check in how many of those chunks each of a list of words appear, as well as the total number of chunks. Without the seq it consumes huge amounts of memory. Strategies! Try ((,) $| rnf) dfs' (n + 1) Or (id $| seqPair rnf r0) (dfs', n + 1) But I don't know if that falls within the intended meaning of `less ugly'. jcc {-# LANGUAGE BangPatterns, PatternGuards #-} import Data.List (foldl') split delim s | [] - rest = [token] | otherwise = token : split delim (tail rest) where (token,rest) = span (/=delim) s main = do putStrLn = fmap (show . stats [the,a,and] . split DOC . words) getContents stats ws docs = foldl' f ((map (const 0) ws),0) docs where f (dfs,n) d = let dfs' = zipWith (\w df - (df + fromEnum (w `elem` d))) ws dfs in sum dfs' `seq` (dfs',n+1) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Existential quantification problem
Hello, how do I unbox a existential quantificated data type? {-# LANGUAGE ExistentialQuantification #-} data L a = forall l. L (l a) unboxL (L l) = l is giving me, in GHC: Inferred type is less polymorphic than expected Quantified type variable `l' escapes When checking an existential match that binds l :: l t The pattern(s) have type(s): L t The body has type: l t In the definition of `unboxL': unboxL (L l) = l Thanks. -- Marco Túlio Gontijo e Silva Página: http://marcotmarcot.googlepages.com/ Blog: http://marcotmarcot.blogspot.com/ Correio: [EMAIL PROTECTED] XMPP: [EMAIL PROTECTED] IRC: [EMAIL PROTECTED] Telefone: 25151920 Celular: 98116720 Endereço: Rua Turfa, 639/701 Prado 30410-370 Belo Horizonte/MG Brasil ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Trying to install cabal
Dear all, I have downloaded cabal and am trying to install it but have gotten the following error message: C:\cabal\cabal-install-0.5.1runghc Setup configure Configuring cabal-install-0.5.1... Setup: At least the following dependencies are missing Cabal =1.41.5, HTTP =30003002, zlib =0.4 I'm not sure from this message what packages I need to install to get cabal up and running. Can anyone help? Eric M. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Existential quantification problem
On Thu, 2008-07-10 at 14:53 -0300, Marco Túlio Gontijo e Silva wrote: Hello, how do I unbox a existential quantificated data type? You can't. You have to use case analysis: case foo of L l - whatever you wanted to do where none of the information your case analysis discovers about the actual type of l can be made available outside of the scope of the case expression. (It can't `escape'). This is required for decidable static typing, IIRC. jcc {-# LANGUAGE ExistentialQuantification #-} data L a = forall l. L (l a) unboxL (L l) = l is giving me, in GHC: Inferred type is less polymorphic than expected Quantified type variable `l' escapes When checking an existential match that binds l :: l t The pattern(s) have type(s): L t The body has type: l t In the definition of `unboxL': unboxL (L l) = l Thanks. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] More idiomatic use of strictness
jonathanccast: On Thu, 2008-07-10 at 03:16 -0700, Grzegorz Chrupala wrote: Hi all, Is there a less ugly way of avoiding laziness in the code pasted below then the use of seq in the last line? The program is supposed to split a large input file into chunks and check in how many of those chunks each of a list of words appear, as well as the total number of chunks. Without the seq it consumes huge amounts of memory. Strategies! Try ((,) $| rnf) dfs' (n + 1) Or (id $| seqPair rnf r0) (dfs', n + 1) But I don't know if that falls within the intended meaning of `less ugly'. I'd use a strict pair and the rnf strategy. data P = P [Something] !Int rnf dfs' (P dfs' (n+1) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Trying to install cabal
eeoam: Dear all, I have downloaded cabal and am trying to install it but have gotten the following error message: C:\cabal\cabal-install-0.5.1runghc Setup configure Configuring cabal-install-0.5.1... Setup: At least the following dependencies are missing Cabal =1.41.5, HTTP =30003002, zlib =0.4 I'm not sure from this message what packages I need to install to get cabal up and running. Can anyone help? All Haskell packages of good repute live on hackage.haskell.org. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Cabal http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HTTP http://hackage.haskell.org/cgi-bin/hackage-scripts/package/zlib ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Trying to install cabal
Hello Eric. Em Qui, 2008-07-10 às 19:00 +0100, Eric escreveu: C:\cabal\cabal-install-0.5.1runghc Setup configure Configuring cabal-install-0.5.1... Setup: At least the following dependencies are missing Cabal =1.41.5, HTTP =30003002, zlib =0.4 I'm not sure from this message what packages I need to install to get cabal up and running. Can anyone help? You can get these listed packages (Cabal, HTTP and zlib) in Hackage ( http://hackage.haskell.org/ ). Greetings. -- Marco Túlio Gontijo e Silva Página: http://marcotmarcot.googlepages.com/ Blog: http://marcotmarcot.blogspot.com/ Correio: [EMAIL PROTECTED] XMPP: [EMAIL PROTECTED] IRC: [EMAIL PROTECTED] Telefone: 25151920 Celular: 98116720 Endereço: Rua Turfa, 639/701 Prado 30410-370 Belo Horizonte/MG Brasil ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Existential quantification problem
On Thursday 10 July 2008, Marco Túlio Gontijo e Silva wrote: Hello, how do I unbox a existential quantificated data type? {-# LANGUAGE ExistentialQuantification #-} data L a = forall l. L (l a) unboxL (L l) = l is giving me, in GHC: Inferred type is less polymorphic than expected Quantified type variable `l' escapes When checking an existential match that binds l :: l t The pattern(s) have type(s): L t The body has type: l t In the definition of `unboxL': unboxL (L l) = l You don't. Or, at least, you don't do it that way. The point of an existential is that the quantified type is 'forgotten', and there's no way to get it back. That's good for abstraction, in that it restricts you to using some provided interface that's guaranteed to work with the forgotten type, but it means that you can't just take things out of the existential box. Instead, you have to use them in ways that make the forgotten type irrelevant (that is, ways that are parametric in the corresponding type). The type of the unboxL function in a type system with first-class existentials is something like: unboxL :: L a - (exists l. l a) Of course, GHC doesn't do first-class existentials, otherwise you'd probably not be bothering with the datatype in the first place. :) The proper way to eliminate an existential is (as mentioned above) with a universal: elim :: (exists l. l a) - (forall l. l a - r) - r elim e f = f e Or, since existentials in GHC are restricted to data types: elim :: L a - (forall l. l a - r) - r elim (L e) f = f e Of course, as has already been noted, elim foo (\l - stuff) is equivalent to: case foo of L l - stuff and doesn't need rank-2 polymorphism enabled, to boot. :) -- Dan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Architecturally flawed
OK, so I just spent an entire day trying to write some code, and after hours of struggling I have something that's semi-working but very ugly and rather unreliable. My usual guideline for Haskell programming is if it seems hard, you're doing it wrong... After many hours of effort, I came up with these: data Writer x instance Monad Writer run_writer :: Writer () - ByteString write1 :: Bool - Writer () write8 :: Word8 - Writer () write16 :: Word16 - Writer () write32 :: Word32 - Writer () write64 :: Word64 - Writer () writeN :: Word8 - Word32 - Writer () data Reader x instance Monad Reader run_reader :: Reader x - ByteString - x is_EOF :: Reader Bool read1 :: Reader Bool read8 :: Reader Word8 read16 :: Reader Word16 read32 :: Reader Word32 read64 :: Reader Word64 readN :: Word8 - Reader Word32 Notice that, unlike the Binary package, all of these are bit-aligned rather than byte-aligned. This is what took so much effort. I strived to make each operation as efficient as possible - by performing as few steps as possible. It would have been *far* easier to, say, implement read8 by calling read1 eight times and then packing the bits back into a byte. But that wouldn't be very fast. So actually read8 reads a pair of bytes, bit-shifts them as required, and then ANDs them together. And so on. (Note that the Writer monad uses Data.Binary.Builder (only) from the Binary package. I assume this is more efficient...) I even sat down and wrote a battery of QuickCheck properties because - as you can imagine - there's a hell of a lot to go wrong here! After many hours, I managed to get it to pass all tests... Next I decided to write an LZW compressor. Here's what I came up with: data EncodeLZW symbol eLZW_start :: (Ord symbol) = EncodeLZW symbol eLZW_encode :: (Ord symbol) = EncodeLZW symbol - symbol - Writer (EncodeLZW symbol) eLZW_end :: (Ord symbol) = EncodeLZW symbol - Writer () data DecodeLZW symbol dLZW_start :: DecodeLZW symbol dLZW_decode :: DecodeLZW symbol - Reader (DecodeLZW symbol, symbol) So each step of the encoder (possibly) writes some bits, and also returns a new encoder state. The decoder is similar. (At least one program bug was caused by the wrong version of the state being used somewhere!) Then I tried to run the code, and oh look, there's a bug somewhere. Emphasis somewhere. At this point I have several KB of code and no idea how in hell to test it. What I *want* to do is single-step through the encoder algorithm, watch it write bits out and update state, and then single-step through the decoder watching it read bits in and update its state, etc. But I can't. All the encoder does is return a giant Writer object which you can't look inside, only run. And likewise for the decoder. I could try GHC's new debugger. But my experiences with it so far have shown that for all but the most trivial programs possible, it becomes intractably difficult to figure out what the debugger is actually showing you. I actually tried to debug a normal LZW implementation once - one that didn't involve two highly convoluted custom monads and a stateful execution model with manually threaded state. This is *not* my idea of a fun time... In a normal programming language, at this point you would sprinkle a few print statements around so you can see the intermediate steps the program is taking. But I can't. I'm in the wrong monad. Curses! In the end, the only solution I could come up with was to design a second, hacked version of the two monads. Instead of importing one module, you import another that provides the same interface. However, now Reader and Writer are aliases to IO. All write requests cause pretty-printed binary to be sent to stdout, and all read requests pop up a prompt for input from stdin. It worked reasonably well in that I could now add the vitally necessary print statements, and see intermediate values and so forth... It wasn't very pretty though. At this point I decided that lugging 5 individual functions around was silly, and I should write a class: class Encoder e where encoder_start :: e x encode :: e x - x - Writer (e x) encoder_end :: e x - Writer () class Decoder d where decoder_start :: d x decode :: d x - Reader (d x, x) 10 points to the first person to spot the fatal flaw in this plan... Yep, that's right. The type system won't accept this. The reason? x needs an Ord context. If you turn on multi-parameter type classes *and* flexible instances, apparently this works: class Encoder e x where... instance (Ord x) = Encoder EncodeLZW x where... (I haven't tried but I *presume* it means what I think it does...) Alternatively, you can avoid using dangerous type system extensions and just write class Encoder e where encode :: (Symbol x) = e x - x - Writer (e x) ... and make Symbol encompass everything any possible encoder could want. (In reality, x is almost always Word8 or
Re: [Haskell-cafe] Existential quantification problem
On Thu, 10 July 2008, Marco Túlio Gontijo e Silva wrote: how do I unbox a existential quantificated data type? Dan Doel wrote: elim :: L a - (forall l. l a - r) - r elim (L e) f = f e Just one catch: You can't actually write a function 'f' of type (forall l. l a - r) without knowing something about the forgotten type of l. One way to deal with this is by restricting the type of l in the data declaration. For example, you could restrict it to the typeclass Foldable, and then you have access to the methods of that typeclass. \begin{code} {-# LANGUAGE ExistentialQuantification #-} module Main where import qualified Data.Foldable as F data L a = forall l. (F.Foldable l) = L (l a) toList :: L a - [a] toList (L x) = F.foldr (:) [] x main :: IO () main = do let x = L [1..10] print $ toList x \end{code} See also http://www.haskell.org/haskellwiki/Existential_type ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Architecturally flawed
andrewcoppin: I could try GHC's new debugger. But my experiences with it so far have shown that for all but the most trivial programs possible, it becomes intractably difficult to figure out what the debugger is actually showing you. I actually tried to debug a normal LZW implementation once - one that didn't involve two highly convoluted custom monads and a stateful execution model with manually threaded state. This is *not* my idea of a fun time... For what its worth, people are using this at work on large projects happily. In a normal programming language, at this point you would sprinkle a few print statements around so you can see the intermediate steps the program is taking. But I can't. I'm in the wrong monad. Curses! Use Debug.Trace.trace. In the end, the only solution I could come up with was to design a second, hacked version of the two monads. Instead of importing one module, you import another that provides the same interface. However, now Reader and Writer are aliases to IO. All write requests cause pretty-printed binary to be sent to stdout, and all read requests pop up a prompt for input from stdin. It worked reasonably well in that I could now add the vitally necessary print statements, and see intermediate values and so forth... It wasn't very pretty though. You should have used Debug.Trace. So at least I got that part fixed. Heh. But now I find myself worrying about yet *another* problem: is Writer lazy enough? I mean, the idea is that you can write a program that lazily reads from a file, pushes it through a Writer, and lazily writes the result back to another file. The thing should chug along reasonably fast and use a constant amount of RAM. But all this is only true of Writer is actually lazy enough. I have a horrible feeling that all the complicated Origami inside makes it too strict. And I have no way to check! Actually, you can use 'chasingBottoms' to write QuickCheck properties that state your expected laziness or strictness behaviour. Actually, thinking about it, is Reader lazy enough? You call run_reader and it hands over your data, but if that data is, say, a list, will run_reader build the entire damn list before it'll hand it over? Or will the monadic code by called as-needed to generate the list elements? Obviously I desire the latter, but I'm really not sure what the actual behaviour is... The mtl Reader class is lazy. In summary, I've spent several days coding, and I still don't have a single algorithm working. I've spent all my time wrestling with the mundane details of infrastructure rather than the interesting algorithms I actually set out to implement. This makes me very sad. :-( You should have stopped by #haskell a few days ago. If anybody can think of a better set of abstractions or another way to do debugging, I'd be interested to hear about it. There's already a bit layer for Data.Binary on hackage, for what its worth. And an LZW encoder/decoder. (This would all be so trivial in an OO language. Just make an Encoder object that updates its own state internally and talks to a Source object and a Destination object for its data...) Make an Encoder class that updates its own state internally and lazy streams input and output. As Data.Binary does, as zlib does, et al. -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Newbie: Appending arrays?
Two questions. How often does the array change, and how big does it get? It may well be that you just copy it and take the hit, as that'll be cheaper (even in C, incidentally) than any other solution, if it's a short array or if the updates happen rarely. If not, try using Data.Array.Diff and replaceDiffArray. This is usually fairly efficient for most applications. By the way, depending on the type of the data you're putting into these arrays, Data.ByteString might be a good choice as well. On Thu, Jul 10, 2008 at 12:12 PM, Felipe Lessa [EMAIL PROTECTED] wrote: 2008/7/10 Dmitri O.Kondratiev [EMAIL PROTECTED]: allows construct an array of a fixed size. How to add more elements to the array later? I can't really answer your question, however I bet that it would require allocating another, bigger array and copying the old elements over, at least from time to time. So you may want to take a look at Data.Sequence[1], supporting O(1) append on both sides and (sort of) O(log i) for accessing the i-th element. [1] http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Sequence.html HTH, -- Felipe. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- I try to take things like a crow; war and chaos don't always ruin a picnic, they just mean you have to be careful what you swallow. -- Jessica Edwards ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Data.Derive problems
I'm using GHC 6.8.3 with $ cabal --version cabal-install version 0.5.1 using version 1.4.0.1 of the Cabal library I installed Data.Derive from hackage, only to be unable to find the 'derive' binary! Trying it directly from darcs, I get: $ ghc --make Setup.hs [1 of 1] Compiling Main ( Setup.hs, Setup.o ) Linking Setup ... silverback-wired:derive ronwalf$ ./Setup configure Warning: defaultUserHooks in Setup script is deprecated. Configuring derive-0.1.1... Warning: No 'build-type' specified. If you do not need a custom Setup.hs or ./configure script then use 'build-type: Simple'. -Ron ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Combining Wouter's expressions with extensible records
I'm making progress, but how would I make the following a Typeable instance: data (f :+: g) e = Inl (f e) | Inr (g e) deriving Eq Here is what I'm using for Expr: data Expr f = In (f (Expr f)) instance Typeable1 f = Typeable (Expr f) where typeOf (In x) = mkTyConApp (mkTyCon Data.Trie.General.ListGT) [typeOf1 x] I don't think I can use this for ':+:', because the typeOf instance only has access to a member of one type at a time. This may be similar to a definition of Typeable2 for Either, but I can't find an example to follow for that. Thanks, -Ron On Wed, Jul 9, 2008 at 10:40 PM, Ron Alford [EMAIL PROTECTED] wrote: Well, my extension of Wouter's datatypes proved to be unweildy So, I'm trying to use http://fmapfixreturn.wordpress.com/2008/05/03/simple-extensible-records-now-quick-generic-tricks-pt-1/ for extensible records. I ran across my first problem rather quickly! data Expr f = In (f (Expr f)) Ok, but to make it part of a record, it needs to implement Data: data Expr f = In (f (Expr f)) deriving Data but this gives No instances for (Data (f (Expr f)), Typeable (Expr f)) arising from the 'deriving' clause of a data type declaration at Planning/Wouter.hs:77:0-42 Any hints? Thanks, -Ron ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Data.Derive problems
Hi Ron, I'm using GHC 6.8.3 with $ cabal --version cabal-install version 0.5.1 using version 1.4.0.1 of the Cabal library I installed Data.Derive from hackage, only to be unable to find the 'derive' binary! Did you do the runhaskell Setup configure runhaskell Setup build runhaskell Setup install? You may also need to add the install path to your $PATH variable - do -v when running Setup install to see where it goes. Thanks Neil ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Architecturally flawed
I have a similar piece of code at http://code.haskell.org/gmap/serial/ which is fairly well tested. It currently only outputs lists of words but its based on Data.Binary so it should be fairly easy to get bytestrings out it (bytestrings worked up till 2-3 weeks ago, I just havent bothered to keep the byestring part up to date).I dont yet know how fast it is but I will be tweaking it over the next month or so. Jamie ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Data.Derive problems
On Thu, Jul 10, 2008 at 3:18 PM, Neil Mitchell [EMAIL PROTECTED] wrote: Hi Ron, I'm using GHC 6.8.3 with $ cabal --version cabal-install version 0.5.1 using version 1.4.0.1 of the Cabal library I installed Data.Derive from hackage, only to be unable to find the 'derive' binary! Did you do the runhaskell Setup configure runhaskell Setup build runhaskell Setup install? I used 'sudo cabal install derive'. I did find the binary - in my user's .cabal/bin directory! Odd that it should default to that when run as root. I don't have the darcs version working yet, though. -Ron ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Data.Derive problems
On 10 Jul 2008, at 21:25, Ron Alford wrote: On Thu, Jul 10, 2008 at 3:18 PM, Neil Mitchell [EMAIL PROTECTED] wrote: Hi Ron, I'm using GHC 6.8.3 with $ cabal --version cabal-install version 0.5.1 using version 1.4.0.1 of the Cabal library I installed Data.Derive from hackage, only to be unable to find the 'derive' binary! Did you do the runhaskell Setup configure runhaskell Setup build runhaskell Setup install? I used 'sudo cabal install derive'. I did find the binary - in my user's .cabal/bin directory! Odd that it should default to that when run as root. I don't have the darcs version working yet, though. I've found that cabal install doesn't actually install anything on my system either, despite going through all the motions. I just download the tarballs of hackage and config/build/install them myself, and I then end up with all the relevant bits installed. Bob ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Data.Derive problems
Hi Did you do the runhaskell Setup configure runhaskell Setup build runhaskell Setup install? I used 'sudo cabal install derive'. I did find the binary - in my user's .cabal/bin directory! Odd that it should default to that when run as root. I think if you pass --global as a flag it will appear somewhere more sensible. I don't have the darcs version working yet, though. What is the problem? The message you gave from runhaskell Setup configure was merely a warning, and it should continue to work fine if you build/install it. Thanks Neil ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Template Haskell and haskell-src-exts
Hi, Can one represent the ''Type template Haskell syntax of $( makeMergeable ''FileDescriptorProto ) in haskell-src.exts Language.Haskell.Exts.Syntax ? And what are the HsReify data (e.g. HsReifyType and HsReifyDecl and HsReifyFixity )? I don't see any pretty print capability to produce the ''Type so I am wondering what else I might use... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Combining Wouter's expressions with extensible records
On Thu, Jul 10, 2008 at 2:15 PM, Ron Alford [EMAIL PROTECTED] wrote: I'm making progress, but how would I make the following a Typeable instance: data (f :+: g) e = Inl (f e) | Inr (g e) deriving Eq Here is what I'm using for Expr: data Expr f = In (f (Expr f)) instance Typeable1 f = Typeable (Expr f) where typeOf (In x) = mkTyConApp (mkTyCon Data.Trie.General.ListGT) [typeOf1 x] I don't think I can use this for ':+:', because the typeOf instance only has access to a member of one type at a time. This may be similar to a definition of Typeable2 for Either, but I can't find an example to follow for that. Maybe something like: instance (Typeable1 f, Typeable1 g) = Typeable (f :+: g) where typeOf in@(InL f) = (some function of 'f' and 'g') where InR g = undefined `asTypeOf` in typeOf in@(InR g) = (some function of 'f' and 'g') where InL f = undefined `asTypeOf` in would work? -Antoine ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Template Haskell and haskell-src-exts
Hello, I am not sure about the full answer to your qusetion, but I do know that template haskell support in haskell-src-exts is currently broken, but supposedly easy to fix. Not sure if that will give you the features you need or not though. From this thread: http://groups.google.com/group/haskell-server-pages/browse_thread/thread/c2a44d1445b66d35 -- It would be really nice if trhsx could parse files that have template haskell in them. It would simplify using happs-hsp-template a bit. Right, there's an open bug in haskell-src-exts for that. There used to be working support for TH, but the syntax was changed for 6.4 iirc and haskell-src-exts was never updated to fix that. It should be rather easy though, I'll have a look when I get some time over. -- j. At Thu, 10 Jul 2008 20:47:34 +0100, ChrisK wrote: Hi, Can one represent the ''Type template Haskell syntax of $( makeMergeable ''FileDescriptorProto ) in haskell-src.exts Language.Haskell.Exts.Syntax ? And what are the HsReify data (e.g. HsReifyType and HsReifyDecl and HsReifyFixity )? I don't see any pretty print capability to produce the ''Type so I am wondering what else I might use... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Inductive graphs memory usage
Hello I'm trying to create a directed graph using the Data.Graph.Inductive. The graph is a random graph using the G(n, p) model, that is, each of the n nodes is linked to every other node with probability p. I'm seeing a large increase of memory usage when n grows (this is using p = 0.1): n = 1000 - 96MB n = 2000 - 283MB n = 3000 - 760MB So, I'm probably doing something very stupid :) The code is below. Is there anything I could do to optimize memory usage here? module Main where import Control.Monad import Data.Graph.Inductive import System.Random createEdges :: Int - Double - IO [LEdge Int] createEdges n prob = foldM create [] [1..n] where create es i = foldM (flip $ link i) es [i, i-1 .. 1] link i j es | i == j= return es -- no self-loops | otherwise = do es' - maybeCreateEdge i j prob es es'' - maybeCreateEdge j i prob es' return es'' maybeCreateEdge :: Node - Node - Double - [LEdge Int] - IO [LEdge Int] maybeCreateEdge i j prob es = do r - randomDouble return $ if r prob then (i, j, 0):es else es randomDouble :: IO Double randomDouble = getStdRandom $ random main :: IO () main = do let (n, p) = (3000, 0.1) es - createEdges n p let g = mkGraph [(i, 0) | i - [1..n]] es :: Gr Int Int return () Thanks, Andre ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Inductive graphs memory usage
On Thu, Jul 10, 2008 at 4:57 PM, Andre Nathan [EMAIL PROTECTED] wrote: Hello I'm trying to create a directed graph using the Data.Graph.Inductive. The graph is a random graph using the G(n, p) model, that is, each of the n nodes is linked to every other node with probability p. So the average degree of a single node is p * n, and the expected number of edges in the entire graph will grow as O(n ^2). I'm seeing a large increase of memory usage when n grows (this is using p = 0.1): n = 1000 - 96MB n = 2000 - 283MB n = 3000 - 760MB So, I'm probably doing something very stupid :) Your ratios are about 1 : 3 : 8. That pretty close to quadratic growth, 1 : 4 : 9, so I think all is well. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Combining Wouter's expressions with extensible records
Close - it compiles now! I made a minor change, going to Typeable1 instead of Typeable: instance (Typeable1 f, Typeable1 g) = Typeable1 (f :+: g) where typeOf1 l@(Inl x) = mkTyConApp (mkTyCon Planning.Wouter.:+:) [typeOf1 x, typeOf1 y] where (Inr y) = undefined `asTypeOf` l typeOf1 r@(Inr y) = mkTyConApp (mkTyCon Planning.Wouter.:+:) [typeOf1 x, typeOf1 y] where (Inl x) = undefined `asTypeOf` r Except this gives me a runtime error: *WouterTest getName testNamed *** Exception: Prelude.undefined The only thing I can think of is to have a class that gives default values to type - ick! -Ron Alford On Thu, Jul 10, 2008 at 4:16 PM, Antoine Latter [EMAIL PROTECTED] wrote: On Thu, Jul 10, 2008 at 2:15 PM, Ron Alford [EMAIL PROTECTED] wrote: I'm making progress, but how would I make the following a Typeable instance: data (f :+: g) e = Inl (f e) | Inr (g e) deriving Eq Here is what I'm using for Expr: data Expr f = In (f (Expr f)) instance Typeable1 f = Typeable (Expr f) where typeOf (In x) = mkTyConApp (mkTyCon Data.Trie.General.ListGT) [typeOf1 x] I don't think I can use this for ':+:', because the typeOf instance only has access to a member of one type at a time. This may be similar to a definition of Typeable2 for Either, but I can't find an example to follow for that. Maybe something like: instance (Typeable1 f, Typeable1 g) = Typeable (f :+: g) where typeOf in@(InL f) = (some function of 'f' and 'g') where InR g = undefined `asTypeOf` in typeOf in@(InR g) = (some function of 'f' and 'g') where InL f = undefined `asTypeOf` in would work? -Antoine WouterTest.hs Description: Binary data ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Combining Wouter's expressions with extensible records
This is a bit similar to Either. Is there a way to see the generated instance code for deriving instance Data Either ? On Thu, Jul 10, 2008 at 6:38 PM, Ron Alford [EMAIL PROTECTED] wrote: Close - it compiles now! I made a minor change, going to Typeable1 instead of Typeable: instance (Typeable1 f, Typeable1 g) = Typeable1 (f :+: g) where typeOf1 l@(Inl x) = mkTyConApp (mkTyCon Planning.Wouter.:+:) [typeOf1 x, typeOf1 y] where (Inr y) = undefined `asTypeOf` l typeOf1 r@(Inr y) = mkTyConApp (mkTyCon Planning.Wouter.:+:) [typeOf1 x, typeOf1 y] where (Inl x) = undefined `asTypeOf` r Except this gives me a runtime error: *WouterTest getName testNamed *** Exception: Prelude.undefined The only thing I can think of is to have a class that gives default values to type - ick! -Ron Alford On Thu, Jul 10, 2008 at 4:16 PM, Antoine Latter [EMAIL PROTECTED] wrote: On Thu, Jul 10, 2008 at 2:15 PM, Ron Alford [EMAIL PROTECTED] wrote: I'm making progress, but how would I make the following a Typeable instance: data (f :+: g) e = Inl (f e) | Inr (g e) deriving Eq Here is what I'm using for Expr: data Expr f = In (f (Expr f)) instance Typeable1 f = Typeable (Expr f) where typeOf (In x) = mkTyConApp (mkTyCon Data.Trie.General.ListGT) [typeOf1 x] I don't think I can use this for ':+:', because the typeOf instance only has access to a member of one type at a time. This may be similar to a definition of Typeable2 for Either, but I can't find an example to follow for that. Maybe something like: instance (Typeable1 f, Typeable1 g) = Typeable (f :+: g) where typeOf in@(InL f) = (some function of 'f' and 'g') where InR g = undefined `asTypeOf` in typeOf in@(InR g) = (some function of 'f' and 'g') where InL f = undefined `asTypeOf` in would work? -Antoine ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Trying to install cabal
On 2008 Jul 10, at 14:00, Eric wrote: I have downloaded cabal and am trying to install it but have gotten the following error message: C:\cabal\cabal-install-0.5.1runghc Setup configure Cabal itself is a special case; you need the same version of Cabal already installed to install it via Cabal... Just run make to bootstrap it, IIRC. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Inductive graphs memory usage
On Thu, 2008-07-10 at 18:32 -0400, Ronald Guida wrote: Your ratios are about 1 : 3 : 8. That pretty close to quadratic growth, 1 : 4 : 9, so I think all is well. Maybe, but 96MB of resident memory for a 1000-node graph looks bad, especially considering p is low. Is the internal representation of inductive graphs perhaps not very memory-efficient? I still haven't read Erwig's paper... I know this is probably not fair, but I'm comparing these numbers with a C implementation which uses Ruby's C API for its complex data structures, and a 10,000 nodes graph uses around 6MB of memory. Thanks, Andre ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Inductive graphs memory usage
andre: On Thu, 2008-07-10 at 18:32 -0400, Ronald Guida wrote: Your ratios are about 1 : 3 : 8. That pretty close to quadratic growth, 1 : 4 : 9, so I think all is well. Maybe, but 96MB of resident memory for a 1000-node graph looks bad, especially considering p is low. Is the internal representation of inductive graphs perhaps not very memory-efficient? I still haven't read Erwig's paper... I know this is probably not fair, but I'm comparing these numbers with a C implementation which uses Ruby's C API for its complex data structures, and a 10,000 nodes graph uses around 6MB of memory. Well, they're radically different graph representations, and fgl hasn't been designed for large graphs. What C library is Ruby's binding to? It might be quite cheap to bind to that. I've been on the look out for a good C graph lib to use for Haskell bindings for a while.. -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Inductive graphs memory usage
On Thu, 2008-07-10 at 16:52 -0700, Don Stewart wrote: Well, they're radically different graph representations, and fgl hasn't been designed for large graphs. Do you know if King and Launchbury's implementation (Data.Graph) scales better? What C library is Ruby's binding to? It might be quite cheap to bind to that. I've been on the look out for a good C graph lib to use for Haskell bindings for a while.. None. I've built my own representing the graph as a hash table with nodes as keys and arrays of nodes as values, and I'm using ruby's hash and array classes (which are written in C) for that. Did you have a look at igraph [http://cneurocvs.rmki.kfki.hu/igraph/]? It would probably be a lot of work to bind to it (it has many public functions), but it looks nice and has bindings for a few languages. Andre ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
GHCi Debugger (was Re: [Haskell-cafe] Architecturally flawed)
I could try GHC's new debugger. But my experiences with it so far have shown that for all but the most trivial programs possible, it becomes intractably difficult to figure out what the debugger is actually showing you. GDB is to C as (a) GHCi debugger :: Haskell (b) Pigs :: Farmers (c) Food :: TomMD (d) None of the above Hint: Its not (a). The GHCi debugger seems to catch extra flack because people want to pour through their Haskell code as they do imperative code. I can sympathize - I would like to do that too - but it would be an inaccurate picture of the programs execution. so long as you regard the GHCi as a new/useful tool and not try to pretend its like other debuggers you'll probably be happier. I've found ghcid to be useful when quickcheck + HPC + ChasingBottoms fails to narrow down the problem any further. Its gotten to the point where I often know exactly which LOC/module will be the next step (based on knowledge of the data dependencies). A fair share of bugs have fallen to the sword named vim as a result :-). It really is useful, but like all other haskellisms, one must learn to ride a bike all over again. At times I think of ghcid as the anti-gdb. If there's a series of let bindings, each mutating the predecessor, its enjoyable to see the debugger start at the bottom and crawl its way back up. Tom ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Combining Wouter's expressions with extensible records
Ok, I'm closer, but I'm running into a problem with typeOf and lists, of all things: *WouterTest typeOf (eVar v :: TermExpr) Planning.Wouter.Expr (Planning.Wouter.:+: WouterTest.Const WouterTest.Var) *WouterTest typeOf ([eVar v] :: [TermExpr]) *** Exception: Prelude.undefined I'm pretty sure this is the culprit for getName: *WouterTest getName testNamed *** Exception: Prelude.undefined Any hints? Also, anyone have hints for how to get automatic derivation of Data (Expr f) ? I don't want to proliferate the last lines: deriving instance Data (Expr (And :+: Atomic (Expr (Const :+: Var deriving instance Data (Expr (Const :+: Var)) -Ron Alford WouterTest.hs Description: Binary data ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: HPC for debugging (Was Re: GHCi Debugger
thomas.dubuisson: I could try GHC's new debugger. But my experiences with it so far have shown that for all but the most trivial programs possible, it becomes intractably difficult to figure out what the debugger is actually showing you. At times I think of ghcid as the anti-gdb. If there's a series of let bindings, each mutating the predecessor, its enjoyable to see the debugger start at the bottom and crawl its way back up. I'd like to relate a debugging effort this week. A colleague had an exception thrown from deep within a large body of code, we knew not where. A few trace statements didn't yield much information. The debugger was fired up on this 50 module program, and we got a few interesting hints and pieces, but it seemed as if the exception was floating away from its call site, to the point it was being demanded. Hmm. A puzzle. So instead we compiled the application with -fhpc, ran it till the exception occured, and then ran hpc markup on the result. (This marks up the program source in colours showing what code was actually executed during a given program run). Loading the colourised trace into firefox, we saw at a glance all the code that had been executed up to the point of the exception, and then there was the exception itself, staring at us amongst a chunk of bright yellow code, a lone streak of uncoloured code where it shouldn't have been. It took all of 5 seconds to find the bug with HPC. -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: HPC for debugging (Was Re: GHCi Debugger
On Thu, 10 Jul 2008, Don Stewart wrote: thomas.dubuisson: I could try GHC's new debugger. But my experiences with it so far have shown that for all but the most trivial programs possible, it becomes intractably difficult to figure out what the debugger is actually showing you. At times I think of ghcid as the anti-gdb. If there's a series of let bindings, each mutating the predecessor, its enjoyable to see the debugger start at the bottom and crawl its way back up. I'd like to relate a debugging effort this week. A colleague had an exception thrown from deep within a large body of code, we knew not where. Let me relate this to the Extensible Exception thread of the Haskell-Library list. Your exception - was it an 'error' or an IO exception? If it would be an exception (like file not found) and we would use ErrorT monad for exceptions with specific types for the exceptions, then it would be clearer where the exception can come from. However if it was an error, then we cannot handle it terminally by some exception-catching like mechanism. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Combining Wouter's expressions with extensible records
2008/7/10 Ron Alford [EMAIL PROTECTED]: Ok, I'm closer, but I'm running into a problem with typeOf and lists, of all things: *WouterTest typeOf (eVar v :: TermExpr) Planning.Wouter.Expr (Planning.Wouter.:+: WouterTest.Const WouterTest.Var) *WouterTest typeOf ([eVar v] :: [TermExpr]) *** Exception: Prelude.undefined I'm pretty sure this is the culprit for getName: *WouterTest getName testNamed *** Exception: Prelude.undefined Any hints? Also, anyone have hints for how to get automatic derivation of Data (Expr f) ? I don't want to proliferate the last lines: deriving instance Data (Expr (And :+: Atomic (Expr (Const :+: Var deriving instance Data (Expr (Const :+: Var)) I screwed up the example code - it typechecks, but it'll fail at runtime. If you say: Inr x = undefined and then try to pass 'x' off to another function, you're trying to evaluate the undeifned, which is a runtime error. You'll want something more like: typeOf1 in@(InR f) = [...] where InL f = (InL undefined) `asTypeOf` in This is approaching silliness, but I've tested the code this time around - so it should even work. -Antoine ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe