From uhollerbach at gmail.com Mon Jun 1 02:39:09 2009 From: uhollerbach at gmail.com (Uwe Hollerbach) Date: Mon Jun 1 02:23:13 2009 Subject: [Haskell-cafe] (Pre-) Announce: Data.GDS 0.1.0 Message-ID: <65d7a7e0905312339j2eb142a4m98c29cc986e3eae7@mail.gmail.com> Hello, all, I'm hereby announcing Data.GDS, a small module to write and (eventually -- that's part of the "pre") read GDS files. For those of you not in the semiconductor biz, GDS-II is one of the classic formats of the industry. It's perhaps ever so slightly obsolete at this point, as the OASIS format is in the process of displacing it, but there are still huge numbers of designs in GDS format, and lots and lots of tools deal with it. Since I'm a sad sick weirdo(*), I spent a perfectly nice & sunny NorCal day hacking up this initial version of this module. It is to the point where it can generate a GDS file of your devising, although your specification of it still has to be at a very low level. It would be, and eventually will be, nicer to specify things at a higher level of abstraction. Also, it will eventually be nice to be able to read GDS files, returning an array of GDSRecord. I know how to do that, and I plan to, but I haven't got there yet. This ought to already be properly cabalized, and there's a small test program included; run it, save the output somewhere, and compare that with the sample GDS file which I also included in the tarball. If you examine the GDS file itself, you will see that, although it is small, it does in fact contain vital bits of design which will no doubt enable the biz to continue Moore's law for at least another century or so. Once I've implemented the reader, I'll upload this to hackage; in the meantime, if any of you are especially interested in what the rest of the interface to this should look like, I'm happy to hear your suggestions! Uwe (*) In point of fact, I am neither sad nor sick; I am in fact mostly happy & healthy. The reason I wasn't out taking a long walk today was because, alas, I dinged one achilles tendon a few days ago, and wanted to let it heal a bit... as to the "weirdo" charge, I beg you, gentle readers, avert your eyes while I plead no contest! :-) -------------- next part -------------- A non-text attachment was scrubbed... Name: gds-0.1.0.tar.gz Type: application/x-gzip Size: 6751 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090601/bbf4e1f1/gds-0.1.0.tar.gz From bulat.ziganshin at gmail.com Mon Jun 1 04:02:00 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Mon Jun 1 03:46:19 2009 Subject: [Haskell-cafe] Umlauts in command line arguments In-Reply-To: References: Message-ID: <1773829707.20090601120200@gmail.com> Hello Gwern, Monday, June 1, 2009, 4:35:25 AM, you wrote: > GHC mangles UTF by default. You probably want to use one of the utf8 > packages; eg. > http://hackage.haskell.org/cgi-bin/hackage-scripts/package/utf8-string > or > http://hackage.haskell.org/cgi-bin/hackage-scripts/package/utf8-light > (Neither of them seems to allow for accessing *arguments* rather than > stdin/stdout, but you could probably do something with the > encoding/decoding functions.) in order to get proper unicode handling, one should ask win api directly for cmdline: myGetArgs = do alloca $ \p_argc -> do p_argv_w <- commandLineToArgvW getCommandLineW p_argc argc <- peek p_argc argv_w <- peekArray (i argc) p_argv_w mapM peekTString argv_w >>== tail foreign import stdcall unsafe "windows.h GetCommandLineW" getCommandLineW :: LPTSTR foreign import stdcall unsafe "windows.h CommandLineToArgvW" commandLineToArgvW :: LPCWSTR -> Ptr CInt -> IO (Ptr LPWSTR) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From pkeir at dcs.gla.ac.uk Mon Jun 1 05:00:39 2009 From: pkeir at dcs.gla.ac.uk (Paul Keir) Date: Mon Jun 1 04:44:45 2009 Subject: [Haskell-cafe] iota Message-ID: <3CDFB8AFEA98E34CB599475AB11589C81C7958@EX2.ad.dcs.gla.ac.uk> Hi all, I was looking for an APL-style "iota" function for array indices. I noticed "range" from Data.Ix which, with a zero for the lower bound (here (0,0)), gives the values I need: > let (a,b) = (2,3) > index ((0,0),(a-1,b-1)) > [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2)] However, I need the results as a list of lists rather than a list of tuples; and my input is a list of integral values. I ended up writing the following function instead. The function isn't long, but longer than I first expected. Did I miss a simpler approach? iota :: (Integral a) => [a] -> [[a]] iota is = let count = product is tups = zip (tail $ scanr (*) 1 is) is buildRepList (r,i) = genericTake count $ cycle $ [0..i-1] >>= genericReplicate r lists = map buildRepList tups in transpose lists > length $ iota [2,3,4] > 24 Thanks, Paul -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090601/8d0b311f/attachment.html From alexott at gmail.com Mon Jun 1 05:00:44 2009 From: alexott at gmail.com (Alex Ott) Date: Mon Jun 1 04:44:52 2009 Subject: [Haskell-cafe] problem with inf-haskell + ghci? Message-ID: Hello all I recently found strange problem in use of inf-haskell + ghci on my Mac OS X Tyger. I haven't used inf-haskell for a some time, and several days ago i found, that it stopped to work - when I run C-c C-l (load file) it signal error, and when I perform C-c C-b (start interpreter) it load it, but entering of any text in it, leads to message: Leaving GHCi. Process haskell finished In terminal ghci works fine, but I couldn't find why ghci terminates when it called from Emacs. May be somebody had such problem with ghci? P.S. I use Carbon Emacs 22 + ghc 6.10.1 installed from macports -- With best wishes, Alex Ott, MBA http://alexott.blogspot.com/ http://xtalk.msk.su/~ott/ http://alexott-ru.blogspot.com/ From sebf at informatik.uni-kiel.de Mon Jun 1 06:06:50 2009 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Mon Jun 1 05:50:54 2009 Subject: [Haskell-cafe] Bool as type class to serve EDSLs. In-Reply-To: References: <638ABD0A29C8884A91BC5FB5C349B1C337FC71304F@EA-EXMSG-C334.europe.corp.microsoft.com> <381509001.20090528170702@gmail.com> Message-ID: <9C76A33A-B007-4F3C-B516-3F2352529587@informatik.uni-kiel.de> On Jun 1, 2009, at 12:17 AM, Henning Thielemann wrote: > On Thu, 28 May 2009, Bulat Ziganshin wrote: > >> i use another approach which imho is somewhat closer to >> interpretation >> of logical operations in dynamic languages (lua, ruby, perl): [...] > > The absence of such interpretations and thus the increased type > safety was one of the major the reasons for me to move from > scripting languages to Haskell. Do you argue that overloading logical operations like this in Haskell sacrifices type safety? Could programs "go wrong" [1] that use such abstractions? [1]: Robin Milner. A theory of type polymorphism in programming. J. Comput. Syst. Sci., 17:348?375, 1978. -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From shinnonoir at gmail.com Mon Jun 1 06:27:37 2009 From: shinnonoir at gmail.com (Raynor Vliegendhart) Date: Mon Jun 1 06:11:40 2009 Subject: [Haskell-cafe] iota In-Reply-To: <3CDFB8AFEA98E34CB599475AB11589C81C7958@EX2.ad.dcs.gla.ac.uk> References: <3CDFB8AFEA98E34CB599475AB11589C81C7958@EX2.ad.dcs.gla.ac.uk> Message-ID: <6d961e560906010327s5a2ef880y50b9b8e6078ef572@mail.gmail.com> The iota function you're looking for can be a whole lot simpler if you know about monads (list monad in particular) and sequence. For lists, sequence has the following behaviour: sequence [xs1,xs2, ... xsn] = [[x1,x2, ... , xn] | x1 <- xs1, x2 <- xs2, ... , xn <- xsn] Using this, you can reduce your iota function to a powerful one-liner: iota = sequence . map (enumFromTo 0 . pred) Kind regards, Raynor Vliegendhart On 6/1/09, Paul Keir wrote: > > > > Hi all, > > > > I was looking for an APL-style ?iota? function for array indices. I noticed > > ?range? from Data.Ix which, with a zero for the lower bound (here (0,0)), > > gives the values I need: > > > > > let (a,b) = (2,3) > > > index ((0,0),(a-1,b-1)) > > > [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2)] > > > > However, I need the results as a list of lists rather than a list of tuples; > and > > my input is a list of integral values. I ended up writing the following > function > > instead. The function isn?t long, but longer than I first expected. Did I > miss a > > simpler approach? > > > > iota :: (Integral a) => [a] -> [[a]] > > iota is = let count = product is > > tups = zip (tail $ scanr (*) 1 is) is > > buildRepList (r,i) = genericTake count $ cycle $ > > > [0..i-1] >>= genericReplicate r > > lists = map buildRepList tups > > in transpose lists > > > > > length $ iota [2,3,4] > > > 24 > > > > Thanks, > > Paul > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From pkeir at dcs.gla.ac.uk Mon Jun 1 07:24:05 2009 From: pkeir at dcs.gla.ac.uk (Paul Keir) Date: Mon Jun 1 07:08:12 2009 Subject: [Haskell-cafe] RE: iota Message-ID: <3CDFB8AFEA98E34CB599475AB11589C81C795D@EX2.ad.dcs.gla.ac.uk> That is quite spectacular. I revised my knowledge of sequence with a little function, akin to "sequence [xs1,xs2]": seq2 xs1 xs2 = do x1 <- xs1 x2 <- xs2 return [x1,x2] > seq2 [0,1] [0,1,2] > [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2]] I like your point-free style too; and that's a nice use of pred. Many thanks, Paul The iota function you're looking for can be a whole lot simpler if you know about monads (list monad in particular) and sequence. For lists, sequence has the following behaviour: sequence [xs1,xs2, ... xsn] = [[x1,x2, ... , xn] | x1 <- xs1, x2 <- xs2, ... , xn <- xsn] Using this, you can reduce your iota function to a powerful one-liner: iota = sequence . map (enumFromTo 0 . pred) Kind regards, Raynor Vliegendhart From: Paul Keir Sent: 01 June 2009 10:01 To: haskell-cafe@haskell.org Subject: iota Hi all, I was looking for an APL-style "iota" function for array indices. I noticed "range" from Data.Ix which, with a zero for the lower bound (here (0,0)), gives the values I need: > let (a,b) = (2,3) > index ((0,0),(a-1,b-1)) > [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2)] However, I need the results as a list of lists rather than a list of tuples; and my input is a list of integral values. I ended up writing the following function instead. The function isn't long, but longer than I first expected. Did I miss a simpler approach? iota :: (Integral a) => [a] -> [[a]] iota is = let count = product is tups = zip (tail $ scanr (*) 1 is) is buildRepList (r,i) = genericTake count $ cycle $ [0..i-1] >>= genericReplicate r lists = map buildRepList tups in transpose lists > length $ iota [2,3,4] > 24 Thanks, Paul -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090601/4a59bd25/attachment.html From akamaus at gmail.com Mon Jun 1 08:24:36 2009 From: akamaus at gmail.com (Dmitry V'yal) Date: Mon Jun 1 08:10:37 2009 Subject: [Haskell-cafe] GUI and background processing Message-ID: <4A23C884.6000905@gmail.com> Greetings, fellow haskellers. Currently I'm writing some kind of web crawler in haskell with gtk2hs gui. All network operations are run in separate thread, but sometimes input from user is needed. Afaik, gtk2hs is not thread safe, so I came up with following: I create two mvars, A and B, one for question, one for answer. Worker thread puts question in A and blocks trying to take B. Gui thread checks for question by polling with tryTakeMVar. Then question is ready, it asks user and puts his answer into B. Worker awakens and continues processing. Also, for progress report, I use a Chan which is written to by worker and is read by polling by gui thread. This scheme works, but I don't like it. All these mvars and chans create too much clutter, and polling looks rather ugly too. Is there a better way for implementing similar patterns of interaction? Best regards, Dmitry. From bulat.ziganshin at gmail.com Mon Jun 1 08:36:46 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Mon Jun 1 08:20:58 2009 Subject: [Haskell-cafe] GUI and background processing In-Reply-To: <4A23C884.6000905@gmail.com> References: <4A23C884.6000905@gmail.com> Message-ID: <1239759206.20090601163646@gmail.com> Hello Dmitry, Monday, June 1, 2009, 4:24:36 PM, you wrote: > All network operations are run in separate thread, but sometimes input > from user is needed. Afaik, gtk2hs is not thread safe, so I came up with look for postGUISync and postGUIASync -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From v.reshetnikov at gmail.com Mon Jun 1 08:44:37 2009 From: v.reshetnikov at gmail.com (Vladimir Reshetnikov) Date: Mon Jun 1 08:28:41 2009 Subject: [Haskell-cafe] Trouble with types Message-ID: <4770d2590906010544p65deaa91k10ec011714522a32@mail.gmail.com> Hi, I tried this code: ----------------------- f, g :: a -> a (f, g) = (id, id) ----------------------- Hugs: OK GHC: Couldn't match expected type `forall a. a -> a' against inferred type `a -> a' In the expression: id In the expression: (id, id) In a pattern binding: (f, g) = (id, id) What does mean this error message? And what of them (Hugs, GHC) is correct? Thanks Vladimir From daniel.is.fischer at web.de Mon Jun 1 09:54:06 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Jun 1 09:38:49 2009 Subject: [Haskell-cafe] Trouble with types In-Reply-To: <4770d2590906010544p65deaa91k10ec011714522a32@mail.gmail.com> References: <4770d2590906010544p65deaa91k10ec011714522a32@mail.gmail.com> Message-ID: <200906011554.06363.daniel.is.fischer@web.de> Am Montag 01 Juni 2009 14:44:37 schrieb Vladimir Reshetnikov: > Hi, > > I tried this code: > > ----------------------- > f, g :: a -> a > (f, g) = (id, id) > ----------------------- > > Hugs: OK > > GHC: > Couldn't match expected type `forall a. a -> a' > against inferred type `a -> a' > In the expression: id > In the expression: (id, id) > In a pattern binding: (f, g) = (id, id) > > What does mean this error message? > And what of them (Hugs, GHC) is correct? http://www.haskell.org/ghc/docs/latest/html/users_guide/bugs-and-infelicities.html Section 12.1.1.4, Declarations and bindings GHC's typechecker makes all pattern bindings monomorphic by default; this behaviour can be disabled with -XNoMonoPatBinds. See Section 7.1, ?Language options?. Hugs is correct, it's a known infelicity in GHC which can be disabled. > > Thanks > Vladimir From dagit at codersbase.com Mon Jun 1 12:14:05 2009 From: dagit at codersbase.com (Jason Dagit) Date: Mon Jun 1 11:58:08 2009 Subject: [Haskell-cafe] Bool as type class to serve EDSLs. In-Reply-To: <9C76A33A-B007-4F3C-B516-3F2352529587@informatik.uni-kiel.de> References: <638ABD0A29C8884A91BC5FB5C349B1C337FC71304F@EA-EXMSG-C334.europe.corp.microsoft.com> <381509001.20090528170702@gmail.com> <9C76A33A-B007-4F3C-B516-3F2352529587@informatik.uni-kiel.de> Message-ID: On Mon, Jun 1, 2009 at 3:06 AM, Sebastian Fischer < sebf@informatik.uni-kiel.de> wrote: > On Jun 1, 2009, at 12:17 AM, Henning Thielemann wrote: > > On Thu, 28 May 2009, Bulat Ziganshin wrote: >> >> i use another approach which imho is somewhat closer to interpretation >>> of logical operations in dynamic languages (lua, ruby, perl): [...] >>> >> >> The absence of such interpretations and thus the increased type safety was >> one of the major the reasons for me to move from scripting languages to >> Haskell. >> > > Do you argue that overloading logical operations like this in Haskell > sacrifices type safety? Could programs "go wrong" [1] that use such > abstractions? If I understand your point correctly, you are suggesting that such programs are still type safe. I agree with the claim that such features are detrimental in practice though. Instead of lumping it with type safety, then what do we call it? I think I've heard of languages that do such conversions as "weakly" typed. Really the issue is with implicit conversions, right? Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090601/8f47f9a0/attachment.html From nowgate at yahoo.com Mon Jun 1 13:02:36 2009 From: nowgate at yahoo.com (michael rice) Date: Mon Jun 1 12:46:40 2009 Subject: [Haskell-cafe] Missing a "Deriving"? Message-ID: <416173.48544.qm@web31102.mail.mud.yahoo.com> I went back and tried to convert the YAHT example to Monad, importing Monad, commenting out all but the data descriptions and the searchAll function, and finally replacing success, failure, augment, and combine in the searchAll function with return, fail, >>=, and mplus. *Main> let g = Graph [(1,'a'),(2,'b'),(3,'c'),(4,'d')] [(1,2,'p'),(2,3,'q'),(1,4,'r'),(4,3,'s')] *Main> searchAll g 1 3 :: [[Int]] [[1,2,3],[1,4,3]] *Main> searchAll g 1 3 :: Maybe [Int] Just [1,2,3] *Main> searchAll g 3 1 :: Maybe [Int] Nothing *Main> searchAll g 3 1 :: [[Int]] [] All good so far, but then tried to convert Failable from Computation to Monad instance Monad Failable where ??? return = Success ??? fail = Fail ??? >>= (Success x) f = f x ??? >>= (Fail s) _ = Fail s ??? mplus (Fail _) y = y ??? mplus x _ = x ? and got the following error. Prelude> :l graph5 [1 of 1] Compiling Main???????????? ( graph5.hs, interpreted ) graph5.hs:34:4: parse error on input `>>=' Failed, modules loaded: none. Prelude> Complete code follows. Michael ========================= import Monad data Failable a = Success a | Fail String deriving (Show) data Graph v e = Graph [(Int,v)] [(Int,Int,e)] {- class Computation c where ??? success :: a -> c a ??? failure :: String -> c a ??? augment :: c a -> (a -> c b) -> c b ??? combine :: c a -> c a -> c a instance Computation Maybe where ??? success = Just ??? failure = const Nothing ??? augment (Just x) f = f x ??? augment Nothing _ = Nothing ??? combine Nothing y = y ??? combine x _ = x instance Computation Failable where ??? success = Success ??? failure = Fail ??? augment (Success x) f = f x ??? augment (Fail s) _ = Fail s ??? combine (Fail _) y = y ??? combine x _ = x -} instance Monad Failable where ??? return = Success ??? fail = Fail ??? >>= (Success x) f = f x ??? >>= (Fail s) _ = Fail s ??? mplus (Fail _) y = y ??? mplus x _ = x {- instance Computation [] where ??? success a = [a] ??? failure = const [] ??? augment l f = concat (map f l) ??? combine = (++) searchAll g@(Graph vl el) src dst ??? | src == dst = success [src] ??? | otherwise = search' el ??? where search' [] = failure "no path" ????????? search' ((u,v,_):es) ????????????? | src == u = (searchAll g v dst `augment` ???????????????????????????? (success . (u:))) ??????????????????????????? `combine` search' es ????????????? | otherwise = search' es -} searchAll g@(Graph vl el) src dst ??? | src == dst = return [src] ??? | otherwise = search' el ??? where search' [] = fail "no path" ????????? search' ((u,v,_):es) ????????????? | src == u = (searchAll g v dst >>= ???????????????????????????? (return . (u:))) ??????????????????????????? `mplus` search' es ????????????? | otherwise = search' es ? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090601/2762ddb2/attachment.html From byorgey at seas.upenn.edu Mon Jun 1 13:07:17 2009 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Mon Jun 1 12:50:22 2009 Subject: [Haskell-cafe] How to implement this? A case for scoped record labels? In-Reply-To: <5ab17e790905311820q23c7a4dejf05f387107e3e97f@mail.gmail.com> References: <4A1B54AE.9030903@freegeek.org> <5ab17e790905311820q23c7a4dejf05f387107e3e97f@mail.gmail.com> Message-ID: <20090601170717.GA9223@seas.upenn.edu> On Sun, May 31, 2009 at 06:20:23PM -0700, Iavor Diatchki wrote: > > and so on. It is a bit verbose, but you only have to do it once for > your protocol, and then you get the nice overloaded interface. This also seems like the kind of thing perfectly suited to Template Haskell. Especially if the records might end up being modified, fields added, etc., having some TH code to regenerate all the necessary classes and instances from some compact description could be a big win, and probably not too hard to code either. -Brent From nadine.and.henry at pobox.com Mon Jun 1 13:45:54 2009 From: nadine.and.henry at pobox.com (Henry Laxen) Date: Mon Jun 1 13:30:12 2009 Subject: [Haskell-cafe] MySQL, CouchDB, and Haskell Message-ID: Dear Group, I've spent the last few days trying to convert a bunch of mysql tables into couchdb using haskell, and I've documented my efforts, in case anyone else intends to wander in similar waters. The tutorial is at: http://maztravel.com/haskell/mySqlToCouchDB.html comments welcome here at the list or to me privately at nadine.and.henry -AT- pobox.com Best wishes, Henry Laxen From daniel.is.fischer at web.de Mon Jun 1 13:51:35 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Jun 1 13:36:27 2009 Subject: [Haskell-cafe] Missing a "Deriving"? In-Reply-To: <416173.48544.qm@web31102.mail.mud.yahoo.com> References: <416173.48544.qm@web31102.mail.mud.yahoo.com> Message-ID: <200906011951.35775.daniel.is.fischer@web.de> Am Montag 01 Juni 2009 19:02:36 schrieb michael rice: > All good so far, but then tried to convert Failable from Computation to > Monad > > > instance Monad Failable where > ??? return = Success > ??? fail = Fail > ??? >>= (Success x) f = f x > ??? >>= (Fail s) _ = Fail s > ??? mplus (Fail _) y = y > ??? mplus x _ = x > ? > > and got the following error. > > > Prelude> :l graph5 > [1 of 1] Compiling Main???????????? ( graph5.hs, interpreted ) > > graph5.hs:34:4: parse error on input `>>=' > Failed, modules loaded: none. > Prelude> > When you use an operator in prefix position, you must enclose it in parentheses, like you must enclose a function in backticks if you use it infix. So the definition of (>>=) should read (>>=) (Success x) f = f x (>>=) (Fail s) _ = Fail s or, defining it in infix position, (Success x) >>= f = f x (Fail s) >>= _ = Fail s > > Complete code follows. > > Michael > From claus.reinke at talk21.com Mon Jun 1 14:22:10 2009 From: claus.reinke at talk21.com (Claus Reinke) Date: Mon Jun 1 14:06:28 2009 Subject: [Haskell-cafe] Bool as type class to serve EDSLs. References: <638ABD0A29C8884A91BC5FB5C349B1C337FC71304F@EA-EXMSG-C334.europe.corp.microsoft.com><381509001.20090528170702@gmail.com><9C76A33A-B007-4F3C-B516-3F2352529587@informatik.uni-kiel.de> Message-ID: <76CE077128014A86A2D61E5918F8BFE8@cr3lt> >> Do you argue that overloading logical operations like this in Haskell >> sacrifices type safety? Could programs "go wrong" [1] that use such >> abstractions? > > If I understand your point correctly, you are suggesting that such programs > are still type safe. I agree with the claim that such features are > detrimental in practice though. Instead of lumping it with type safety, > then what do we call it? I think I've heard of languages that do such > conversions as "weakly" typed. Really the issue is with implicit > conversions, right? Isn't it merely a matter of balance? In order for typed programs not to go "wrong", one has to define "right" and "wrong", and devise a type system that rules out anything that might go "wrong", usually at the expense of some programs that might go "right". Advanced type system features like overloading take that unused space and devise ways to redirect code that would go "wrong" (in simpler systems) to go "right" in useful new ways (eg: adding two functions or matrices or .. does not have to be "wrong", there are interpretations in which all of these make perfect sense, and Haskell can express many of them). What is happening then is that more and more of the previously "wrong" space is filled up with meaningful ways of going "right", until nearly every syntactically valid program goes somewhere. That can make for an extremely expressive and powerful language, but it renders the naive notion of going "wrong" or "right" rather meaningless: "wrong" just means we haven't figured out a meaningful way to interpret it, and going "right" can easily be a far cry from where you wanted it to go. Claus PS. this problem can be made worse if the implicit conversions aren't consistent, if small "twitches" in source code can lead to grossly different behaviour. There is a fine line between advanced and uncontrollable, and opinions on what side of the line any given definition is on can differ. From doaitse at swierstra.net Mon Jun 1 14:27:05 2009 From: doaitse at swierstra.net (S. Doaitse Swierstra) Date: Mon Jun 1 14:11:11 2009 Subject: [Haskell-cafe] ANN: new version of uu-parsinglib In-Reply-To: <20090531232147.GA14703@soi.city.ac.uk> References: <20090531232147.GA14703@soi.city.ac.uk> Message-ID: <8F2D399B-451A-45F4-9FE1-B7F5145C3B91@swierstra.net> And rename "empty" to "fail"? You managed to confuse me since I always use pSucceed to recognise the empty string. Doaitse On 1 jun 2009, at 01:21, Ross Paterson wrote: > On Sun, May 31, 2009 at 09:40:38PM +0200, S. Doaitse Swierstra wrote: >> A new version of the uu-parsinglib has been uploaded to hackage. It >> is >> now based on Control.Applicative where possible. >> >> Be warned that functions like some and many will be redefined in the >> future. > > Perhaps we should make some and many methods of Alternative, <* and *> > methods of Applicative and <$ a method of Functor, all with the > current > definitions as defaults. (John Meacham was also asking for the first > of these.) > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From claus.reinke at talk21.com Mon Jun 1 14:49:44 2009 From: claus.reinke at talk21.com (Claus Reinke) Date: Mon Jun 1 14:33:52 2009 Subject: [Haskell-cafe] Re: Error message reform References: <294178482.20090528014514@gmail.com> <1243461810.9823.6.camel@ulysses> <9FF8B5F979DD46C1A0E870E68A22CECC@cr3lt> <4A1F57F2.1000302@freegeek.org><4A2120D0.4010107@cs.au.dk> <4A22FE7D.7090304@freegeek.org> Message-ID: > It's too wordy, but it's a start. This is also prime ground for wanting > to have configurable levels of error reports, since some users will find > it helpful to see both types but others will find it confusing. Indeed. For this simple example, I find Hugs' message nearly optimal, but as one could just as well construct examples where GHC's message was nearly optimal, I've tried instead to extend the example, until neither Hugs nor GHC gives an optimal message. Even so, it is worth comparing the two, and their complementary approaches to the problem: t = (let q=0 in(\y->(\x->(\z->let r=1 in x z))) ()) :: (a->b)->(a->a) D:\home\Haskell\tmp\desktop\errormessages.hs:2:41: Couldn't match expected type `a' against inferred type `b' `a' is a rigid type variable bound by an expression type signature at D:\home\Haskell\tmp\desktop\errormessages.hs:2:56 `b' is a rigid type variable bound by an expression type signature at D:\home\Haskell\tmp\desktop\errormessages.hs:2:59 In the expression: x z In the expression: let r = 1 in x z In the expression: (\ z -> let r = 1 in x z) ERROR file:.\errormessages.hs:2 - Inferred type is not general enough *** Expression : let {...} in (\y -> \x -> \z -> let {...} in x z) () *** Expected type : (a -> b) -> a -> a *** Inferred type : (a -> a) -> a -> a GHC delivers its messages from in-the-middle of its typing process, which one hopes might give as little information as neccessary to identify the issue, without irrelevant context. It then tries to explain that information nicely, followed by some value-level context. Hugs delivers its messages from on-the-outside-looking-in, which one hopes might give the maximum potentially relevant information. It makes no attempt to cushion the blow. In practice, neither approach works all the time, and even for this tiny contrived example, one would have to engage in some "type debugging" (inserting type signatures, to trigger type-level printfs; commenting out large parts of code to see whether they contribute to the issue; ..) to figure it out. Note that both approaches are fairly precise in locating the error at the type level - it is the cross-reference from type to value level that runs into trouble, especially if the former is only implicit in the latter (which is why type debugging by adding signatures helps). > For really intricate type hacking, even this isn't enough because the > programming errors often happen far from where the type errors are > finally caught. In an ideal world, ghc could dump the entire proof > forest generated by inference, so an external tool[1] could be used to > browse through it and track the complete history of where inferred types > came from. This gives a partial view of the inferred types for a > compilation unit, something I've often wanted (rather than the manual > comment/reload/uncomment routine). The proof forest could even be used > as an interlingua over which people can write filters to generate > messages they find most helpful. Yes, most research papers on this ended up suggesting visual representations and separation between generating and presenting/querying error information. > Ah the joys of ideal worlds... ;) "if you don't have a dream, how you gonna have a dream come true?" (Bloody Mary) Claus From claus.reinke at talk21.com Mon Jun 1 15:00:09 2009 From: claus.reinke at talk21.com (Claus Reinke) Date: Mon Jun 1 14:44:16 2009 Subject: [Haskell-cafe] Re: Error message reform (was: Strange type errorwith associated type synonyms) References: <294178482.20090528014514@gmail.com> <1243461810.9823.6.camel@ulysses><9FF8B5F979DD46C1A0E870E68A22CECC@cr3lt> Message-ID: <8C39CAA7170D479D88613F7F77920916@cr3lt> > I once thought, that error messages must be configurable by libraries, > too. This would be perfect for EDSLs that shall be used by non-Haskellers. Yes, that is a problem. > But I have no idea how to design that. There was some work in that direction in the context of the Helium project. See the publication lists of Bastiaan Heeren and Jurriaan Hage: http://people.cs.uu.nl/bastiaan/#Publications http://www.cs.uu.nl/research/techreps/aut/jur.html Claus From nowgate at yahoo.com Mon Jun 1 17:30:00 2009 From: nowgate at yahoo.com (michael rice) Date: Mon Jun 1 17:14:04 2009 Subject: [Haskell-cafe] Missing a "Deriving"? Message-ID: <789959.35516.qm@web31103.mail.mud.yahoo.com> Got it. Thanks! Michael --- On Mon, 6/1/09, Daniel Fischer wrote: From: Daniel Fischer Subject: Re: [Haskell-cafe] Missing a "Deriving"? To: haskell-cafe@haskell.org Date: Monday, June 1, 2009, 1:51 PM Am Montag 01 Juni 2009 19:02:36 schrieb michael rice: > All good so far, but then tried to convert Failable from Computation to > Monad > > > instance Monad Failable where > return = Success > fail = Fail > >>= (Success x) f = f x > >>= (Fail s) _ = Fail s > mplus (Fail _) y = y > mplus x _ = x > > > and got the following error. > > > Prelude> :l graph5 > [1 of 1] Compiling Main ( graph5.hs, interpreted ) > > graph5.hs:34:4: parse error on input `>>=' > Failed, modules loaded: none. > Prelude> > When you use an operator in prefix position, you must enclose it in parentheses, like you must enclose a function in backticks if you use it infix. So the definition of (>>=) should read ? ? (>>=) (Success x) f = f x ? ? (>>=) (Fail s) _ = Fail s or, defining it in infix position, ? ? (Success x) >>= f = f x ? ? (Fail s) >>= _ = Fail s > > Complete code follows. > > Michael > _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090601/5da24d47/attachment.html From sebf at informatik.uni-kiel.de Mon Jun 1 20:14:08 2009 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Mon Jun 1 19:58:11 2009 Subject: [Haskell-cafe] Bool as type class to serve EDSLs. In-Reply-To: <76CE077128014A86A2D61E5918F8BFE8@cr3lt> References: <638ABD0A29C8884A91BC5FB5C349B1C337FC71304F@EA-EXMSG-C334.europe.corp.microsoft.com><381509001.20090528170702@gmail.com><9C76A33A-B007-4F3C-B516-3F2352529587@informatik.uni-kiel.de> <76CE077128014A86A2D61E5918F8BFE8@cr3lt> Message-ID: <7E09E1CC-7C3A-4296-AE39-0148AD27A343@informatik.uni-kiel.de> >>> Do you argue that overloading logical operations like this in >>> Haskell >>> sacrifices type safety? Could programs "go wrong" [1] that use such >>> abstractions? >> If I understand your point correctly, you are suggesting that such >> programs >> are still type safe. My asking was really meant as a question to find out what Henning meant when he talked about type safety. >> I agree with the claim that such features are detrimental in >> practice though. I also feel uncomfortable about such features, but the problem seems to be different from type safety. Maybe it is more about predictability. For example, if '1 + 23 = 24' and '1 + "23" = "123"' this can lead to confusion although using overloading this could be done in Haskell. That the compiler is able to figure out a correct instantiation of an overloaded operation does not mean that it is easy for the programmer too. And if it is not, programs are hard to understand. >> Instead of lumping it with type safety, >> then what do we call it? I think I've heard of languages that do >> such >> conversions as "weakly" typed. Really the issue is with implicit >> conversions, right? > > Isn't it merely a matter of balance? In order for typed programs not > to go "wrong", one has to define "right" and "wrong", and devise a > type > system that rules out anything that might go "wrong", usually at the > expense of some programs that might go "right". I had in mind "causes a run-time error" as definition of "goes wrong". But this simple view may well be inaccurate. > Advanced type system features like overloading take that unused > space and devise ways to redirect code that would go "wrong" (in > simpler systems) to go "right" in useful new ways (eg: adding two > functions or matrices or .. does not have to be "wrong", there are > interpretations in which all of these make perfect sense, and > Haskell can express many > of them). > > What is happening then is that more and more of the previously "wrong" > space is filled up with meaningful ways of going "right", until > nearly every > syntactically valid program goes somewhere. That can make for an > extremely expressive and powerful language, but it renders the naive > notion of going "wrong" or "right" rather meaningless: "wrong" just > means we haven't figured out a meaningful way to interpret it, and > going "right" can easily be a far cry from where you wanted it to go. I (think I) agree with you. Overloading could give a meaning to almost everything. Not necessarily a sensible one, and judgements about what is sensible seem to differ among different people. Regardless of whether a specific overloading is *sensible*, wanting it to be *predictable* seems like a reasonable requirement which may be easier to agree on. Cheers, Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From danielkcook at gmail.com Mon Jun 1 23:39:44 2009 From: danielkcook at gmail.com (Dan Cook) Date: Mon Jun 1 20:23:49 2009 Subject: [Haskell-cafe] Checking a value against a passed-in constructor? Message-ID: Hi, (Relatively new to Haskell here ..) So I have the following: data MyVal = Atom String | Bool Bool And I want to do something like this check :: (Bool -> MyVal) -> MyVal -> True check f (f x) = True check _ _ = False What that means is I want to pass a MyVal constructor and a MyVal, and return True if the second argument was constructed with the first. More generally, I'd like to be able to do genCheck :: (* -> MyVal) -> MyVal -> True genCheck f (f x) = True genCheck _ _ = False So that I can pass in _any_ MyVal constructor and let the function just check if the second argument was constructed with the first, without caring which constructor it is. What is the preferred way to do this, since neither of those functions compile? Cheers, - Dan From dagit at codersbase.com Mon Jun 1 21:02:09 2009 From: dagit at codersbase.com (Jason Dagit) Date: Mon Jun 1 20:46:12 2009 Subject: [Haskell-cafe] Checking a value against a passed-in constructor? In-Reply-To: References: Message-ID: Hi Dan, On Mon, Jun 1, 2009 at 8:39 PM, Dan Cook wrote: > Hi, > (Relatively new to Haskell here ..) > > So I have the following: > > data MyVal = Atom String > | Bool Bool > > And I want to do something like this > > check :: (Bool -> MyVal) -> MyVal -> True > check f (f x) = True > check _ _ = False You may be confusing yourself here on one point. The type 'Bool' is already defined by the prelude, but the data constructor is not. So you are able to create a data constructor for MyVal that is called "Bool" and contains a Bool. I think this distinction is leading to the next probem I see. Type signatures have to contain types and not values in Haskell. 'True' is a value so it can't be placed in the type signature. The type of True is Bool. So I think you meant to ask about: check :: (Bool -> MyVal) -> MyVal -> Bool Now if you define this function the first parameter can be any function Bool -> MyVal, not just the data constructors of MyVal. Also, the type of Atom :: String -> MyVal so you can't even pass it to 'check'. > > What that means is I want to pass a MyVal constructor and a MyVal, and > return True if the second argument was constructed with the first. More > generally, I'd like to be able to do > > genCheck :: (* -> MyVal) -> MyVal -> True > genCheck f (f x) = True > genCheck _ _ = False > > So that I can pass in _any_ MyVal constructor and let the function just > check if the second argument was constructed with the first, without caring > which constructor it is. This strikes me as a job for template haskell, but the use of TH is beyond what I can explain :) > > > What is the preferred way to do this, since neither of those functions > compile? My preferred way, is just to define isAtom and isBool both with type MyVal -> Bool and use them where I need them. There are a number of tools to generate such things like DrIFT, TH, and maybe some others? I hope that helps, Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090601/5c6b3080/attachment.html From nowgate at yahoo.com Mon Jun 1 21:28:09 2009 From: nowgate at yahoo.com (michael rice) Date: Mon Jun 1 21:12:11 2009 Subject: [Haskell-cafe] Missing a "Deriving"? Message-ID: <585584.70758.qm@web31106.mail.mud.yahoo.com> Still stumped. Maybe and [] are in the same MonadPlus monad, but how do I make monad Failable understand mplus? I'm now getting this error upon loading: Prelude> :l graph5 [1 of 1] Compiling Main???????????? ( graph5.hs, interpreted ) graph5.hs:36:4: `mplus' is not a (visible) method of class `Monad' Failed, modules loaded: none. Prelude> Complete code follows. Michael ========================= import Monad data Failable a = Success a | Fail String deriving (Show) data Graph v e = Graph [(Int,v)] [(Int,Int,e)] {- class Computation c where ??? success :: a -> c a ??? failure :: String -> c a ??? augment :: c a -> (a -> c b) -> c b ??? combine :: c a -> c a -> c a instance Computation Maybe where ??? success = Just ??? failure = const Nothing ??? augment (Just x) f = f x ??? augment Nothing _ = Nothing ??? combine Nothing y = y ??? combine x _ = x instance Computation Failable where ??? success = Success ??? failure = Fail ??? augment (Success x) f = f x ??? augment (Fail s) _ = Fail s ??? combine (Fail _) y = y ??? combine x _ = x -} instance Monad Failable where ??? return = Success ??? fail = Fail ??? (>>=) (Success x) f = f x ??? (>>=) (Fail s) _ = Fail s ??? mplus (Fail _) y = y ??? mplus x _ = x {- instance Computation [] where ??? success a = [a] ??? failure = const [] ??? augment l f = concat (map f l) ??? combine = (++) searchAll g@(Graph vl el) src dst ??? | src == dst = success [src] ??? | otherwise = search' el ??? where search' [] = failure "no path" ????????? search' ((u,v,_):es) ????????????? | src == u = (searchAll g v dst `augment` ???????????????????????????? (success . (u:))) ??????????????????????????? `combine` search' es ????????????? | otherwise = search' es -} searchAll g@(Graph vl el) src dst ??? | src == dst = return [src] ??? | otherwise = search' el ??? where search' [] = fail "no path" ????????? search' ((u,v,_):es) ????????????? | src == u = (searchAll g v dst >>= ???????????????????????????? (return . (u:))) ??????????????????????????? `mplus` search' es ????????????? | otherwise = search' es ? -----Inline Attachment Follows----- _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090601/011280e3/attachment.html From rmm-haskell at z.odi.ac Mon Jun 1 21:33:47 2009 From: rmm-haskell at z.odi.ac (Ross Mellgren) Date: Mon Jun 1 21:17:51 2009 Subject: [Haskell-cafe] Missing a "Deriving"? In-Reply-To: <585584.70758.qm@web31106.mail.mud.yahoo.com> References: <585584.70758.qm@web31106.mail.mud.yahoo.com> Message-ID: mplus is a method of class MonadPlus, so you need to write it in a separate instance from the one for Monad, e.g. instance MonadPlus Failable where mplus = ... -Ross On Jun 1, 2009, at 9:28 PM, michael rice wrote: > Still stumped. Maybe and [] are in the same MonadPlus monad, but how > do I make monad Failable understand mplus? > > I'm now getting this error upon loading: > > > Prelude> :l graph5 > [1 of 1] Compiling Main ( graph5.hs, interpreted ) > > graph5.hs:36:4: `mplus' is not a (visible) method of class `Monad' > Failed, modules loaded: none. > Prelude> > > > > Complete code follows. > > Michael > > ========================= > > import Monad > > data Failable a = Success a | Fail String deriving (Show) > > data Graph v e = Graph [(Int,v)] [(Int,Int,e)] > > {- > class Computation c where > success :: a -> c a > failure :: String -> c a > augment :: c a -> (a -> c b) -> c b > combine :: c a -> c a -> c a > > instance Computation Maybe where > success = Just > failure = const Nothing > augment (Just x) f = f x > augment Nothing _ = Nothing > combine Nothing y = y > combine x _ = x > > instance Computation Failable where > success = Success > failure = Fail > augment (Success x) f = f x > augment (Fail s) _ = Fail s > combine (Fail _) y = y > combine x _ = x > -} > > instance Monad Failable where > return = Success > fail = Fail > (>>=) (Success x) f = f x > (>>=) (Fail s) _ = Fail s > mplus (Fail _) y = y > mplus x _ = x > > {- > instance Computation [] where > success a = [a] > failure = const [] > augment l f = concat (map f l) > combine = (++) > > > searchAll g@(Graph vl el) src dst > | src == dst = success [src] > | otherwise = search' el > where search' [] = failure "no path" > search' ((u,v,_):es) > | src == u = (searchAll g v dst `augment` > (success . (u:))) > `combine` search' es > | otherwise = search' es > -} > > searchAll g@(Graph vl el) src dst > | src == dst = return [src] > | otherwise = search' el > where search' [] = fail "no path" > search' ((u,v,_):es) > | src == u = (searchAll g v dst >>= > (return . (u:))) > `mplus` search' es > | otherwise = search' es > > > > -----Inline Attachment Follows----- > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090601/5ef740fd/attachment.html From nowgate at yahoo.com Mon Jun 1 21:40:43 2009 From: nowgate at yahoo.com (michael rice) Date: Mon Jun 1 21:24:44 2009 Subject: [Haskell-cafe] Missing a "Deriving"? Message-ID: <903060.9615.qm@web31105.mail.mud.yahoo.com> Hi Ross, I thought of that, but return, fail, and >>= became "not visible" when I changed the instance declaration from Monad to MonadPlus.. Can Failable be in two instance declarations, one for Monad (giving it return, fail, and >>=) and one for MonadPlus (giving it mplus)? Michael --- On Mon, 6/1/09, Ross Mellgren wrote: From: Ross Mellgren Subject: Re: [Haskell-cafe] Missing a "Deriving"? To: "michael rice" Cc: "haskell-cafe Cafe" Date: Monday, June 1, 2009, 9:33 PM mplus is a method of class MonadPlus, so you need to write it in a separate instance from the one for Monad, e.g. instance MonadPlus Failable where?? ?mplus = ... -Ross On Jun 1, 2009, at 9:28 PM, michael rice wrote: Still stumped. Maybe and [] are in the same MonadPlus monad, but how do I make monad Failable understand mplus? I'm now getting this error upon loading: Prelude> :l graph5 [1 of 1] Compiling Main???????????? ( graph5.hs, interpreted ) graph5.hs:36:4: `mplus' is not a (visible) method of class `Monad' Failed, modules loaded: none. Prelude> Complete code follows. Michael ========================= import Monad data Failable a = Success a | Fail String deriving (Show) data Graph v e = Graph [(Int,v)] [(Int,Int,e)] {- class Computation c where ??? success :: a -> c a ??? failure :: String -> c a ??? augment :: c a -> (a -> c b) -> c b ??? combine :: c a -> c a -> c a instance Computation Maybe where ??? success = Just ??? failure = const Nothing ??? augment (Just x) f = f x ??? augment Nothing _ = Nothing ??? combine Nothing y = y ??? combine x _ = x instance Computation Failable where ??? success = Success ??? failure = Fail ??? augment (Success x) f = f x ??? augment (Fail s) _ = Fail s ??? combine (Fail _) y = y ??? combine x _ = x -} instance Monad Failable where ??? return = Success ??? fail = Fail ??? (>>=) (Success x) f = f x ??? (>>=) (Fail s) _ = Fail s ??? mplus (Fail _) y = y ??? mplus x _ = x {- instance Computation [] where ??? success a = [a] ??? failure = const [] ??? augment l f = concat (map f l) ??? combine = (++) searchAll g@(Graph vl el) src dst ??? | src == dst = success [src] ??? | otherwise = search' el ??? where search' [] = failure "no path" ????????? search' ((u,v,_):es) ????????????? | src == u = (searchAll g v dst `augment` ???????????????????????????? (success . (u:))) ??????????????????????????? `combine` search' es ????????????? | otherwise = search' es -} searchAll g@(Graph vl el) src dst ??? | src == dst = return [src] ??? | otherwise = search' el ??? where search' [] = fail "no path" ????????? search' ((u,v,_):es) ????????????? | src == u = (searchAll g v dst >>= ???????????????????????????? (return . (u:))) ??????????????????????????? `mplus` search' es ????????????? | otherwise = search' es ? -----Inline Attachment Follows----- _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090601/452cfd72/attachment.html From rmm-haskell at z.odi.ac Mon Jun 1 21:43:34 2009 From: rmm-haskell at z.odi.ac (Ross Mellgren) Date: Mon Jun 1 21:27:38 2009 Subject: [Haskell-cafe] Missing a "Deriving"? In-Reply-To: <903060.9615.qm@web31105.mail.mud.yahoo.com> References: <903060.9615.qm@web31105.mail.mud.yahoo.com> Message-ID: Oh I wasn't clear -- you need multiple instance declarations for a given type (Failable, for example), one for each type class you're implementing. That is, instance Monad Failable where return = ... ... instance MonadPlus Failable where mplus = ... ... -Ross On Jun 1, 2009, at 9:40 PM, michael rice wrote: > Hi Ross, > > I thought of that, but return, fail, and >>= became "not visible" > when I changed the instance declaration from Monad to MonadPlus.. > Can Failable be in two instance declarations, one for Monad (giving > it return, fail, and >>=) and one for MonadPlus (giving it mplus)? > > Michael > > --- On Mon, 6/1/09, Ross Mellgren wrote: > > From: Ross Mellgren > Subject: Re: [Haskell-cafe] Missing a "Deriving"? > To: "michael rice" > Cc: "haskell-cafe Cafe" > Date: Monday, June 1, 2009, 9:33 PM > > mplus is a method of class MonadPlus, so you need to write it in a > separate instance from the one for Monad, e.g. > > instance MonadPlus Failable where > mplus = ... > > -Ross > > On Jun 1, 2009, at 9:28 PM, michael rice wrote: > >> Still stumped. Maybe and [] are in the same MonadPlus monad, but >> how do I make monad Failable understand mplus? >> >> I'm now getting this error upon loading: >> >> >> Prelude> :l graph5 >> [1 of 1] Compiling Main ( graph5.hs, interpreted ) >> >> graph5.hs:36:4: `mplus' is not a (visible) method of class `Monad' >> Failed, modules loaded: none. >> Prelude> >> >> >> >> Complete code follows. >> >> Michael >> >> ========================= >> >> import Monad >> >> data Failable a = Success a | Fail String deriving (Show) >> >> data Graph v e = Graph [(Int,v)] [(Int,Int,e)] >> >> {- >> class Computation c where >> success :: a -> c a >> failure :: String -> c a >> augment :: c a -> (a -> c b) -> c b >> combine :: c a -> c a -> c a >> >> instance Computation Maybe where >> success = Just >> failure = const Nothing >> augment (Just x) f = f x >> augment Nothing _ = Nothing >> combine Nothing y = y >> combine x _ = x >> >> instance Computation Failable where >> success = Success >> failure = Fail >> augment (Success x) f = f x >> augment (Fail s) _ = Fail s >> combine (Fail _) y = y >> combine x _ = x >> -} >> >> instance Monad Failable where >> return = Success >> fail = Fail >> (>>=) (Success x) f = f x >> (>>=) (Fail s) _ = Fail s >> mplus (Fail _) y = y >> mplus x _ = x >> >> {- >> instance Computation [] where >> success a = [a] >> failure = const [] >> augment l f = concat (map f l) >> combine = (++) >> >> >> searchAll g@(Graph vl el) src dst >> | src == dst = success [src] >> | otherwise = search' el >> where search' [] = failure "no path" >> search' ((u,v,_):es) >> | src == u = (searchAll g v dst `augment` >> (success . (u:))) >> `combine` search' es >> | otherwise = search' es >> -} >> >> searchAll g@(Graph vl el) src dst >> | src == dst = return [src] >> | otherwise = search' el >> where search' [] = fail "no path" >> search' ((u,v,_):es) >> | src == u = (searchAll g v dst >>= >> (return . (u:))) >> `mplus` search' es >> | otherwise = search' es >> >> >> >> -----Inline Attachment Follows----- >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090601/59913874/attachment.html From nowgate at yahoo.com Mon Jun 1 22:03:08 2009 From: nowgate at yahoo.com (michael rice) Date: Mon Jun 1 21:47:11 2009 Subject: [Haskell-cafe] Missing a "Deriving"? Message-ID: <810042.76010.qm@web31101.mail.mud.yahoo.com> I didn't know I could do that. Works fine. Output below. Thanks! This is some pretty neat stuff, and I've only scratched the surface. Michael =================== [michael@localhost ~]$ ghci GHCi, version 6.10.1: http://www.haskell.org/ghc/? :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> :l graph5 [1 of 1] Compiling Main???????????? ( graph5.hs, interpreted ) graph5.hs:37:9: ??? Warning: No explicit method nor default method for `mzero' ??? In the instance declaration for `MonadPlus Failable' Ok, modules loaded: Main. *Main> let g = Graph [(1,'a'),(2,'b'),(3,'c'),(4,'d')] [(1,2,'p'),(2,3,'q'),(1,4,'r'),(4,3,'s')] *Main> searchAll g 1 3 :: Failable [Int] Success [1,2,3] *Main> searchAll g 3 1 :: Failable [Int] Fail "no path" *Main> searchAll g 1 3 :: Maybe [Int] Just [1,2,3] *Main> searchAll g 3 1 :: Maybe [Int] Nothing *Main> searchAll g 1 3 :: [[Int]] [[1,2,3],[1,4,3]] *Main> searchAll g 3 1 :: [[Int]] [] *Main> --- On Mon, 6/1/09, Ross Mellgren wrote: From: Ross Mellgren Subject: Re: [Haskell-cafe] Missing a "Deriving"? To: "michael rice" Cc: "haskell-cafe Cafe" Date: Monday, June 1, 2009, 9:43 PM Oh I wasn't clear -- you need multiple instance declarations for a given type (Failable, for example), one for each type class you're implementing. That is,? instance Monad Failable where?? return = ...?? ... instance MonadPlus Failable where?? mplus = ...?? ... -Ross On Jun 1, 2009, at 9:40 PM, michael rice wrote: Hi Ross, I thought of that, but return, fail, and >>= became "not visible" when I changed the instance declaration from Monad to MonadPlus.. Can Failable be in two instance declarations, one for Monad (giving it return, fail, and >>=) and one for MonadPlus (giving it mplus)? Michael --- On Mon, 6/1/09, Ross Mellgren wrote: From: Ross Mellgren Subject: Re: [Haskell-cafe] Missing a "Deriving"? To: "michael rice" Cc: "haskell-cafe Cafe" Date: Monday, June 1, 2009, 9:33 PM mplus is a method of class MonadPlus, so you need to write it in a separate instance from the one for Monad, e.g. instance MonadPlus Failable where?? ?mplus = ... -Ross On Jun 1, 2009, at 9:28 PM, michael rice wrote: Still stumped. Maybe and [] are in the same MonadPlus monad, but how do I make monad Failable understand mplus? I'm now getting this error upon loading: Prelude> :l graph5 [1 of 1] Compiling Main???????????? ( graph5.hs, interpreted ) graph5.hs:36:4: `mplus' is not a (visible) method of class `Monad' Failed, modules loaded: none. Prelude> Complete code follows. Michael ========================= import Monad data Failable a = Success a | Fail String deriving (Show) data Graph v e = Graph [(Int,v)] [(Int,Int,e)] {- class Computation c where ??? success :: a -> c a ??? failure :: String -> c a ??? augment :: c a -> (a -> c b) -> c b ??? combine :: c a -> c a -> c a instance Computation Maybe where ??? success = Just ??? failure = const Nothing ??? augment (Just x) f = f x ??? augment Nothing _ = Nothing ??? combine Nothing y = y ??? combine x _ = x instance Computation Failable where ??? success = Success ??? failure = Fail ??? augment (Success x) f = f x ??? augment (Fail s) _ = Fail s ??? combine (Fail _) y = y ??? combine x _ = x -} instance Monad Failable where ??? return = Success ??? fail = Fail ??? (>>=) (Success x) f = f x ??? (>>=) (Fail s) _ = Fail s ??? mplus (Fail _) y = y ??? mplus x _ = x {- instance Computation [] where ??? success a = [a] ??? failure = const [] ??? augment l f = concat (map f l) ??? combine = (++) searchAll g@(Graph vl el) src dst ??? | src == dst = success [src] ??? | otherwise = search' el ??? where search' [] = failure "no path" ????????? search' ((u,v,_):es) ????????????? | src == u = (searchAll g v dst `augment` ???????????????????????????? (success . (u:))) ??????????????????????????? `combine` search' es ????????????? | otherwise = search' es -} searchAll g@(Graph vl el) src dst ??? | src == dst = return [src] ??? | otherwise = search' el ??? where search' [] = fail "no path" ????????? search' ((u,v,_):es) ????????????? | src == u = (searchAll g v dst >>= ???????????????????????????? (return . (u:))) ??????????????????????????? `mplus` search' es ????????????? | otherwise = search' es ? -----Inline Attachment Follows----- _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090601/6ae3cae3/attachment-0001.html From ryani.spam at gmail.com Mon Jun 1 22:36:00 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Mon Jun 1 22:20:01 2009 Subject: [Haskell-cafe] Missing a "Deriving"? In-Reply-To: <810042.76010.qm@web31101.mail.mud.yahoo.com> References: <810042.76010.qm@web31101.mail.mud.yahoo.com> Message-ID: <2f9b2d30906011936h76b7f6et8049f52b0e76f804@mail.gmail.com> > graph5.hs:37:9: > Warning: No explicit method nor default method for `mzero' > In the instance declaration for `MonadPlus Failable' This warning is saying you didn't finish the declaration. Try something like instance MonadPlus Failable where mplus (Fail _) y = y mplus x _ = x mzero = Fail "mzero" Also, I'd use "import Control.Monad" instead of "import Monad". -- ryan On Mon, Jun 1, 2009 at 7:03 PM, michael rice wrote: > I didn't know I could do that. Works fine. Output below. Thanks! > > This is some pretty neat stuff, and I've only scratched the surface. > > Michael > > =================== > > [michael@localhost ~]$ ghci > GHCi, version 6.10.1: http://www.haskell.org/ghc/? :? for help > Loading package ghc-prim ... linking ... done. > Loading package integer ... linking ... done. > Loading package base ... linking ... done. > Prelude> :l graph5 > [1 of 1] Compiling Main???????????? ( graph5.hs, interpreted ) > > graph5.hs:37:9: > ??? Warning: No explicit method nor default method for `mzero' > ??? In the instance declaration for `MonadPlus Failable' > Ok, modules loaded: Main. > *Main> let g = Graph [(1,'a'),(2,'b'),(3,'c'),(4,'d')] > [(1,2,'p'),(2,3,'q'),(1,4,'r'),(4,3,'s')] > *Main> searchAll g 1 3 :: Failable [Int] > Success [1,2,3] > *Main> searchAll g 3 1 :: Failable [Int] > Fail "no path" > *Main> searchAll g 1 3 :: Maybe [Int] > Just [1,2,3] > *Main> searchAll g 3 1 :: Maybe [Int] > Nothing > *Main> searchAll g 1 3 :: [[Int]] > [[1,2,3],[1,4,3]] > *Main> searchAll g 3 1 :: [[Int]] > [] > *Main> > > > > --- On Mon, 6/1/09, Ross Mellgren wrote: > > From: Ross Mellgren > Subject: Re: [Haskell-cafe] Missing a "Deriving"? > To: "michael rice" > Cc: "haskell-cafe Cafe" > Date: Monday, June 1, 2009, 9:43 PM > > Oh I wasn't clear -- you need multiple instance declarations for a given > type (Failable, for example), one for each type class you're implementing. > That is, > instance Monad Failable where > ?? return = ... > ?? ... > > instance MonadPlus Failable where > ?? mplus = ... > ?? ... > -Ross > On Jun 1, 2009, at 9:40 PM, michael rice wrote: > > Hi Ross, > > I thought of that, but return, fail, and >>= became "not visible" when I > changed the instance declaration from Monad to MonadPlus.. Can Failable be > in two instance declarations, one for Monad (giving it return, fail, and >>>=) and one for MonadPlus (giving it mplus)? > > Michael > > --- On Mon, 6/1/09, Ross Mellgren wrote: > > From: Ross Mellgren > Subject: Re: [Haskell-cafe] Missing a "Deriving"? > To: "michael rice" > Cc: "haskell-cafe Cafe" > Date: Monday, June 1, 2009, 9:33 PM > > mplus is a method of class MonadPlus, so you need to write it in a separate > instance from the one for Monad, e.g. > instance MonadPlus Failable where > ?? ?mplus = ... > -Ross > On Jun 1, 2009, at 9:28 PM, michael rice wrote: > > Still stumped. Maybe and [] are in the same MonadPlus monad, but how do I > make monad Failable understand mplus? > > I'm now getting this error upon loading: > > > Prelude> :l graph5 > [1 of 1] Compiling Main???????????? ( graph5.hs, interpreted ) > > graph5.hs:36:4: `mplus' is not a (visible) method of class `Monad' > Failed, modules loaded: none. > Prelude> > > > > Complete code follows. > > Michael > > ========================= > > import Monad > > data Failable a = Success a | Fail String deriving (Show) > > data Graph v e = Graph [(Int,v)] [(Int,Int,e)] > > {- > class Computation c where > ??? success :: a -> c a > ??? failure :: String -> c a > ??? augment :: c a -> (a -> c b) -> c b > ??? combine :: c a -> c a -> c a > > instance Computation Maybe where > ??? success = Just > ??? failure = const Nothing > ??? augment (Just x) f = f x > ??? augment Nothing _ = Nothing > ??? combine Nothing y = y > ??? combine x _ = x > > instance Computation Failable where > ??? success = Success > ??? failure = Fail > ??? augment (Success x) f = f x > ??? augment (Fail s) _ = Fail s > ??? combine (Fail _) y = y > ??? combine x _ = x > -} > > instance Monad Failable where > ??? return = Success > ??? fail = Fail > ??? (>>=) (Success x) f = f x > ??? (>>=) (Fail s) _ = Fail s > ??? mplus (Fail _) y = y > ??? mplus x _ = x > > {- > instance Computation [] where > ??? success a = [a] > ??? failure = const [] > ??? augment l f = concat (map f l) > ??? combine = (++) > > > searchAll g@(Graph vl el) src dst > ??? | src == dst = success [src] > ??? | otherwise = search' el > ??? where search' [] = failure "no path" > ????????? search' ((u,v,_):es) > ????????????? | src == u = (searchAll g v dst `augment` > ???????????????????????????? (success . (u:))) > ??????????????????????????? `combine` search' es > ????????????? | otherwise = search' es > -} > > searchAll g@(Graph vl el) src dst > ??? | src == dst = return [src] > ??? | otherwise = search' el > ??? where search' [] = fail "no path" > ????????? search' ((u,v,_):es) > ????????????? | src == u = (searchAll g v dst >>= > ???????????????????????????? (return . (u:))) > ??????????????????????????? `mplus` search' es > ????????????? | otherwise = search' es > > > -----Inline Attachment Follows----- > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From ok at cs.otago.ac.nz Mon Jun 1 22:55:25 2009 From: ok at cs.otago.ac.nz (Richard O'Keefe) Date: Mon Jun 1 22:39:31 2009 Subject: [Haskell-cafe] Checking a value against a passed-in constructor? In-Reply-To: References: Message-ID: <9F110BD7-C9AA-4007-ADAA-2690513690D1@cs.otago.ac.nz> On 2 Jun 2009, at 3:39 pm, Dan Cook wrote: > Hi, > (Relatively new to Haskell here ..) > > So I have the following: > > data MyVal = Atom String > | Bool Bool > > And I want to do something like this > > check :: (Bool -> MyVal) -> MyVal -> True > check f (f x) = True > check _ _ = False > > What that means is I want to pass a MyVal constructor and a MyVal, > and return True if the second argument was constructed with the first. Yeek. Why do you want to do _that_? You could quite easily determine whether two values were constructed with the _same_ constructor: check (Atom _) (Atom _) = True check (Bool _) (Bool _) = True check _ _ = False and instead of passing in "a constructor" pass in "an example of a term constructed by that constructor". So instead of check Atom foo, do check (Atom undefined) foo instead of check Bool bar, do check (Bool undefined) bar Another approach is to write a boolean function for each constructor, e.g., is_atom (Atom _) = True is_atom _ = False is_bool (Bool _) = True is_bool _ = False and pass one of these instead of a constructor: check :: (MyVal -> Bool) -> MyVal -> Bool check f x = f x which makes the check function itself pointless. > More generally, I'd like to be able to do > > genCheck :: (* -> MyVal) -> MyVal -> True > genCheck f (f x) = True > genCheck _ _ = False > > So that I can pass in _any_ MyVal constructor and let the function > just check if the second argument was constructed with the first, > without caring which constructor it is. There are some very high-powered things you can do in Haskell these days which would let you get closer to this than most people would be happy reading. We can use the same idea of passing an example. So given data Biffo x y z = Ping x | Pong y z | Pang x y z you can easily write check (Ping _) (Ping _) = True check (Pong _ _) (Pong _ _) = True check (Pang _ _ _) (Pang _ _ _) = True check _ _ = False called as check (Ping undefined) foo or check (Pong undefined undefined) bar or check (Pang undefined undefined undefined) or much better, go the Boolean function route: is_ping (Ping _) = True is_ping _ = False is_pong (Pong _ _) = True is_pong _ = False is_pang (Pang _ _ _) = True is_pang _ = False and use one of these functions whenever you want something you can use to check for a particular constructor. There are various meta-programming ("Scrap Your Boilerplate", "Template Haskell") approaches you can use to automate some of these. The first step is the step backwards where you ask "why am I trying to do this?" From rj248842 at hotmail.com Mon Jun 1 23:34:28 2009 From: rj248842 at hotmail.com (R J) Date: Mon Jun 1 23:18:38 2009 Subject: [Haskell-cafe] RE: Haskell-Cafe Digest, Vol 70, Issue 2 In-Reply-To: <20090602014716.59FB0324719@www.haskell.org> References: <20090602014716.59FB0324719@www.haskell.org> Message-ID: Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: Vocabulary Template.dotx Type: application/vnd.openxmlformats-officedocument.wordprocessingml.template Size: 27396 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090601/41d2b070/VocabularyTemplate-0001.bin From tomahawkins at gmail.com Tue Jun 2 00:18:55 2009 From: tomahawkins at gmail.com (Tom Hawkins) Date: Tue Jun 2 00:02:56 2009 Subject: [Haskell-cafe] Possible Haskell Project Message-ID: <594c1e830906012118s65978b5cjaf2e9bd6a2412f40@mail.gmail.com> My family and I are moving in the coming months. My wife will be attending a new school in the fall. Among the many hassles of moving are locating and transferring medical records to new doctors and clinics. During our time in Minnesota, we've visited several clinics and hospitals, so our medical data is spread across a dozen different networks. Collecting this data is a chore. And reciting it to every new medical provider is frustrating, especially knowing someone else has already typed this stuff into the computer. For obvious reasons, there are many software companies competing in the Electronic Health Record (EHR) industry. I haven't spent much time researching the field, but I have to imagine there is no shortage of bloated standards and next to nil interoperability. With President Obama pushing for electronic health records, this could be an opportunity for the Haskell community to deliver a common framework that the US, and maybe the rest of the world, could build upon -- a longshot I realize. At the core, the fundamental problem is not that complicated. It's just storing and retrieving a person's various health events: checkups, prescriptions, procedures, test results, etc. The main technical challenges are database distribution and patient security. Both are fun problems, and our friends at Galios continue to show how effective Haskell is at building secure systems. Any thoughts? Ideas? -Tom BTW, Anyone looking to rent a house in Eden Prairie, MN? A Haskell employer is just 4 miles down the road (Eaton). From aslatter at gmail.com Tue Jun 2 01:12:05 2009 From: aslatter at gmail.com (Antoine Latter) Date: Tue Jun 2 00:56:08 2009 Subject: [Haskell-cafe] Possible Haskell Project In-Reply-To: <594c1e830906012118s65978b5cjaf2e9bd6a2412f40@mail.gmail.com> References: <594c1e830906012118s65978b5cjaf2e9bd6a2412f40@mail.gmail.com> Message-ID: <694519c50906012212v48b555f9tfc02dce162914575@mail.gmail.com> On Mon, Jun 1, 2009 at 11:18 PM, Tom Hawkins wrote: > My family and I are moving in the coming months. ?My wife will be > attending a new school in the fall. ?Among the many hassles of moving > are locating and transferring medical records to new doctors and > clinics. ?During our time in Minnesota, we've visited several clinics > and hospitals, so our medical data is spread across a dozen different > networks. ?Collecting this data is a chore. ?And reciting it to every > new medical provider is frustrating, especially knowing someone else > has already typed this stuff into the computer. > > For obvious reasons, there are many software companies competing in > the Electronic Health Record (EHR) industry. ?I haven't spent much > time researching the field, but I have to imagine there is no shortage > of bloated standards and next to nil interoperability. ?With President > Obama pushing for electronic health records, this could be an > opportunity for the Haskell community to deliver a common framework > that the US, and maybe the rest of the world, could build upon -- a > longshot I realize. > > At the core, the fundamental problem is not that complicated. ?It's > just storing and retrieving a person's various health events: > checkups, prescriptions, procedures, test results, etc. ?The main > technical challenges are database distribution and patient security. > Both are fun problems, and our friends at Galios continue to show how > effective Haskell is at building secure systems. > > Any thoughts? ?Ideas? > > -Tom > A good place to start is http://en.wikipedia.org/wiki/HL7 , which is a not-for-profit organization which tries to define interfacing standards between medical devices and medical records providers. I haven't worked much with their standards so I don't know how useful they'd be. I think they might be geared towards vendor-to-vendor interop. As for the legacy of people who thought it wasn't complex: http://histalk.blog-city.com/guest_article__repeat_after_me_healthcare_data_models_matter.htm I don't agree with everything the guy wrote, but it's an interesting article. As for knowing how to use the data once you've got it, there were some recent news articles about the Google personal-health-record (PHR) importing billing codes and trying to use them to reconstruct a clinical history to not-so-great effect. And I would say that the security problem is more than a technical problem - the big security issue in medical record interchange is privacy. What data can flow between healthcare organizations? What information can individual organizations restrict access to? How can we get the patient's input in how their data can move between healthcare organizations? Should we? And how should data move to organizations that are both providers and payors? Does it matter? Maybe I'm drifting a bit far afield from Haskell ... Antoine From v.reshetnikov at gmail.com Tue Jun 2 01:30:59 2009 From: v.reshetnikov at gmail.com (Vladimir Reshetnikov) Date: Tue Jun 2 01:15:01 2009 Subject: [Haskell-cafe] Trouble with types In-Reply-To: <200906011554.06363.daniel.is.fischer@web.de> References: <4770d2590906010544p65deaa91k10ec011714522a32@mail.gmail.com> <200906011554.06363.daniel.is.fischer@web.de> Message-ID: <4770d2590906012230p337c9e88w812a4bf03d8646f6@mail.gmail.com> Hi Daniel, Could you please explain what does mean 'monomorphic' in this context? I thought that all type variables in Haskell are implicitly universally quantified, so (a -> a) is the same type as (forall a. a -> a) Thank you, Vladimir On 6/1/09, Daniel Fischer wrote: > Am Montag 01 Juni 2009 14:44:37 schrieb Vladimir Reshetnikov: >> Hi, >> >> I tried this code: >> >> ----------------------- >> f, g :: a -> a >> (f, g) = (id, id) >> ----------------------- >> >> Hugs: OK >> >> GHC: >> Couldn't match expected type `forall a. a -> a' >> against inferred type `a -> a' >> In the expression: id >> In the expression: (id, id) >> In a pattern binding: (f, g) = (id, id) >> >> What does mean this error message? >> And what of them (Hugs, GHC) is correct? > > http://www.haskell.org/ghc/docs/latest/html/users_guide/bugs-and-infelicities.html > Section 12.1.1.4, Declarations and bindings > > GHC's typechecker makes all pattern bindings monomorphic by default; this > behaviour can be > disabled with -XNoMonoPatBinds. See Section 7.1, ?Language options?. > > Hugs is correct, it's a known infelicity in GHC which can be disabled. >> >> Thanks >> Vladimir > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From ross at soi.city.ac.uk Tue Jun 2 03:38:34 2009 From: ross at soi.city.ac.uk (Ross Paterson) Date: Tue Jun 2 03:22:24 2009 Subject: [Haskell-cafe] ANN: new version of uu-parsinglib In-Reply-To: <8F2D399B-451A-45F4-9FE1-B7F5145C3B91@swierstra.net> References: <20090531232147.GA14703@soi.city.ac.uk> <8F2D399B-451A-45F4-9FE1-B7F5145C3B91@swierstra.net> Message-ID: <20090602073834.GA3831@soi.city.ac.uk> On Mon, Jun 01, 2009 at 08:27:05PM +0200, S. Doaitse Swierstra wrote: > And rename "empty" to "fail"? You managed to confuse me since I always > use pSucceed to recognise the empty string. That would clash with the existing and widely used "fail". One could view "empty" as the parser for the empty language. And some of us are also interested in Alternatives that aren't parsers. From wren at freegeek.org Tue Jun 2 04:42:52 2009 From: wren at freegeek.org (wren ng thornton) Date: Tue Jun 2 04:26:55 2009 Subject: [Haskell-cafe] Trouble with types In-Reply-To: <4770d2590906012230p337c9e88w812a4bf03d8646f6@mail.gmail.com> References: <4770d2590906010544p65deaa91k10ec011714522a32@mail.gmail.com> <200906011554.06363.daniel.is.fischer@web.de> <4770d2590906012230p337c9e88w812a4bf03d8646f6@mail.gmail.com> Message-ID: <4A24E60C.5090704@freegeek.org> Vladimir Reshetnikov wrote: > Hi Daniel, > > Could you please explain what does mean 'monomorphic' in this context? > I thought that all type variables in Haskell are implicitly > universally quantified, so (a -> a) is the same type as (forall a. a > -> a) At the top level (i.e. definition level), yes. However, each use site this polymorphism may be restricted down (in particular, to the point of monomorphism). In a syntax more like Core, the definition of the identity function is, id :: forall a. a -> a id @a (x :: a) = x Where the @ is syntax for reifying types or for capital-lambda application (whichever interpretation you prefer). In this syntax it's clear to see that |id| (of type forall a. a -> a) is quite different than any particular |id @a| (of type a->a for the particular @a). So in your example, there's a big difference between these definitions, (f,g) = (id,id) (f', g') @a = (id @a, id @a) The latter one is polymorphic, but it has interesting type sharing going on which precludes giving universally quantified types to f' and g' (the universality is for the pair (f',g') and so the types of f' and g' must covary). Whereas the former has both fields of the tuple being polymorphic (independently). Both interpretations of the original code are legitimate in theory, but the former is much easier to work with and reason about. It also allows for tupling definitions as a way of defining local name scope blocks, without side effects on types. -- Live well, ~wren From wren at freegeek.org Tue Jun 2 05:18:05 2009 From: wren at freegeek.org (wren ng thornton) Date: Tue Jun 2 05:02:08 2009 Subject: [Haskell-cafe] Possible Haskell Project In-Reply-To: <594c1e830906012118s65978b5cjaf2e9bd6a2412f40@mail.gmail.com> References: <594c1e830906012118s65978b5cjaf2e9bd6a2412f40@mail.gmail.com> Message-ID: <4A24EE4D.5040507@freegeek.org> Tom Hawkins wrote: > At the core, the fundamental problem is not that complicated. It's > just storing and retrieving a person's various health events: > checkups, prescriptions, procedures, test results, etc. The main > technical challenges are database distribution and patient security. > Both are fun problems, and our friends at Galios continue to show how > effective Haskell is at building secure systems. > > Any thoughts? Ideas? Actually, it's a lot more complicated than that, albeit not for "technical" reasons. There's a great deal of legislation about what can and cannot be done with medical records: who can have access to them, under what circumstances, how they can be transmitted, stored, etc. This is more than just boilerplate code--- clinics can be audited to prove proper handling and can loose their licenses or worse for improper handling of records. Additionally, the requisite formats do require a lot of boilerplate code since the protocols were defined back in the paper age and medical legislation moves at the speed of mountains. I worked briefly on an open-source database project for managing a medical clinic's records (so, not even for dealing with the public in any way). The technical feat isn't that difficult, as you say, but the human engineering involved can be quite complex--- and the human programming will have major effects on the design, in order to forbid invalid or unacceptable behavior. It's not a project to undertake lightly or without corporate funding. Medical record management is a market that has very low penetration from the F/OSS movement, which in turn places a burden on smaller clinics, so I'm all for anyone who's willing to invest in an open solution :) -- Live well, ~wren From danielkcook at gmail.com Tue Jun 2 06:50:32 2009 From: danielkcook at gmail.com (Dan) Date: Tue Jun 2 06:34:49 2009 Subject: [Haskell-cafe] Checking a value against a passed-in constructor? In-Reply-To: <9F110BD7-C9AA-4007-ADAA-2690513690D1@cs.otago.ac.nz> References: <9F110BD7-C9AA-4007-ADAA-2690513690D1@cs.otago.ac.nz> Message-ID: <20090602115032.686ebc76@dan-laptop> Hi Richard, > Yeek. Why do you want to do _that_? Heh. I've got a parser and I want to check what I've parsed (it's an exercise in Write Yourself a Scheme in 48 Hours). > check (Atom _) (Atom _) = True > check (Bool _) (Bool _) = True > check _ _ = False Yes I came up with this too, but it seemed ugly to create unnecessary new values just to take them apart again. > is_atom (Atom _) = True > is_atom _ = False This is nicer. It still requires listing out the possible constructors (Bool, Atom ... the real code obviously has more). I don't like that, because I've already listed them out once, in the type declaration itself. Surely, I shouldn't have to list them out again? > There are various meta-programming ("Scrap Your Boilerplate", > "Template Haskell") approaches you can use to automate some of > these. You hit the nail on the head. "Why I am doing this" is because of boilerplate. Boilerplate gives me rashes and bulbous spots on the nose. Consider the following Ruby code: def check(zeClass, zeValue) zeValue.is_a? zeClass end This does not require a new function for every class defined in Ruby. (To be fair, though, the class of a Ruby object tells you precious little, compared to a Haskell type constructor). I figured there would be a clever Haskell idiom that would give me a similarly concise route. Does it really require Template Haskell? I can barely parse regular Haskell as it is.. Cheers, - Dan From voigt at tcs.inf.tu-dresden.de Tue Jun 2 07:18:00 2009 From: voigt at tcs.inf.tu-dresden.de (Janis Voigtlaender) Date: Tue Jun 2 07:02:03 2009 Subject: [Haskell-cafe] HaL4: Haskell-Meeting in Germany, 12th June 2009 Message-ID: <4A250A68.9040105@tcs.inf.tu-dresden.de> Hi all, If you are anyway near Halle/Saale in June, be sure not to miss out on: http://iba-cg.de/hal4.html We have already close to 50 registered participants, so expect a very lively meeting. See you there? (Late registration still possible.) Ciao, Janis. -- Dr. Janis Voigtlaender http://wwwtcs.inf.tu-dresden.de/~voigt/ mailto:voigt@tcs.inf.tu-dresden.de From voigt at tcs.inf.tu-dresden.de Tue Jun 2 07:21:17 2009 From: voigt at tcs.inf.tu-dresden.de (Janis Voigtlaender) Date: Tue Jun 2 07:05:19 2009 Subject: [Haskell-cafe] HaL4: Haskell-Meeting in Germany, 12th June 2009 In-Reply-To: <4A250A68.9040105@tcs.inf.tu-dresden.de> References: <4A250A68.9040105@tcs.inf.tu-dresden.de> Message-ID: <4A250B2D.8090000@tcs.inf.tu-dresden.de> Janis Voigtlaender wrote: > Hi all, > > If you are anyway near Halle/Saale in June, be sure not to miss out on: I meant "anywhere near", of course :-) And even if you are not anyway or anywhere near, you might still want to come just for the occasion :-) -- Dr. Janis Voigtlaender http://wwwtcs.inf.tu-dresden.de/~voigt/ mailto:voigt@tcs.inf.tu-dresden.de From gue.schmidt at web.de Tue Jun 2 08:47:55 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Tue Jun 2 08:32:05 2009 Subject: [Haskell-cafe] Compiling a windows app - embedding application icon Message-ID: Hi all, is it possible to make ghc embedd an application icon in the .exe during the compilation process? G?nther From mxcantor at gmail.com Tue Jun 2 09:14:21 2009 From: mxcantor at gmail.com (Max Cantor) Date: Tue Jun 2 08:58:26 2009 Subject: [Haskell-cafe] HXT XmlPicklers - TH Derivation Message-ID: <4A9146CE-64C0-4D4C-836D-E242BD5C737A@gmail.com> Hi, I have developed some simple TH code to automatically derive XmlPickler instances for my types and if there is interest, I will clean it up and submit a patch. Its not complete, but is a start. Any interest? Max From danielkcook at gmail.com Tue Jun 2 10:15:29 2009 From: danielkcook at gmail.com (Daniel Cook) Date: Tue Jun 2 09:59:31 2009 Subject: [Haskell-cafe] Spam apology Message-ID: <48ca5ce50906020715v1f817f37t5d2a55140aa408fd@mail.gmail.com> Sorry for all the repeated messages, my e-mail client exploded. From bulat.ziganshin at gmail.com Tue Jun 2 10:28:37 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Tue Jun 2 10:12:42 2009 Subject: [Haskell-cafe] Compiling a windows app - embedding application icon In-Reply-To: References: Message-ID: <1143000733.20090602182837@gmail.com> Hello Gu?nther, Tuesday, June 2, 2009, 4:47:55 PM, you wrote: > is it possible to make ghc embedd an application icon in the .exe during > the compilation process? i've found that answer may be googled as "gcc icon": 1) create icon.rc containing one line: 100 ICON "freearc.ico" 2) compile it using windres: windres.exe icon.rc icon.o 3) link in icon.o when making executable: ghc --make main.hs icon.o -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From tomahawkins at gmail.com Tue Jun 2 10:56:11 2009 From: tomahawkins at gmail.com (Tom Hawkins) Date: Tue Jun 2 10:40:14 2009 Subject: [Haskell-cafe] Possible Haskell Project In-Reply-To: <694519c50906012212v48b555f9tfc02dce162914575@mail.gmail.com> References: <594c1e830906012118s65978b5cjaf2e9bd6a2412f40@mail.gmail.com> <694519c50906012212v48b555f9tfc02dce162914575@mail.gmail.com> Message-ID: <594c1e830906020756j1a83d8e0kb4370df851ea9e3a@mail.gmail.com> On Tue, Jun 2, 2009 at 12:12 AM, Antoine Latter wrote: > A good place to start is http://en.wikipedia.org/wiki/HL7 , which is a > not-for-profit organization which tries to define interfacing > standards between medical devices and medical records providers. ?I > haven't worked much with their standards so I don't know how useful > they'd be. I think they might be geared towards vendor-to-vendor > interop. > > As for the legacy of people who thought it wasn't complex: > http://histalk.blog-city.com/guest_article__repeat_after_me_healthcare_data_models_matter.htm > > I don't agree with everything the guy wrote, but it's an interesting article. In an industry like this that generates so much data, I think all parties are tempted to record and track as must as possible. But after all the lab results, x-rays, and MRIs, it's the two or three paragraphs of a doctor's dictation that matter. Maybe patients and doctors would be best served if they had an easy way to store, retrieve, and query these dictations. I see this as an abstracting database problem: - records (dictations) are write-once-read-only data pertaining to a subject (patient) - some users (doctors, patients) are allowed to view a subset of records on a subject - some users are allowed to create new records on a subject - some users are allowed to change capabilities of other users Then, built on top of an abstract distributed data storage problem: - a network of computers store a collection of write-once-read-only data chunks (encoded, fragmented records) - chunks are distributed to minimize access time - chunks are distributed to maintain data integrity through system failures Both of these abstract problems can be used for many things outside the medical field. So even if an electronic health record project does not pan out, the code could find its way into other applications. -Tom From doaitse at swierstra.net Tue Jun 2 11:00:34 2009 From: doaitse at swierstra.net (S. Doaitse Swierstra) Date: Tue Jun 2 10:44:36 2009 Subject: [Haskell-cafe] Possible Haskell Project In-Reply-To: <4A24EE4D.5040507@freegeek.org> References: <594c1e830906012118s65978b5cjaf2e9bd6a2412f40@mail.gmail.com> <4A24EE4D.5040507@freegeek.org> Message-ID: The Dutch government has been trying to get something like this for years; parliament is asking every new minister why the promised heaven has not yet arrived, only to hear that more consultants are needed. I have been to hearings of our parliament and I can tell you such events are extremely informative and make you loose any hope that something good will come out of this soon; there are just too many stakeholders, and no so-called "problem-owner"s except you. Simple questions asked, for which there often is no answer is: - who owns the information? - are you allowed to change information which you own? - should docters pay for the right to enter information in this system, or be paid for the service they provide if they enter information? Instead of trying to change the world you may run a small wiki (I run Twiki) server on your home machine where you just store the information you collect, and enter your information while you are having a consult through your iPhone! When you leave the room you ask your docter whether what you have entered is a correct view of this situation ;-}I think this will solve the major part of your problem, and maybe it opens the eyes of the medical establishment. Doaitse Swierstra On 2 jun 2009, at 11:18, wren ng thornton wrote: > Tom Hawkins wrote: >> At the core, the fundamental problem is not that complicated. It's >> just storing and retrieving a person's various health events: >> checkups, prescriptions, procedures, test results, etc. The main >> technical challenges are database distribution and patient security. >> Both are fun problems, and our friends at Galios continue to show how >> effective Haskell is at building secure systems. >> Any thoughts? Ideas? > > Actually, it's a lot more complicated than that, albeit not for > "technical" reasons. There's a great deal of legislation about what > can and cannot be done with medical records: who can have access to > them, under what circumstances, how they can be transmitted, stored, > etc. This is more than just boilerplate code--- clinics can be > audited to prove proper handling and can loose their licenses or > worse for improper handling of records. Additionally, the requisite > formats do require a lot of boilerplate code since the protocols > were defined back in the paper age and medical legislation moves at > the speed of mountains. > > I worked briefly on an open-source database project for managing a > medical clinic's records (so, not even for dealing with the public > in any way). The technical feat isn't that difficult, as you say, > but the human engineering involved can be quite complex--- and the > human programming will have major effects on the design, in order to > forbid invalid or unacceptable behavior. It's not a project to > undertake lightly or without corporate funding. > > Medical record management is a market that has very low penetration > from the F/OSS movement, which in turn places a burden on smaller > clinics, so I'm all for anyone who's willing to invest in an open > solution :) > > -- > Live well, > ~wren > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From leimy2k at gmail.com Tue Jun 2 12:20:43 2009 From: leimy2k at gmail.com (David Leimbach) Date: Tue Jun 2 12:04:46 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary Message-ID: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> I've got the following "printHex" string as a response from a 9P server running on the Inferno Operating System. (thanks to a friendly mailing list contributor who sent a nice example of using Data.Binary) 1300000065ffff000400000600395032303030 This is a little endian encoded ByteString with the following fields in it: Rversion {size :: Word32, mtype :: Word8, tag :: Word16, msize :: Word32, ssize :: Word16, version :: ByteString} But when I try to use the following implementation of "get" to decode this stream, I'm getting the following error: "too few bytes. Failed reading at byte position 20" Unfortunately, I'm only expecting 19 bytes, and in fact never asked for byte 20. (I am just asking for everything up to ssize, and then "getRemainingLazyByteString"). Is this a bug? Is it mine or in Data.Binary? :-) Here's my "get" function: get = do s <- getWord32le mtype <- getWord8 getSpecific s mtype where getSpecific s mt | mt == mtRversion = do t <- getWord16le ms <- getWord32le ss <- getWord16le v <- getRemainingLazyByteString return $ MessageClient $ Rversion {size=s, mtype=mt, tag=t, msize=ms, ssize=ss, version=v} The good news is I'm talking 9P otherwise, correctly, just having some decoding issues. I hope to have a hackage package eventually for this. Dave -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090602/a1f191e9/attachment.html From vanenkj at gmail.com Tue Jun 2 12:32:48 2009 From: vanenkj at gmail.com (John Van Enk) Date: Tue Jun 2 12:16:48 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> Message-ID: I think getRemainingLazyByteString expects at least one byte (this, perhaps, is not the appropriate behavior). You'll want to wrap your call to getRemainingLazyByteString with a call to Data.Binary.Get.remaining[1] like this: foo = do r <- remaining rbs <- case r of 0 -> return empty -- Data.ByteString.Lazy.empty _ -> getRemainingLazyByteString Hope this helps. :) /jve 1: http://hackage.haskell.org/packages/archive/binary/0.5.0.1/doc/html/Data-Binary-Get.html#v%3Aremaining On Tue, Jun 2, 2009 at 12:20 PM, David Leimbach wrote: > I've got the following "printHex" ?string as a response from a 9P server > running on the Inferno Operating System. (thanks to a friendly mailing list > contributor who sent a nice example of using Data.Binary) > 1300000065ffff000400000600395032303030 > This is a little endian encoded ByteString with the following fields in it: > ?Rversion {size :: Word32, > ?? ? ? ? ? ? ? ?mtype :: Word8, > ?? ? ? ? ? ? ? ?tag :: Word16, > ?? ? ? ? ? ? ? ?msize :: Word32, > ?? ? ? ? ? ? ? ?ssize :: Word16, > ?? ? ? ? ? ? ? ?version :: ByteString} > But when I try to use the following implementation of "get" to decode this > stream, I'm getting the following error: > "too few bytes. Failed reading at byte position 20" > Unfortunately, I'm only expecting 19 bytes, and in fact never asked for byte > 20. ?(I am just asking for everything up to ssize, and then > "getRemainingLazyByteString"). > Is this a bug? ? ?Is it mine or in Data.Binary? ?:-) > Here's my "get" function: > ?get = do s <- getWord32le > ?? ? ? ? ? ? mtype <- getWord8 > ?? ? ? ? ? ? getSpecific s mtype > ?? ? ? ?where > ?? ? ? ? ?getSpecific s mt > ?? ? ? ? ? ? ? ? ? ? ?| mt == mtRversion = do t <- getWord16le > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?v <- > getRemainingLazyByteString > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return $ MessageClient $ > Rversion {size=s, > > ? ? ? ? ? ? ? ? ? ? ? ? mtype=mt, > > ? ? ? ? ? ? ? ? ? ? ? ? tag=t, > > ? ? ? ? ? ? ? ? ? ? ? ? msize=ms, > > ? ? ? ? ? ? ? ? ? ? ? ? ssize=ss, > > ? ? ? ? ? ? ? ? ? ? ? ? version=v} > > > The good news is I'm talking 9P otherwise, correctly, just having some > decoding issues. ?I hope to have a hackage package eventually for this. > Dave > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- /jve From thomas.dubuisson at gmail.com Tue Jun 2 13:24:51 2009 From: thomas.dubuisson at gmail.com (Thomas DuBuisson) Date: Tue Jun 2 13:08:51 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> Message-ID: <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> > I think getRemainingLazyByteString expects at least one byte No, it works with an empty bytestring. Or, my tests do with binary 0.5.0.1. The specific error means you are requiring more data than providing. First check the length of the bytestring you pass in to the to level decode (or 'get') routine and walk though that to figure out how much it should be consuming. I notice you have a guard on the 'getSpecific' function, hopefully you're sure the case you gave us is the branch being taken. I think the issue isn't with the code provided. I cleaned up the code (which did change behavior due to the guard and data declarations that weren't in the mailling) and it works fine all the way down to the expected minimum of 13 bytes. > import Data.ByteString.Lazy > import Data.Binary > import Data.Binary.Get > > data RV = > Rversion { size :: Word32, > mtype :: Word8, > tag :: Word16, > msize :: Word32, > ssize :: Word16, > version :: ByteString} > deriving (Eq, Ord, Show) > instance Binary RV where > get = do s <- getWord32le > mtype <- getWord8 > getSpecific s mtype > where > getSpecific s mt = do t <- getWord16le > ms <- getWord32le > ss <- getWord16le > v <- getRemainingLazyByteString > return $ Rversion {size=s, > mtype=mt, > tag=t, > msize=ms, > ssize=ss, > version=v } > put _ = undefined From vanenkj at gmail.com Tue Jun 2 13:51:10 2009 From: vanenkj at gmail.com (John Van Enk) Date: Tue Jun 2 13:35:18 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> Message-ID: Thomas, You're correct. For some reason, I based my advice on the thought that 19 was the minimum size instead of 13. On Tue, Jun 2, 2009 at 1:24 PM, Thomas DuBuisson wrote: >> I think getRemainingLazyByteString expects at least one byte > No, it works with an empty bytestring. ?Or, my tests do with binary 0.5.0.1. > > The specific error means you are requiring more data than providing. > First check the length of the bytestring you pass in to the to level > decode (or 'get') routine and walk though that to figure out how much > it should be consuming. ?I notice you have a guard on the > 'getSpecific' function, hopefully you're sure the case you gave us is > the branch being taken. > > I think the issue isn't with the code provided. ?I cleaned up the code > (which did change behavior due to the guard and data declarations that > weren't in the mailling) and it works fine all the way down to the > expected minimum of 13 bytes. > > >> import Data.ByteString.Lazy >> import Data.Binary >> import Data.Binary.Get >> >> data RV = >> Rversion { ? ? size ? :: Word32, >> ? ? ? ? ? ? ? ?mtype ?:: Word8, >> ? ? ? ? ? ? ? ?tag ? ?:: Word16, >> ? ? ? ? ? ? ? ?msize ?:: Word32, >> ? ? ? ? ? ? ? ?ssize ?:: Word16, >> ? ? ? ? ? ? ? ?version :: ByteString} >> ? ? ? deriving (Eq, Ord, Show) > >> instance Binary RV where >> ?get = do s <- getWord32le >> ? ? ? ? ?mtype <- getWord8 >> ? ? ? ? ?getSpecific s mtype >> ? where >> ? ?getSpecific s mt = do t <- getWord16le >> ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le >> ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le >> ? ? ? ? ? ? ? ? ? ? ? ? ?v <- getRemainingLazyByteString >> ? ? ? ? ? ? ? ? ? ? ? ? ?return $ Rversion {size=s, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mtype=mt, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tag=t, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? msize=ms, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ssize=ss, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? version=v } >> ?put _ = undefined > -- /jve From ryani.spam at gmail.com Tue Jun 2 15:11:53 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Tue Jun 2 14:55:58 2009 Subject: [Haskell-cafe] Checking a value against a passed-in constructor? In-Reply-To: <20090602115032.686ebc76@dan-laptop> References: <9F110BD7-C9AA-4007-ADAA-2690513690D1@cs.otago.ac.nz> <20090602115032.686ebc76@dan-laptop> Message-ID: <2f9b2d30906021211o4a012674kd9a01ee51dbc80d1@mail.gmail.com> On Tue, Jun 2, 2009 at 3:50 AM, Dan wrote: > You hit the nail on the head. ?"Why I am doing this" is because of > boilerplate. Boilerplate gives me rashes and bulbous spots on the nose. > > Consider the following Ruby code: > > ? ? ? ?def check(zeClass, zeValue) > ? ? ? ? ? ? ? ?zeValue.is_a? zeClass > ? ? ? ?end > > This does not require a new function for every class defined in Ruby. > (To be fair, though, the class of a Ruby object tells you precious > little, compared to a Haskell type constructor). > > I figured there would be a clever Haskell idiom that would give me a > similarly concise route. Does it really require Template Haskell? I can > barely parse regular Haskell as it is.. So the question is, why do you need to know if x is an Atom or a Bool? The Haskell idiom is to pattern match and just do what you want with the data: f (Atom s) = ... f (Bool b) = ... instead of f x = if isAtom x then ... atomData x ... else ... boolData x ... Alternatively, you can define a fold[1] once: myval :: MyVal -> (Bool -> a) -> (String -> a) -> a myval (Bool b) bool atom = bool b myval (Atom s) bool atom = atom s f x = myval bool atom where bool b = ... atom s = ... This is a small amount of boilerplate that you write once for each type; it's possible to automate it with TH, but usually it's not worth it, in my opinion. Coming from Ruby (the same route I took to get to Haskell!), you should be aware that Haskell does have somewhat more "boilerplate" than Ruby, but it has its benefits as well. I am a convert to the Church of Purity and Type-Safety :) And you can use type classes for many metaprogramming tasks. -- ryan [1] "fold" here is the general term for this type of function. Examples are foldr: http://haskell.org/ghc/docs/latest/html/libraries/base/src/GHC-Base.html#foldr maybe: http://haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Maybe.html#maybe either: http://haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Either.html#either From gue.schmidt at web.de Tue Jun 2 16:11:15 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Tue Jun 2 15:55:29 2009 Subject: [Haskell-cafe] Compiling a windows app - embedding a manifest Message-ID: Hi all, is it possible to make ghc embedd a particular manifest in the .exe during the compilation process? G?nther From leimy2k at gmail.com Tue Jun 2 16:20:59 2009 From: leimy2k at gmail.com (David Leimbach) Date: Tue Jun 2 16:04:58 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> Message-ID: <3e1162e60906021320r1937f22er284154ed56861e7d@mail.gmail.com> The thing is I have 19 bytes in the hex string I provided: 1300000065ffff000400000600395032303030 That's 38 characters or 19 bytes. The last 4 are 9P2000 13000000 = 4 bytes for 32bit message payload, This is little endian for 19 bytes total. 65 = 1 byte for message type. 65 is "Rversion" or the response type for a Tversion request ffff = 2 bytes for 16bit message "tag". 00040000 = 4 bytes for the 32 bit maximum message payload size I'm negotiating with the 9P server. This is little endian for 1024 0600 = 2 bytes for 16 bit value for the length of the "string" I'm sending. The strings are *NOT* null terminated in 9p, and this is little endian for 6 bytes remaining. 5032303030 = 6 bytes the ASCII or UTF-8 string "9P2000" which is 6 bytes 4 + 1 + 2 + 4 + 2 + 6 = 19 bytes. As far as I can see, my "get" code does NOT ask for a 20th byte, so why am I getting that error? get = do s <- getWord32le -- 4 mtype <- getWord8 -- 1 getSpecific s mtype where getSpecific s mt | mt == mtRversion = do t <- getWord16le -- 2 ms <- getWord32le -- 4 ss <- getWord16le -- 2 v <- getRemainingLazyByteString -- remaining should be 6 bytes. return $ MessageClient $ Rversion {size=s, mtype=mt, tag=t, msize=ms, ssize=ss, version=v} Should I file a bug? I don't believe I should be seeing an error message claiming a failure at the 20th byte when I've never asked for one. Dave On Tue, Jun 2, 2009 at 10:51 AM, John Van Enk wrote: > Thomas, > > You're correct. For some reason, I based my advice on the thought that > 19 was the minimum size instead of 13. > > On Tue, Jun 2, 2009 at 1:24 PM, Thomas DuBuisson > wrote: > >> I think getRemainingLazyByteString expects at least one byte > > No, it works with an empty bytestring. Or, my tests do with binary > 0.5.0.1. > > > > The specific error means you are requiring more data than providing. > > First check the length of the bytestring you pass in to the to level > > decode (or 'get') routine and walk though that to figure out how much > > it should be consuming. I notice you have a guard on the > > 'getSpecific' function, hopefully you're sure the case you gave us is > > the branch being taken. > > > > I think the issue isn't with the code provided. I cleaned up the code > > (which did change behavior due to the guard and data declarations that > > weren't in the mailling) and it works fine all the way down to the > > expected minimum of 13 bytes. > > > > > >> import Data.ByteString.Lazy > >> import Data.Binary > >> import Data.Binary.Get > >> > >> data RV = > >> Rversion { size :: Word32, > >> mtype :: Word8, > >> tag :: Word16, > >> msize :: Word32, > >> ssize :: Word16, > >> version :: ByteString} > >> deriving (Eq, Ord, Show) > > > >> instance Binary RV where > >> get = do s <- getWord32le > >> mtype <- getWord8 > >> getSpecific s mtype > >> where > >> getSpecific s mt = do t <- getWord16le > >> ms <- getWord32le > >> ss <- getWord16le > >> v <- getRemainingLazyByteString > >> return $ Rversion {size=s, > >> mtype=mt, > >> tag=t, > >> msize=ms, > >> ssize=ss, > >> version=v } > >> put _ = undefined > > > > > > -- > /jve > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090602/2548ca08/attachment.html From vanenkj at gmail.com Tue Jun 2 16:28:43 2009 From: vanenkj at gmail.com (John Van Enk) Date: Tue Jun 2 16:12:46 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: <3e1162e60906021320r1937f22er284154ed56861e7d@mail.gmail.com> References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> <3e1162e60906021320r1937f22er284154ed56861e7d@mail.gmail.com> Message-ID: I think Thomas' point was that some other branch in `getSpecific' is running. Is there a chance we can see the rest of `getSpecific'? On Tue, Jun 2, 2009 at 4:20 PM, David Leimbach wrote: > The thing is I have 19 bytes in the hex string I provided: > 1300000065ffff000400000600395032303030 > That's 38 characters or 19 bytes. > The last 4 are 9P2000 > 13000000 ?= 4 bytes for 32bit message payload, ?This is little endian for 19 > bytes total. > 65 = 1 byte for message type. ?65 is "Rversion" or the response type for a > Tversion request > ffff = 2 bytes for 16bit message "tag". > > 00040000 = 4 bytes for the 32 bit maximum message payload size I'm > negotiating with the 9P server. ?This is little endian for 1024 > 0600 = ?2?bytes for 16 bit value for the length of the "string" I'm sending. > ?The strings are *NOT* null terminated in 9p, and this is little endian for > 6 bytes remaining. > 5032303030 = 6 bytes the ASCII or UTF-8 string "9P2000" which is 6 bytes > 4 + 1 + 2 + 4 + 2 + 6 = 19 bytes. > As far as I can see, my "get" code does NOT ask for a 20th byte, so why am I > getting that error? > get = do s <- getWord32le ?-- 4 > ?? ? ? ? ? ? mtype <- getWord8 ?-- 1 > ?? ? ? ? ? ? getSpecific s mtype > ?? ? ? ?where > ?? ? ? ? ?getSpecific s mt > ?? ? ? ? ? ? ? ? ? ? ?| mt == mtRversion = do t <- getWord16le -- 2 > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le ?-- 4 > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le -- 2 > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?v <- > getRemainingLazyByteString ?-- remaining should be 6 bytes. > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return $ MessageClient $ > Rversion {size=s, > > ? ? ? ? ? ? ? ? ? ? ? ? mtype=mt, > > ? ? ? ? ? ? ? ? ? ? ? ? tag=t, > > ? ? ? ? ? ? ? ? ? ? ? ? msize=ms, > > ? ? ? ? ? ? ? ? ? ? ? ? ssize=ss, > > ? ? ? ? ? ? ? ? ? ? ? ? version=v} > Should I file a bug? ?I don't believe I should be seeing an error message > claiming a failure at the 20th byte when I've never asked for one. > Dave > > On Tue, Jun 2, 2009 at 10:51 AM, John Van Enk wrote: >> >> Thomas, >> >> You're correct. For some reason, I based my advice on the thought that >> 19 was the minimum size instead of 13. >> >> On Tue, Jun 2, 2009 at 1:24 PM, Thomas DuBuisson >> wrote: >> >> I think getRemainingLazyByteString expects at least one byte >> > No, it works with an empty bytestring. ?Or, my tests do with binary >> > 0.5.0.1. >> > >> > The specific error means you are requiring more data than providing. >> > First check the length of the bytestring you pass in to the to level >> > decode (or 'get') routine and walk though that to figure out how much >> > it should be consuming. ?I notice you have a guard on the >> > 'getSpecific' function, hopefully you're sure the case you gave us is >> > the branch being taken. >> > >> > I think the issue isn't with the code provided. ?I cleaned up the code >> > (which did change behavior due to the guard and data declarations that >> > weren't in the mailling) and it works fine all the way down to the >> > expected minimum of 13 bytes. >> > >> > >> >> import Data.ByteString.Lazy >> >> import Data.Binary >> >> import Data.Binary.Get >> >> >> >> data RV = >> >> Rversion { ? ? size ? :: Word32, >> >> ? ? ? ? ? ? ? ?mtype ?:: Word8, >> >> ? ? ? ? ? ? ? ?tag ? ?:: Word16, >> >> ? ? ? ? ? ? ? ?msize ?:: Word32, >> >> ? ? ? ? ? ? ? ?ssize ?:: Word16, >> >> ? ? ? ? ? ? ? ?version :: ByteString} >> >> ? ? ? deriving (Eq, Ord, Show) >> > >> >> instance Binary RV where >> >> ?get = do s <- getWord32le >> >> ? ? ? ? ?mtype <- getWord8 >> >> ? ? ? ? ?getSpecific s mtype >> >> ? where >> >> ? ?getSpecific s mt = do t <- getWord16le >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?v <- getRemainingLazyByteString >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?return $ Rversion {size=s, >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mtype=mt, >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tag=t, >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? msize=ms, >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ssize=ss, >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? version=v } >> >> ?put _ = undefined >> > >> >> >> >> -- >> /jve > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- /jve From leimy2k at gmail.com Tue Jun 2 16:28:42 2009 From: leimy2k at gmail.com (David Leimbach) Date: Tue Jun 2 16:12:47 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> Message-ID: <3e1162e60906021328w36253b8ala2fc2e905883ca33@mail.gmail.com> On Tue, Jun 2, 2009 at 10:24 AM, Thomas DuBuisson < thomas.dubuisson@gmail.com> wrote: > > I think getRemainingLazyByteString expects at least one byte > No, it works with an empty bytestring. Or, my tests do with binary > 0.5.0.1. > > The specific error means you are requiring more data than providing. I've shown that I am not trying to decode more than I'm providing. I've asked, expliciitly, for 13 bytes, and then "remaining", and the library is complaining about the 20th byte. > > First check the length of the bytestring you pass in to the to level > decode (or 'get') routine and walk though that to figure out how much > it should be consuming. I notice you have a guard on the > 'getSpecific' function, hopefully you're sure the case you gave us is > the branch being taken. The other branch is Rerror, which is a shorter message decode stream. Unfortunately, I can't get Debug.Trace to show anything to prove it's taking this fork of the code. I suppose I could unsafePerformIO :-) Perhaps I just need a new version of "binary"?? I'll give it a go and try your version. But I need to decode over a dozen message types, so I will need a case or guard or something. Dave > > I think the issue isn't with the code provided. I cleaned up the code > (which did change behavior due to the guard and data declarations that > weren't in the mailling) and it works fine all the way down to the > expected minimum of 13 bytes. > > > > import Data.ByteString.Lazy > > import Data.Binary > > import Data.Binary.Get > > > > data RV = > > Rversion { size :: Word32, > > mtype :: Word8, > > tag :: Word16, > > msize :: Word32, > > ssize :: Word16, > > version :: ByteString} > > deriving (Eq, Ord, Show) > > > instance Binary RV where > > get = do s <- getWord32le > > mtype <- getWord8 > > getSpecific s mtype > > where > > getSpecific s mt = do t <- getWord16le > > ms <- getWord32le > > ss <- getWord16le > > v <- getRemainingLazyByteString > > return $ Rversion {size=s, > > mtype=mt, > > tag=t, > > msize=ms, > > ssize=ss, > > version=v } > > put _ = undefined > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090602/e3ba82b3/attachment.html From leimy2k at gmail.com Tue Jun 2 16:31:26 2009 From: leimy2k at gmail.com (David Leimbach) Date: Tue Jun 2 16:15:25 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> <3e1162e60906021320r1937f22er284154ed56861e7d@mail.gmail.com> Message-ID: <3e1162e60906021331u5f26433at83a94fc190a3c388@mail.gmail.com> On Tue, Jun 2, 2009 at 1:28 PM, John Van Enk wrote: > I think Thomas' point was that some other branch in `getSpecific' is > running. Is there a chance we can see the rest of `getSpecific'? Sure: (In the meantime, I'll try the suggested code from before) get = do s <- getWord32le mtype <- getWord8 getSpecific s mtype where getSpecific s mt | mt == mtRversion = do t <- getWord16le ms <- getWord32le ss <- getWord16le v <- getRemainingLazyByteString return $ MessageClient $ Rversion {size=s, mtype=mt, tag=t, msize=ms, ssize=ss, version=v} | mt == mtRerror = do t <- getWord16le ss <- getWord16le e <- getLazyByteString $ fromIntegral ss return $ MessageClient $ Rerror {size=s, mtype=mt, tag=t, ssize=ss, ename=e} > > > On Tue, Jun 2, 2009 at 4:20 PM, David Leimbach wrote: > > The thing is I have 19 bytes in the hex string I provided: > > 1300000065ffff000400000600395032303030 > > That's 38 characters or 19 bytes. > > The last 4 are 9P2000 > > 13000000 = 4 bytes for 32bit message payload, This is little endian for > 19 > > bytes total. > > 65 = 1 byte for message type. 65 is "Rversion" or the response type for > a > > Tversion request > > ffff = 2 bytes for 16bit message "tag". > > > > 00040000 = 4 bytes for the 32 bit maximum message payload size I'm > > negotiating with the 9P server. This is little endian for 1024 > > 0600 = 2 bytes for 16 bit value for the length of the "string" I'm > sending. > > The strings are *NOT* null terminated in 9p, and this is little endian > for > > 6 bytes remaining. > > 5032303030 = 6 bytes the ASCII or UTF-8 string "9P2000" which is 6 bytes > > 4 + 1 + 2 + 4 + 2 + 6 = 19 bytes. > > As far as I can see, my "get" code does NOT ask for a 20th byte, so why > am I > > getting that error? > > get = do s <- getWord32le -- 4 > > mtype <- getWord8 -- 1 > > getSpecific s mtype > > where > > getSpecific s mt > > | mt == mtRversion = do t <- getWord16le -- 2 > > ms <- getWord32le -- 4 > > ss <- getWord16le -- 2 > > v <- > > getRemainingLazyByteString -- remaining should be 6 bytes. > > return $ MessageClient $ > > Rversion {size=s, > > > > mtype=mt, > > > > tag=t, > > > > msize=ms, > > > > ssize=ss, > > > > version=v} > > Should I file a bug? I don't believe I should be seeing an error message > > claiming a failure at the 20th byte when I've never asked for one. > > Dave > > > > On Tue, Jun 2, 2009 at 10:51 AM, John Van Enk wrote: > >> > >> Thomas, > >> > >> You're correct. For some reason, I based my advice on the thought that > >> 19 was the minimum size instead of 13. > >> > >> On Tue, Jun 2, 2009 at 1:24 PM, Thomas DuBuisson > >> wrote: > >> >> I think getRemainingLazyByteString expects at least one byte > >> > No, it works with an empty bytestring. Or, my tests do with binary > >> > 0.5.0.1. > >> > > >> > The specific error means you are requiring more data than providing. > >> > First check the length of the bytestring you pass in to the to level > >> > decode (or 'get') routine and walk though that to figure out how much > >> > it should be consuming. I notice you have a guard on the > >> > 'getSpecific' function, hopefully you're sure the case you gave us is > >> > the branch being taken. > >> > > >> > I think the issue isn't with the code provided. I cleaned up the code > >> > (which did change behavior due to the guard and data declarations that > >> > weren't in the mailling) and it works fine all the way down to the > >> > expected minimum of 13 bytes. > >> > > >> > > >> >> import Data.ByteString.Lazy > >> >> import Data.Binary > >> >> import Data.Binary.Get > >> >> > >> >> data RV = > >> >> Rversion { size :: Word32, > >> >> mtype :: Word8, > >> >> tag :: Word16, > >> >> msize :: Word32, > >> >> ssize :: Word16, > >> >> version :: ByteString} > >> >> deriving (Eq, Ord, Show) > >> > > >> >> instance Binary RV where > >> >> get = do s <- getWord32le > >> >> mtype <- getWord8 > >> >> getSpecific s mtype > >> >> where > >> >> getSpecific s mt = do t <- getWord16le > >> >> ms <- getWord32le > >> >> ss <- getWord16le > >> >> v <- getRemainingLazyByteString > >> >> return $ Rversion {size=s, > >> >> mtype=mt, > >> >> tag=t, > >> >> msize=ms, > >> >> ssize=ss, > >> >> version=v } > >> >> put _ = undefined > >> > > >> > >> > >> > >> -- > >> /jve > > > > > > _______________________________________________ > > Haskell-Cafe mailing list > > Haskell-Cafe@haskell.org > > http://www.haskell.org/mailman/listinfo/haskell-cafe > > > > > > > > -- > /jve > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090602/ad715770/attachment.html From vanenkj at gmail.com Tue Jun 2 16:32:58 2009 From: vanenkj at gmail.com (John Van Enk) Date: Tue Jun 2 16:16:57 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: <3e1162e60906021328w36253b8ala2fc2e905883ca33@mail.gmail.com> References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> <3e1162e60906021328w36253b8ala2fc2e905883ca33@mail.gmail.com> Message-ID: Perhaps there's some place in your code that's forcing the lazy read to consume more. Perhaps you could replace it with an explict (and strict) getBytes[1] in combination with remaining[2]? Is there a reason you want to use lazy byte strings rather than forcing full consumption? Do the 9P packets generally have a lot of trailing useless data? 1. http://hackage.haskell.org/packages/archive/binary/0.5.0.1/doc/html/Data-Binary-Get.html#v%3AgetBytes 2. http://hackage.haskell.org/packages/archive/binary/0.5.0.1/doc/html/Data-Binary-Get.html#v%3Aremaining On Tue, Jun 2, 2009 at 4:28 PM, David Leimbach wrote: > > > On Tue, Jun 2, 2009 at 10:24 AM, Thomas DuBuisson > wrote: >> >> > I think getRemainingLazyByteString expects at least one byte >> No, it works with an empty bytestring. ?Or, my tests do with binary >> 0.5.0.1. >> >> The specific error means you are requiring more data than providing. > > I've shown that I am not trying to decode more than I'm providing. ?I've > asked, expliciitly, for 13 bytes, and then "remaining", and the library is > complaining about the 20th byte. > >> >> First check the length of the bytestring you pass in to the to level >> decode (or 'get') routine and walk though that to figure out how much >> it should be consuming. ?I notice you have a guard on the >> 'getSpecific' function, hopefully you're sure the case you gave us is >> the branch being taken. > > The other branch is Rerror, which is a shorter message decode stream. > ?Unfortunately, I can't get Debug.Trace to show anything to prove it's > taking this fork of the code. ?I suppose I could unsafePerformIO :-) > Perhaps I just need a new version of "binary"?? ?I'll give it a go and try > your version. ?But I need to decode over a dozen message types, so I will > need a case or guard or something. > Dave >> >> >> I think the issue isn't with the code provided. ?I cleaned up the code >> (which did change behavior due to the guard and data declarations that >> weren't in the mailling) and it works fine all the way down to the >> expected minimum of 13 bytes. >> >> >> > import Data.ByteString.Lazy >> > import Data.Binary >> > import Data.Binary.Get >> > >> > data RV = >> > Rversion { ? ? size ? :: Word32, >> > ? ? ? ? ? ? ? ?mtype ?:: Word8, >> > ? ? ? ? ? ? ? ?tag ? ?:: Word16, >> > ? ? ? ? ? ? ? ?msize ?:: Word32, >> > ? ? ? ? ? ? ? ?ssize ?:: Word16, >> > ? ? ? ? ? ? ? ?version :: ByteString} >> > ? ? ? deriving (Eq, Ord, Show) >> >> > instance Binary RV where >> > ?get = do s <- getWord32le >> > ? ? ? ? ?mtype <- getWord8 >> > ? ? ? ? ?getSpecific s mtype >> > ? where >> > ? ?getSpecific s mt = do t <- getWord16le >> > ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le >> > ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le >> > ? ? ? ? ? ? ? ? ? ? ? ? ?v <- getRemainingLazyByteString >> > ? ? ? ? ? ? ? ? ? ? ? ? ?return $ Rversion {size=s, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mtype=mt, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tag=t, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? msize=ms, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ssize=ss, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? version=v } >> > ?put _ = undefined > > -- /jve From vanenkj at gmail.com Tue Jun 2 16:36:43 2009 From: vanenkj at gmail.com (John Van Enk) Date: Tue Jun 2 16:20:42 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: <3e1162e60906021331u5f26433at83a94fc190a3c388@mail.gmail.com> References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> <3e1162e60906021320r1937f22er284154ed56861e7d@mail.gmail.com> <3e1162e60906021331u5f26433at83a94fc190a3c388@mail.gmail.com> Message-ID: What happens if you use `getRemainingLazyByteString' in your error branch instead of `getLazyByteString'? On Tue, Jun 2, 2009 at 4:31 PM, David Leimbach wrote: > > > On Tue, Jun 2, 2009 at 1:28 PM, John Van Enk wrote: >> >> I think Thomas' point was that some other branch in `getSpecific' is >> running. Is there a chance we can see the rest of `getSpecific'? > > Sure: ?(In the meantime, I'll try the suggested code from before) > ?get = do s <- getWord32le > ?? ? ? ? ? ? mtype <- getWord8 > ?? ? ? ? ? ? getSpecific s mtype > ?? ? ? ?where > ?? ? ? ? ?getSpecific s mt > ?? ? ? ? ? ? ? ? ? ? ?| mt == mtRversion = do t <- getWord16le > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?v <- > getRemainingLazyByteString > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return $ MessageClient $ > Rversion {size=s, > > ? ? mtype=mt, > > ? ? tag=t, > > ? ? msize=ms, > > ? ? ssize=ss, > > ? ? version=v} > ?? ? ? ? ? ? ? ? ? ? ?| mt == mtRerror = do t <- getWord16le > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?e <- getLazyByteString $ > fromIntegral ss > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return $ MessageClient $ Rerror > {size=s, > > mtype=mt, > > tag=t, > > ssize=ss, > > ename=e} > >> >> On Tue, Jun 2, 2009 at 4:20 PM, David Leimbach wrote: >> > The thing is I have 19 bytes in the hex string I provided: >> > 1300000065ffff000400000600395032303030 >> > That's 38 characters or 19 bytes. >> > The last 4 are 9P2000 >> > 13000000 ?= 4 bytes for 32bit message payload, ?This is little endian >> > for 19 >> > bytes total. >> > 65 = 1 byte for message type. ?65 is "Rversion" or the response type for >> > a >> > Tversion request >> > ffff = 2 bytes for 16bit message "tag". >> > >> > 00040000 = 4 bytes for the 32 bit maximum message payload size I'm >> > negotiating with the 9P server. ?This is little endian for 1024 >> > 0600 = ?2?bytes for 16 bit value for the length of the "string" I'm >> > sending. >> > ?The strings are *NOT* null terminated in 9p, and this is little endian >> > for >> > 6 bytes remaining. >> > 5032303030 = 6 bytes the ASCII or UTF-8 string "9P2000" which is 6 bytes >> > 4 + 1 + 2 + 4 + 2 + 6 = 19 bytes. >> > As far as I can see, my "get" code does NOT ask for a 20th byte, so why >> > am I >> > getting that error? >> > get = do s <- getWord32le ?-- 4 >> > ?? ? ? ? ? ? mtype <- getWord8 ?-- 1 >> > ?? ? ? ? ? ? getSpecific s mtype >> > ?? ? ? ?where >> > ?? ? ? ? ?getSpecific s mt >> > ?? ? ? ? ? ? ? ? ? ? ?| mt == mtRversion = do t <- getWord16le -- 2 >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le ?-- 4 >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le -- 2 >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?v <- >> > getRemainingLazyByteString ?-- remaining should be 6 bytes. >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return $ MessageClient $ >> > Rversion {size=s, >> > >> > ? ? ? ? ? ? ? ? ? ? ? ? mtype=mt, >> > >> > ? ? ? ? ? ? ? ? ? ? ? ? tag=t, >> > >> > ? ? ? ? ? ? ? ? ? ? ? ? msize=ms, >> > >> > ? ? ? ? ? ? ? ? ? ? ? ? ssize=ss, >> > >> > ? ? ? ? ? ? ? ? ? ? ? ? version=v} >> > Should I file a bug? ?I don't believe I should be seeing an error >> > message >> > claiming a failure at the 20th byte when I've never asked for one. >> > Dave >> > >> > On Tue, Jun 2, 2009 at 10:51 AM, John Van Enk wrote: >> >> >> >> Thomas, >> >> >> >> You're correct. For some reason, I based my advice on the thought that >> >> 19 was the minimum size instead of 13. >> >> >> >> On Tue, Jun 2, 2009 at 1:24 PM, Thomas DuBuisson >> >> wrote: >> >> >> I think getRemainingLazyByteString expects at least one byte >> >> > No, it works with an empty bytestring. ?Or, my tests do with binary >> >> > 0.5.0.1. >> >> > >> >> > The specific error means you are requiring more data than providing. >> >> > First check the length of the bytestring you pass in to the to level >> >> > decode (or 'get') routine and walk though that to figure out how much >> >> > it should be consuming. ?I notice you have a guard on the >> >> > 'getSpecific' function, hopefully you're sure the case you gave us is >> >> > the branch being taken. >> >> > >> >> > I think the issue isn't with the code provided. ?I cleaned up the >> >> > code >> >> > (which did change behavior due to the guard and data declarations >> >> > that >> >> > weren't in the mailling) and it works fine all the way down to the >> >> > expected minimum of 13 bytes. >> >> > >> >> > >> >> >> import Data.ByteString.Lazy >> >> >> import Data.Binary >> >> >> import Data.Binary.Get >> >> >> >> >> >> data RV = >> >> >> Rversion { ? ? size ? :: Word32, >> >> >> ? ? ? ? ? ? ? ?mtype ?:: Word8, >> >> >> ? ? ? ? ? ? ? ?tag ? ?:: Word16, >> >> >> ? ? ? ? ? ? ? ?msize ?:: Word32, >> >> >> ? ? ? ? ? ? ? ?ssize ?:: Word16, >> >> >> ? ? ? ? ? ? ? ?version :: ByteString} >> >> >> ? ? ? deriving (Eq, Ord, Show) >> >> > >> >> >> instance Binary RV where >> >> >> ?get = do s <- getWord32le >> >> >> ? ? ? ? ?mtype <- getWord8 >> >> >> ? ? ? ? ?getSpecific s mtype >> >> >> ? where >> >> >> ? ?getSpecific s mt = do t <- getWord16le >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?v <- getRemainingLazyByteString >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?return $ Rversion {size=s, >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mtype=mt, >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tag=t, >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? msize=ms, >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ssize=ss, >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? version=v } >> >> >> ?put _ = undefined >> >> > >> >> >> >> >> >> >> >> -- >> >> /jve >> > >> > >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > Haskell-Cafe@haskell.org >> > http://www.haskell.org/mailman/listinfo/haskell-cafe >> > >> > >> >> >> >> -- >> /jve > > -- /jve From kowey at darcs.net Tue Jun 2 16:42:45 2009 From: kowey at darcs.net (Eric Kow) Date: Tue Jun 2 16:26:48 2009 Subject: [Haskell-cafe] code reviewers wanted for hashed-storage (darcs) Message-ID: <20090602204245.GB216@dewdrop.local> Dear Haskellers, Will you have a few spare hours this summer? The Darcs team needs your help! Summary ------- We need two volunteers to help us review the standalone hashed-storage module, which will be used by Darcs in the future. Background ---------- Darcs supports 'hashed' repositories in which each file in the pristine cache is associated with a cryptographic hash. Hashed repositories help Darcs to resist some forms of corruption and also allow for nice features such as a global patch cache and lazy patch fetching. Unfortunately, our implementation can be rather slow. Petr has some nice ideas for making these repositories work a lot faster. He will be producing a library he calls 'hashed-storage' which generalises the idea of storing files associating them with a cryptographic hash and furthermore improves on the current implementation used by Darcs. The hashed-storage library is general purpose and may find a use in other applications that need to manage a large number of files. I'm excited about this project because if it succeeds, we can finally start hammering home the point that yes, Darcs *can* be a fast revision control system. It may not fix all our problems -- we'll still need a Darcs 3 -- but it should alleviate at least some of the practical day to day issues. I want to ensure that Petr's project is a success. One thing in particular is that I would like him to get regular code review from the Haskell community, perhaps from folks who aren't already on the Darcs team. Do you think you can help? Two volunteers needed --------------------- I'm looking for just two volunteers this summer: 1. Do you have one hour per week this summer? We need somebody to track and make comments on changes to hashed-storage over this summer. The current library has only 8 modules, with less than 1400 lines of code, so it should be relatively easy to get started :-) 2. Do you have a spare weekend in August? Towards the end of the summer, it would be nice to have somebody examine the "final" version of hashed-storage and give us their thoughts. Again, no Darcs experience is needed, as this is a standalone module. In fact, a fresh perspective would be very helpful. More information ---------------- You can download hashed-storage from hackage from his darcs repository: darcs get http://repos.mornfall.net/hashed-storage For more information about his project, see http://web.mornfall.net/blog/summer_of_code.html Please get in touch with me if you can help. Thanks! Eric -- Eric Kow PGP Key ID: 08AC04F9 -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 194 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090602/8ff1d3d5/attachment.bin From bulat.ziganshin at gmail.com Tue Jun 2 16:43:33 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Tue Jun 2 16:27:39 2009 Subject: [Haskell-cafe] Compiling a windows app - embedding a manifest In-Reply-To: References: Message-ID: <228227763.20090603004333@gmail.com> Hello Gu?nther, Wednesday, June 3, 2009, 12:11:15 AM, you wrote: > Hi all, > is it possible to make ghc embedd a particular manifest in the .exe > during the compilation process? add to .rc file: 1 24 "app.manifest" and put manifect into app.manifest -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From leimy2k at gmail.com Tue Jun 2 16:45:33 2009 From: leimy2k at gmail.com (David Leimbach) Date: Tue Jun 2 16:29:34 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> <3e1162e60906021328w36253b8ala2fc2e905883ca33@mail.gmail.com> Message-ID: <3e1162e60906021345g53a1787h25f1dee6baaf1aff@mail.gmail.com> On Tue, Jun 2, 2009 at 1:32 PM, John Van Enk wrote: > Perhaps there's some place in your code that's forcing the lazy read > to consume more. Perhaps you could replace it with an explict (and > strict) getBytes[1] in combination with remaining[2]? Unfortunately, I'm using a Lazy ByteString network IO lib. So I don't think going to a strict ByteString is going to be possible. > > > Is there a reason you want to use lazy byte strings rather than > forcing full consumption? Do the 9P packets generally have a lot of > trailing useless data? Nope. Just I noticed that there was a Network ByteString package that utilized lazy bytestrings :-). Even if that's why it's going for a 20th byte, shouldn't that be a bug? :-) > > > 1. > http://hackage.haskell.org/packages/archive/binary/0.5.0.1/doc/html/Data-Binary-Get.html#v%3AgetBytes > 2. > http://hackage.haskell.org/packages/archive/binary/0.5.0.1/doc/html/Data-Binary-Get.html#v%3Aremaining > > On Tue, Jun 2, 2009 at 4:28 PM, David Leimbach wrote: > > > > > > On Tue, Jun 2, 2009 at 10:24 AM, Thomas DuBuisson > > wrote: > >> > >> > I think getRemainingLazyByteString expects at least one byte > >> No, it works with an empty bytestring. Or, my tests do with binary > >> 0.5.0.1. > >> > >> The specific error means you are requiring more data than providing. > > > > I've shown that I am not trying to decode more than I'm providing. I've > > asked, expliciitly, for 13 bytes, and then "remaining", and the library > is > > complaining about the 20th byte. > > > >> > >> First check the length of the bytestring you pass in to the to level > >> decode (or 'get') routine and walk though that to figure out how much > >> it should be consuming. I notice you have a guard on the > >> 'getSpecific' function, hopefully you're sure the case you gave us is > >> the branch being taken. > > > > The other branch is Rerror, which is a shorter message decode stream. > > Unfortunately, I can't get Debug.Trace to show anything to prove it's > > taking this fork of the code. I suppose I could unsafePerformIO :-) > > Perhaps I just need a new version of "binary"?? I'll give it a go and > try > > your version. But I need to decode over a dozen message types, so I will > > need a case or guard or something. > > Dave > >> > >> > >> I think the issue isn't with the code provided. I cleaned up the code > >> (which did change behavior due to the guard and data declarations that > >> weren't in the mailling) and it works fine all the way down to the > >> expected minimum of 13 bytes. > >> > >> > >> > import Data.ByteString.Lazy > >> > import Data.Binary > >> > import Data.Binary.Get > >> > > >> > data RV = > >> > Rversion { size :: Word32, > >> > mtype :: Word8, > >> > tag :: Word16, > >> > msize :: Word32, > >> > ssize :: Word16, > >> > version :: ByteString} > >> > deriving (Eq, Ord, Show) > >> > >> > instance Binary RV where > >> > get = do s <- getWord32le > >> > mtype <- getWord8 > >> > getSpecific s mtype > >> > where > >> > getSpecific s mt = do t <- getWord16le > >> > ms <- getWord32le > >> > ss <- getWord16le > >> > v <- getRemainingLazyByteString > >> > return $ Rversion {size=s, > >> > mtype=mt, > >> > tag=t, > >> > msize=ms, > >> > ssize=ss, > >> > version=v } > >> > put _ = undefined > > > > > > > > -- > /jve > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090602/5e2e765f/attachment.html From leimy2k at gmail.com Tue Jun 2 16:46:57 2009 From: leimy2k at gmail.com (David Leimbach) Date: Tue Jun 2 16:30:56 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> <3e1162e60906021320r1937f22er284154ed56861e7d@mail.gmail.com> <3e1162e60906021331u5f26433at83a94fc190a3c388@mail.gmail.com> Message-ID: <3e1162e60906021346n5d7a149fpafcc12326cbdd741@mail.gmail.com> On Tue, Jun 2, 2009 at 1:36 PM, John Van Enk wrote: > What happens if you use `getRemainingLazyByteString' in your error > branch instead of `getLazyByteString'? > I actually am using getRemainingLazyByteString right now, and it still thinks I'm asking for a 20th byte. if I delete the other guarded branch of that function, it still fails saying I'm asking for the 20th byte. Dave > > On Tue, Jun 2, 2009 at 4:31 PM, David Leimbach wrote: > > > > > > On Tue, Jun 2, 2009 at 1:28 PM, John Van Enk wrote: > >> > >> I think Thomas' point was that some other branch in `getSpecific' is > >> running. Is there a chance we can see the rest of `getSpecific'? > > > > Sure: (In the meantime, I'll try the suggested code from before) > > get = do s <- getWord32le > > mtype <- getWord8 > > getSpecific s mtype > > where > > getSpecific s mt > > | mt == mtRversion = do t <- getWord16le > > ms <- getWord32le > > ss <- getWord16le > > v <- > > getRemainingLazyByteString > > return $ MessageClient $ > > Rversion {size=s, > > > > mtype=mt, > > > > tag=t, > > > > msize=ms, > > > > ssize=ss, > > > > version=v} > > | mt == mtRerror = do t <- getWord16le > > ss <- getWord16le > > e <- getLazyByteString $ > > fromIntegral ss > > return $ MessageClient $ > Rerror > > {size=s, > > > > mtype=mt, > > > > tag=t, > > > > ssize=ss, > > > > ename=e} > > > >> > >> On Tue, Jun 2, 2009 at 4:20 PM, David Leimbach > wrote: > >> > The thing is I have 19 bytes in the hex string I provided: > >> > 1300000065ffff000400000600395032303030 > >> > That's 38 characters or 19 bytes. > >> > The last 4 are 9P2000 > >> > 13000000 = 4 bytes for 32bit message payload, This is little endian > >> > for 19 > >> > bytes total. > >> > 65 = 1 byte for message type. 65 is "Rversion" or the response type > for > >> > a > >> > Tversion request > >> > ffff = 2 bytes for 16bit message "tag". > >> > > >> > 00040000 = 4 bytes for the 32 bit maximum message payload size I'm > >> > negotiating with the 9P server. This is little endian for 1024 > >> > 0600 = 2 bytes for 16 bit value for the length of the "string" I'm > >> > sending. > >> > The strings are *NOT* null terminated in 9p, and this is little > endian > >> > for > >> > 6 bytes remaining. > >> > 5032303030 = 6 bytes the ASCII or UTF-8 string "9P2000" which is 6 > bytes > >> > 4 + 1 + 2 + 4 + 2 + 6 = 19 bytes. > >> > As far as I can see, my "get" code does NOT ask for a 20th byte, so > why > >> > am I > >> > getting that error? > >> > get = do s <- getWord32le -- 4 > >> > mtype <- getWord8 -- 1 > >> > getSpecific s mtype > >> > where > >> > getSpecific s mt > >> > | mt == mtRversion = do t <- getWord16le -- 2 > >> > ms <- getWord32le -- 4 > >> > ss <- getWord16le -- 2 > >> > v <- > >> > getRemainingLazyByteString -- remaining should be 6 bytes. > >> > return $ MessageClient $ > >> > Rversion {size=s, > >> > > >> > mtype=mt, > >> > > >> > tag=t, > >> > > >> > msize=ms, > >> > > >> > ssize=ss, > >> > > >> > version=v} > >> > Should I file a bug? I don't believe I should be seeing an error > >> > message > >> > claiming a failure at the 20th byte when I've never asked for one. > >> > Dave > >> > > >> > On Tue, Jun 2, 2009 at 10:51 AM, John Van Enk > wrote: > >> >> > >> >> Thomas, > >> >> > >> >> You're correct. For some reason, I based my advice on the thought > that > >> >> 19 was the minimum size instead of 13. > >> >> > >> >> On Tue, Jun 2, 2009 at 1:24 PM, Thomas DuBuisson > >> >> wrote: > >> >> >> I think getRemainingLazyByteString expects at least one byte > >> >> > No, it works with an empty bytestring. Or, my tests do with binary > >> >> > 0.5.0.1. > >> >> > > >> >> > The specific error means you are requiring more data than > providing. > >> >> > First check the length of the bytestring you pass in to the to > level > >> >> > decode (or 'get') routine and walk though that to figure out how > much > >> >> > it should be consuming. I notice you have a guard on the > >> >> > 'getSpecific' function, hopefully you're sure the case you gave us > is > >> >> > the branch being taken. > >> >> > > >> >> > I think the issue isn't with the code provided. I cleaned up the > >> >> > code > >> >> > (which did change behavior due to the guard and data declarations > >> >> > that > >> >> > weren't in the mailling) and it works fine all the way down to the > >> >> > expected minimum of 13 bytes. > >> >> > > >> >> > > >> >> >> import Data.ByteString.Lazy > >> >> >> import Data.Binary > >> >> >> import Data.Binary.Get > >> >> >> > >> >> >> data RV = > >> >> >> Rversion { size :: Word32, > >> >> >> mtype :: Word8, > >> >> >> tag :: Word16, > >> >> >> msize :: Word32, > >> >> >> ssize :: Word16, > >> >> >> version :: ByteString} > >> >> >> deriving (Eq, Ord, Show) > >> >> > > >> >> >> instance Binary RV where > >> >> >> get = do s <- getWord32le > >> >> >> mtype <- getWord8 > >> >> >> getSpecific s mtype > >> >> >> where > >> >> >> getSpecific s mt = do t <- getWord16le > >> >> >> ms <- getWord32le > >> >> >> ss <- getWord16le > >> >> >> v <- getRemainingLazyByteString > >> >> >> return $ Rversion {size=s, > >> >> >> mtype=mt, > >> >> >> tag=t, > >> >> >> msize=ms, > >> >> >> ssize=ss, > >> >> >> version=v } > >> >> >> put _ = undefined > >> >> > > >> >> > >> >> > >> >> > >> >> -- > >> >> /jve > >> > > >> > > >> > _______________________________________________ > >> > Haskell-Cafe mailing list > >> > Haskell-Cafe@haskell.org > >> > http://www.haskell.org/mailman/listinfo/haskell-cafe > >> > > >> > > >> > >> > >> > >> -- > >> /jve > > > > > > > > -- > /jve > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090602/8f9acebd/attachment.html From thomas.dubuisson at gmail.com Tue Jun 2 16:56:20 2009 From: thomas.dubuisson at gmail.com (Thomas DuBuisson) Date: Tue Jun 2 16:40:20 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: <3e1162e60906021331u5f26433at83a94fc190a3c388@mail.gmail.com> References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> <3e1162e60906021320r1937f22er284154ed56861e7d@mail.gmail.com> <3e1162e60906021331u5f26433at83a94fc190a3c388@mail.gmail.com> Message-ID: <4c44d90b0906021356x4ef19fbax98cfb146a3c7b502@mail.gmail.com> Again, I can't reproduce your problem. Are you getting data through some previous Binary instance before calling the routines you show us here? The code I tested with is below - I've tried it with both 'getSpecific' paths by commenting out one path at a time. Both methods work, shown below. Thomas *Main> decode test :: RV Rversion {size = 19, mtype = 101, tag = 65535, msize = 1024, ssize = 6, version = Chunk "9P2000" Empty} *Main> :q Leaving GHCi. [... edit ...] [1 of 1] Compiling Main ( p.hs, interpreted ) Ok, modules loaded: Main. *Main> decode test :: RV Rerror {size = 19, mtype = 101, tag = 65535, ssize = 1024, ename = Chunk "\NUL\NUL\ACK\NUL9P2000" Empty} *Main> import Data.ByteString.Lazy import Data.Binary import Data.Binary.Get data RV = Rversion { size :: Word32, mtype :: Word8, tag :: Word16, msize :: Word32, ssize :: Word16, version :: ByteString} | Rerror { size :: Word32, mtype :: Word8, tag :: Word16, ssize :: Word16, ename :: ByteString} deriving (Eq, Ord, Show) instance Binary RV where put = undefined get = do s <- getWord32le mtype <- getWord8 getSpecific s mtype where getSpecific s mt {- = do t <- getWord16le ms <- getWord32le ss <- getWord16le v <- getRemainingLazyByteString return $ Rversion {size=s, mtype=mt, tag=t, msize=ms, ssize=ss, version=v} -} = do t <- getWord16le ss <- getWord16le e <- getLazyByteString $ fromIntegral ss return $ Rerror {size=s, mtype=mt, tag=t, ssize=ss, ename=e} test = pack [ 0x13 , 0x00 , 0x00 , 0x00 , 0x65 , 0xff , 0xff , 0x00 , 0x04 , 0x00 , 0x00 , 0x06 , 0x00 , 0x39 , 0x50 , 0x32 , 0x30 , 0x30 , 0x30 ] On Tue, Jun 2, 2009 at 1:31 PM, David Leimbach wrote: > > > On Tue, Jun 2, 2009 at 1:28 PM, John Van Enk wrote: >> >> I think Thomas' point was that some other branch in `getSpecific' is >> running. Is there a chance we can see the rest of `getSpecific'? > > Sure: ?(In the meantime, I'll try the suggested code from before) > ?get = do s <- getWord32le > ?? ? ? ? ? ? mtype <- getWord8 > ?? ? ? ? ? ? getSpecific s mtype > ?? ? ? ?where > ?? ? ? ? ?getSpecific s mt > ?? ? ? ? ? ? ? ? ? ? ?| mt == mtRversion = do t <- getWord16le > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?v <- > getRemainingLazyByteString > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return $ MessageClient $ > Rversion {size=s, > > ? ? mtype=mt, > > ? ? tag=t, > > ? ? msize=ms, > > ? ? ssize=ss, > > ? ? version=v} > ?? ? ? ? ? ? ? ? ? ? ?| mt == mtRerror = do t <- getWord16le > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?e <- getLazyByteString $ > fromIntegral ss > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return $ MessageClient $ Rerror > {size=s, > > mtype=mt, > > tag=t, > > ssize=ss, > > ename=e} > >> >> On Tue, Jun 2, 2009 at 4:20 PM, David Leimbach wrote: >> > The thing is I have 19 bytes in the hex string I provided: >> > 1300000065ffff000400000600395032303030 >> > That's 38 characters or 19 bytes. >> > The last 4 are 9P2000 >> > 13000000 ?= 4 bytes for 32bit message payload, ?This is little endian >> > for 19 >> > bytes total. >> > 65 = 1 byte for message type. ?65 is "Rversion" or the response type for >> > a >> > Tversion request >> > ffff = 2 bytes for 16bit message "tag". >> > >> > 00040000 = 4 bytes for the 32 bit maximum message payload size I'm >> > negotiating with the 9P server. ?This is little endian for 1024 >> > 0600 = ?2?bytes for 16 bit value for the length of the "string" I'm >> > sending. >> > ?The strings are *NOT* null terminated in 9p, and this is little endian >> > for >> > 6 bytes remaining. >> > 5032303030 = 6 bytes the ASCII or UTF-8 string "9P2000" which is 6 bytes >> > 4 + 1 + 2 + 4 + 2 + 6 = 19 bytes. >> > As far as I can see, my "get" code does NOT ask for a 20th byte, so why >> > am I >> > getting that error? >> > get = do s <- getWord32le ?-- 4 >> > ?? ? ? ? ? ? mtype <- getWord8 ?-- 1 >> > ?? ? ? ? ? ? getSpecific s mtype >> > ?? ? ? ?where >> > ?? ? ? ? ?getSpecific s mt >> > ?? ? ? ? ? ? ? ? ? ? ?| mt == mtRversion = do t <- getWord16le -- 2 >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le ?-- 4 >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le -- 2 >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?v <- >> > getRemainingLazyByteString ?-- remaining should be 6 bytes. >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return $ MessageClient $ >> > Rversion {size=s, >> > >> > ? ? ? ? ? ? ? ? ? ? ? ? mtype=mt, >> > >> > ? ? ? ? ? ? ? ? ? ? ? ? tag=t, >> > >> > ? ? ? ? ? ? ? ? ? ? ? ? msize=ms, >> > >> > ? ? ? ? ? ? ? ? ? ? ? ? ssize=ss, >> > >> > ? ? ? ? ? ? ? ? ? ? ? ? version=v} >> > Should I file a bug? ?I don't believe I should be seeing an error >> > message >> > claiming a failure at the 20th byte when I've never asked for one. >> > Dave >> > >> > On Tue, Jun 2, 2009 at 10:51 AM, John Van Enk wrote: >> >> >> >> Thomas, >> >> >> >> You're correct. For some reason, I based my advice on the thought that >> >> 19 was the minimum size instead of 13. >> >> >> >> On Tue, Jun 2, 2009 at 1:24 PM, Thomas DuBuisson >> >> wrote: >> >> >> I think getRemainingLazyByteString expects at least one byte >> >> > No, it works with an empty bytestring. ?Or, my tests do with binary >> >> > 0.5.0.1. >> >> > >> >> > The specific error means you are requiring more data than providing. >> >> > First check the length of the bytestring you pass in to the to level >> >> > decode (or 'get') routine and walk though that to figure out how much >> >> > it should be consuming. ?I notice you have a guard on the >> >> > 'getSpecific' function, hopefully you're sure the case you gave us is >> >> > the branch being taken. >> >> > >> >> > I think the issue isn't with the code provided. ?I cleaned up the >> >> > code >> >> > (which did change behavior due to the guard and data declarations >> >> > that >> >> > weren't in the mailling) and it works fine all the way down to the >> >> > expected minimum of 13 bytes. >> >> > >> >> > >> >> >> import Data.ByteString.Lazy >> >> >> import Data.Binary >> >> >> import Data.Binary.Get >> >> >> >> >> >> data RV = >> >> >> Rversion { ? ? size ? :: Word32, >> >> >> ? ? ? ? ? ? ? ?mtype ?:: Word8, >> >> >> ? ? ? ? ? ? ? ?tag ? ?:: Word16, >> >> >> ? ? ? ? ? ? ? ?msize ?:: Word32, >> >> >> ? ? ? ? ? ? ? ?ssize ?:: Word16, >> >> >> ? ? ? ? ? ? ? ?version :: ByteString} >> >> >> ? ? ? deriving (Eq, Ord, Show) >> >> > >> >> >> instance Binary RV where >> >> >> ?get = do s <- getWord32le >> >> >> ? ? ? ? ?mtype <- getWord8 >> >> >> ? ? ? ? ?getSpecific s mtype >> >> >> ? where >> >> >> ? ?getSpecific s mt = do t <- getWord16le >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?v <- getRemainingLazyByteString >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?return $ Rversion {size=s, >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mtype=mt, >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tag=t, >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? msize=ms, >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ssize=ss, >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? version=v } >> >> >> ?put _ = undefined >> >> > >> >> >> >> >> >> >> >> -- >> >> /jve >> > >> > >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > Haskell-Cafe@haskell.org >> > http://www.haskell.org/mailman/listinfo/haskell-cafe >> > >> > >> >> >> >> -- >> /jve > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From vanenkj at gmail.com Tue Jun 2 16:56:38 2009 From: vanenkj at gmail.com (John Van Enk) Date: Tue Jun 2 16:40:39 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: <3e1162e60906021346n5d7a149fpafcc12326cbdd741@mail.gmail.com> References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> <3e1162e60906021320r1937f22er284154ed56861e7d@mail.gmail.com> <3e1162e60906021331u5f26433at83a94fc190a3c388@mail.gmail.com> <3e1162e60906021346n5d7a149fpafcc12326cbdd741@mail.gmail.com> Message-ID: Just so we know that it's not the issue, what version of binary are you using? The most current one is 0.5.0.1. On Tue, Jun 2, 2009 at 4:46 PM, David Leimbach wrote: > > > On Tue, Jun 2, 2009 at 1:36 PM, John Van Enk wrote: >> >> What happens if you use `getRemainingLazyByteString' in your error >> branch instead of `getLazyByteString'? > > I actually am using getRemainingLazyByteString right now, and it still > thinks I'm asking for a 20th byte. > if I delete the other guarded branch of that function, it still fails saying > I'm asking for the 20th byte. > Dave > >> >> On Tue, Jun 2, 2009 at 4:31 PM, David Leimbach wrote: >> > >> > >> > On Tue, Jun 2, 2009 at 1:28 PM, John Van Enk wrote: >> >> >> >> I think Thomas' point was that some other branch in `getSpecific' is >> >> running. Is there a chance we can see the rest of `getSpecific'? >> > >> > Sure: ?(In the meantime, I'll try the suggested code from before) >> > ?get = do s <- getWord32le >> > ?? ? ? ? ? ? mtype <- getWord8 >> > ?? ? ? ? ? ? getSpecific s mtype >> > ?? ? ? ?where >> > ?? ? ? ? ?getSpecific s mt >> > ?? ? ? ? ? ? ? ? ? ? ?| mt == mtRversion = do t <- getWord16le >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?v <- >> > getRemainingLazyByteString >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return $ MessageClient $ >> > Rversion {size=s, >> > >> > ? ? mtype=mt, >> > >> > ? ? tag=t, >> > >> > ? ? msize=ms, >> > >> > ? ? ssize=ss, >> > >> > ? ? version=v} >> > ?? ? ? ? ? ? ? ? ? ? ?| mt == mtRerror = do t <- getWord16le >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?e <- getLazyByteString $ >> > fromIntegral ss >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return $ MessageClient $ >> > Rerror >> > {size=s, >> > >> > mtype=mt, >> > >> > tag=t, >> > >> > ssize=ss, >> > >> > ename=e} >> > >> >> >> >> On Tue, Jun 2, 2009 at 4:20 PM, David Leimbach >> >> wrote: >> >> > The thing is I have 19 bytes in the hex string I provided: >> >> > 1300000065ffff000400000600395032303030 >> >> > That's 38 characters or 19 bytes. >> >> > The last 4 are 9P2000 >> >> > 13000000 ?= 4 bytes for 32bit message payload, ?This is little endian >> >> > for 19 >> >> > bytes total. >> >> > 65 = 1 byte for message type. ?65 is "Rversion" or the response type >> >> > for >> >> > a >> >> > Tversion request >> >> > ffff = 2 bytes for 16bit message "tag". >> >> > >> >> > 00040000 = 4 bytes for the 32 bit maximum message payload size I'm >> >> > negotiating with the 9P server. ?This is little endian for 1024 >> >> > 0600 = ?2?bytes for 16 bit value for the length of the "string" I'm >> >> > sending. >> >> > ?The strings are *NOT* null terminated in 9p, and this is little >> >> > endian >> >> > for >> >> > 6 bytes remaining. >> >> > 5032303030 = 6 bytes the ASCII or UTF-8 string "9P2000" which is 6 >> >> > bytes >> >> > 4 + 1 + 2 + 4 + 2 + 6 = 19 bytes. >> >> > As far as I can see, my "get" code does NOT ask for a 20th byte, so >> >> > why >> >> > am I >> >> > getting that error? >> >> > get = do s <- getWord32le ?-- 4 >> >> > ?? ? ? ? ? ? mtype <- getWord8 ?-- 1 >> >> > ?? ? ? ? ? ? getSpecific s mtype >> >> > ?? ? ? ?where >> >> > ?? ? ? ? ?getSpecific s mt >> >> > ?? ? ? ? ? ? ? ? ? ? ?| mt == mtRversion = do t <- getWord16le -- 2 >> >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le ?-- 4 >> >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le -- 2 >> >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?v <- >> >> > getRemainingLazyByteString ?-- remaining should be 6 bytes. >> >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return $ MessageClient >> >> > $ >> >> > Rversion {size=s, >> >> > >> >> > ? ? ? ? ? ? ? ? ? ? ? ? mtype=mt, >> >> > >> >> > ? ? ? ? ? ? ? ? ? ? ? ? tag=t, >> >> > >> >> > ? ? ? ? ? ? ? ? ? ? ? ? msize=ms, >> >> > >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ssize=ss, >> >> > >> >> > ? ? ? ? ? ? ? ? ? ? ? ? version=v} >> >> > Should I file a bug? ?I don't believe I should be seeing an error >> >> > message >> >> > claiming a failure at the 20th byte when I've never asked for one. >> >> > Dave >> >> > >> >> > On Tue, Jun 2, 2009 at 10:51 AM, John Van Enk >> >> > wrote: >> >> >> >> >> >> Thomas, >> >> >> >> >> >> You're correct. For some reason, I based my advice on the thought >> >> >> that >> >> >> 19 was the minimum size instead of 13. >> >> >> >> >> >> On Tue, Jun 2, 2009 at 1:24 PM, Thomas DuBuisson >> >> >> wrote: >> >> >> >> I think getRemainingLazyByteString expects at least one byte >> >> >> > No, it works with an empty bytestring. ?Or, my tests do with >> >> >> > binary >> >> >> > 0.5.0.1. >> >> >> > >> >> >> > The specific error means you are requiring more data than >> >> >> > providing. >> >> >> > First check the length of the bytestring you pass in to the to >> >> >> > level >> >> >> > decode (or 'get') routine and walk though that to figure out how >> >> >> > much >> >> >> > it should be consuming. ?I notice you have a guard on the >> >> >> > 'getSpecific' function, hopefully you're sure the case you gave us >> >> >> > is >> >> >> > the branch being taken. >> >> >> > >> >> >> > I think the issue isn't with the code provided. ?I cleaned up the >> >> >> > code >> >> >> > (which did change behavior due to the guard and data declarations >> >> >> > that >> >> >> > weren't in the mailling) and it works fine all the way down to the >> >> >> > expected minimum of 13 bytes. >> >> >> > >> >> >> > >> >> >> >> import Data.ByteString.Lazy >> >> >> >> import Data.Binary >> >> >> >> import Data.Binary.Get >> >> >> >> >> >> >> >> data RV = >> >> >> >> Rversion { ? ? size ? :: Word32, >> >> >> >> ? ? ? ? ? ? ? ?mtype ?:: Word8, >> >> >> >> ? ? ? ? ? ? ? ?tag ? ?:: Word16, >> >> >> >> ? ? ? ? ? ? ? ?msize ?:: Word32, >> >> >> >> ? ? ? ? ? ? ? ?ssize ?:: Word16, >> >> >> >> ? ? ? ? ? ? ? ?version :: ByteString} >> >> >> >> ? ? ? deriving (Eq, Ord, Show) >> >> >> > >> >> >> >> instance Binary RV where >> >> >> >> ?get = do s <- getWord32le >> >> >> >> ? ? ? ? ?mtype <- getWord8 >> >> >> >> ? ? ? ? ?getSpecific s mtype >> >> >> >> ? where >> >> >> >> ? ?getSpecific s mt = do t <- getWord16le >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?v <- getRemainingLazyByteString >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?return $ Rversion {size=s, >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mtype=mt, >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tag=t, >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? msize=ms, >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ssize=ss, >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? version=v } >> >> >> >> ?put _ = undefined >> >> >> > >> >> >> >> >> >> >> >> >> >> >> >> -- >> >> >> /jve >> >> > >> >> > >> >> > _______________________________________________ >> >> > Haskell-Cafe mailing list >> >> > Haskell-Cafe@haskell.org >> >> > http://www.haskell.org/mailman/listinfo/haskell-cafe >> >> > >> >> > >> >> >> >> >> >> >> >> -- >> >> /jve >> > >> > >> >> >> >> -- >> /jve > > -- /jve From leimy2k at gmail.com Tue Jun 2 17:00:12 2009 From: leimy2k at gmail.com (David Leimbach) Date: Tue Jun 2 16:44:11 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> <3e1162e60906021320r1937f22er284154ed56861e7d@mail.gmail.com> <3e1162e60906021331u5f26433at83a94fc190a3c388@mail.gmail.com> <3e1162e60906021346n5d7a149fpafcc12326cbdd741@mail.gmail.com> Message-ID: <3e1162e60906021400l248d0d64y857571ae53f9d885@mail.gmail.com> 0.5.0.1 On Tue, Jun 2, 2009 at 1:56 PM, John Van Enk wrote: > Just so we know that it's not the issue, what version of binary are > you using? The most current one is 0.5.0.1. > > On Tue, Jun 2, 2009 at 4:46 PM, David Leimbach wrote: > > > > > > On Tue, Jun 2, 2009 at 1:36 PM, John Van Enk wrote: > >> > >> What happens if you use `getRemainingLazyByteString' in your error > >> branch instead of `getLazyByteString'? > > > > I actually am using getRemainingLazyByteString right now, and it still > > thinks I'm asking for a 20th byte. > > if I delete the other guarded branch of that function, it still fails > saying > > I'm asking for the 20th byte. > > Dave > > > >> > >> On Tue, Jun 2, 2009 at 4:31 PM, David Leimbach > wrote: > >> > > >> > > >> > On Tue, Jun 2, 2009 at 1:28 PM, John Van Enk > wrote: > >> >> > >> >> I think Thomas' point was that some other branch in `getSpecific' is > >> >> running. Is there a chance we can see the rest of `getSpecific'? > >> > > >> > Sure: (In the meantime, I'll try the suggested code from before) > >> > get = do s <- getWord32le > >> > mtype <- getWord8 > >> > getSpecific s mtype > >> > where > >> > getSpecific s mt > >> > | mt == mtRversion = do t <- getWord16le > >> > ms <- getWord32le > >> > ss <- getWord16le > >> > v <- > >> > getRemainingLazyByteString > >> > return $ MessageClient $ > >> > Rversion {size=s, > >> > > >> > mtype=mt, > >> > > >> > tag=t, > >> > > >> > msize=ms, > >> > > >> > ssize=ss, > >> > > >> > version=v} > >> > | mt == mtRerror = do t <- getWord16le > >> > ss <- getWord16le > >> > e <- getLazyByteString $ > >> > fromIntegral ss > >> > return $ MessageClient $ > >> > Rerror > >> > {size=s, > >> > > >> > mtype=mt, > >> > > >> > tag=t, > >> > > >> > ssize=ss, > >> > > >> > ename=e} > >> > > >> >> > >> >> On Tue, Jun 2, 2009 at 4:20 PM, David Leimbach > >> >> wrote: > >> >> > The thing is I have 19 bytes in the hex string I provided: > >> >> > 1300000065ffff000400000600395032303030 > >> >> > That's 38 characters or 19 bytes. > >> >> > The last 4 are 9P2000 > >> >> > 13000000 = 4 bytes for 32bit message payload, This is little > endian > >> >> > for 19 > >> >> > bytes total. > >> >> > 65 = 1 byte for message type. 65 is "Rversion" or the response > type > >> >> > for > >> >> > a > >> >> > Tversion request > >> >> > ffff = 2 bytes for 16bit message "tag". > >> >> > > >> >> > 00040000 = 4 bytes for the 32 bit maximum message payload size I'm > >> >> > negotiating with the 9P server. This is little endian for 1024 > >> >> > 0600 = 2 bytes for 16 bit value for the length of the "string" I'm > >> >> > sending. > >> >> > The strings are *NOT* null terminated in 9p, and this is little > >> >> > endian > >> >> > for > >> >> > 6 bytes remaining. > >> >> > 5032303030 = 6 bytes the ASCII or UTF-8 string "9P2000" which is 6 > >> >> > bytes > >> >> > 4 + 1 + 2 + 4 + 2 + 6 = 19 bytes. > >> >> > As far as I can see, my "get" code does NOT ask for a 20th byte, so > >> >> > why > >> >> > am I > >> >> > getting that error? > >> >> > get = do s <- getWord32le -- 4 > >> >> > mtype <- getWord8 -- 1 > >> >> > getSpecific s mtype > >> >> > where > >> >> > getSpecific s mt > >> >> > | mt == mtRversion = do t <- getWord16le -- 2 > >> >> > ms <- getWord32le -- > 4 > >> >> > ss <- getWord16le -- > 2 > >> >> > v <- > >> >> > getRemainingLazyByteString -- remaining should be 6 bytes. > >> >> > return $ > MessageClient > >> >> > $ > >> >> > Rversion {size=s, > >> >> > > >> >> > mtype=mt, > >> >> > > >> >> > tag=t, > >> >> > > >> >> > msize=ms, > >> >> > > >> >> > ssize=ss, > >> >> > > >> >> > version=v} > >> >> > Should I file a bug? I don't believe I should be seeing an error > >> >> > message > >> >> > claiming a failure at the 20th byte when I've never asked for one. > >> >> > Dave > >> >> > > >> >> > On Tue, Jun 2, 2009 at 10:51 AM, John Van Enk > >> >> > wrote: > >> >> >> > >> >> >> Thomas, > >> >> >> > >> >> >> You're correct. For some reason, I based my advice on the thought > >> >> >> that > >> >> >> 19 was the minimum size instead of 13. > >> >> >> > >> >> >> On Tue, Jun 2, 2009 at 1:24 PM, Thomas DuBuisson > >> >> >> wrote: > >> >> >> >> I think getRemainingLazyByteString expects at least one byte > >> >> >> > No, it works with an empty bytestring. Or, my tests do with > >> >> >> > binary > >> >> >> > 0.5.0.1. > >> >> >> > > >> >> >> > The specific error means you are requiring more data than > >> >> >> > providing. > >> >> >> > First check the length of the bytestring you pass in to the to > >> >> >> > level > >> >> >> > decode (or 'get') routine and walk though that to figure out how > >> >> >> > much > >> >> >> > it should be consuming. I notice you have a guard on the > >> >> >> > 'getSpecific' function, hopefully you're sure the case you gave > us > >> >> >> > is > >> >> >> > the branch being taken. > >> >> >> > > >> >> >> > I think the issue isn't with the code provided. I cleaned up > the > >> >> >> > code > >> >> >> > (which did change behavior due to the guard and data > declarations > >> >> >> > that > >> >> >> > weren't in the mailling) and it works fine all the way down to > the > >> >> >> > expected minimum of 13 bytes. > >> >> >> > > >> >> >> > > >> >> >> >> import Data.ByteString.Lazy > >> >> >> >> import Data.Binary > >> >> >> >> import Data.Binary.Get > >> >> >> >> > >> >> >> >> data RV = > >> >> >> >> Rversion { size :: Word32, > >> >> >> >> mtype :: Word8, > >> >> >> >> tag :: Word16, > >> >> >> >> msize :: Word32, > >> >> >> >> ssize :: Word16, > >> >> >> >> version :: ByteString} > >> >> >> >> deriving (Eq, Ord, Show) > >> >> >> > > >> >> >> >> instance Binary RV where > >> >> >> >> get = do s <- getWord32le > >> >> >> >> mtype <- getWord8 > >> >> >> >> getSpecific s mtype > >> >> >> >> where > >> >> >> >> getSpecific s mt = do t <- getWord16le > >> >> >> >> ms <- getWord32le > >> >> >> >> ss <- getWord16le > >> >> >> >> v <- getRemainingLazyByteString > >> >> >> >> return $ Rversion {size=s, > >> >> >> >> mtype=mt, > >> >> >> >> tag=t, > >> >> >> >> msize=ms, > >> >> >> >> ssize=ss, > >> >> >> >> version=v } > >> >> >> >> put _ = undefined > >> >> >> > > >> >> >> > >> >> >> > >> >> >> > >> >> >> -- > >> >> >> /jve > >> >> > > >> >> > > >> >> > _______________________________________________ > >> >> > Haskell-Cafe mailing list > >> >> > Haskell-Cafe@haskell.org > >> >> > http://www.haskell.org/mailman/listinfo/haskell-cafe > >> >> > > >> >> > > >> >> > >> >> > >> >> > >> >> -- > >> >> /jve > >> > > >> > > >> > >> > >> > >> -- > >> /jve > > > > > > > > -- > /jve > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090602/9e6b7891/attachment.html From leimy2k at gmail.com Tue Jun 2 17:07:24 2009 From: leimy2k at gmail.com (David Leimbach) Date: Tue Jun 2 16:51:24 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: <4c44d90b0906021356x4ef19fbax98cfb146a3c7b502@mail.gmail.com> References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> <3e1162e60906021320r1937f22er284154ed56861e7d@mail.gmail.com> <3e1162e60906021331u5f26433at83a94fc190a3c388@mail.gmail.com> <4c44d90b0906021356x4ef19fbax98cfb146a3c7b502@mail.gmail.com> Message-ID: <3e1162e60906021407ne796214n5e91798230663638@mail.gmail.com> On Tue, Jun 2, 2009 at 1:56 PM, Thomas DuBuisson wrote: > Again, I can't reproduce your problem. Are you getting data through > some previous Binary instance before calling the routines you show us > here? Ah good question... I'm calling "decode", but it's not clear that it's even running my instance of Get!!!! If I have a lazy bytestring, and call "decode", which instance of "Get" runs? Probably not my 9P message version I'll bet... geeze... :-( > The code I tested with is below - I've tried it with both > 'getSpecific' paths by commenting out one path at a time. Both > methods work, shown below. > > Thomas > > *Main> decode test :: RV > Rversion {size = 19, mtype = 101, tag = 65535, msize = 1024, ssize = > 6, version = Chunk "9P2000" Empty} > *Main> :q > Leaving GHCi. > [... edit ...] > [1 of 1] Compiling Main ( p.hs, interpreted ) > Ok, modules loaded: Main. > *Main> decode test :: RV > Rerror {size = 19, mtype = 101, tag = 65535, ssize = 1024, ename = > Chunk "\NUL\NUL\ACK\NUL9P2000" Empty} > *Main> > > > > import Data.ByteString.Lazy > import Data.Binary > import Data.Binary.Get > > data RV = > Rversion { size :: Word32, > mtype :: Word8, > tag :: Word16, > msize :: Word32, > ssize :: Word16, > version :: ByteString} > | Rerror { size :: Word32, > mtype :: Word8, > tag :: Word16, > ssize :: Word16, > ename :: ByteString} > deriving (Eq, Ord, Show) > > instance Binary RV where > put = undefined > get = do s <- getWord32le > mtype <- getWord8 > getSpecific s mtype > where > getSpecific s mt > {- = do t <- getWord16le > ms <- getWord32le > ss <- getWord16le > v <- getRemainingLazyByteString > return $ Rversion {size=s, > mtype=mt, > tag=t, > msize=ms, > ssize=ss, > version=v} > -} > = do t <- getWord16le > ss <- getWord16le > e <- getLazyByteString $ fromIntegral ss > return $ Rerror {size=s, > mtype=mt, > tag=t, > ssize=ss, > ename=e} > > test = pack > [ 0x13 > , 0x00 > , 0x00 > , 0x00 > , 0x65 > , 0xff > , 0xff > , 0x00 > , 0x04 > , 0x00 > , 0x00 > , 0x06 > , 0x00 > , 0x39 > , 0x50 > , 0x32 > , 0x30 > , 0x30 > , 0x30 ] > > On Tue, Jun 2, 2009 at 1:31 PM, David Leimbach wrote: > > > > > > On Tue, Jun 2, 2009 at 1:28 PM, John Van Enk wrote: > >> > >> I think Thomas' point was that some other branch in `getSpecific' is > >> running. Is there a chance we can see the rest of `getSpecific'? > > > > Sure: (In the meantime, I'll try the suggested code from before) > > get = do s <- getWord32le > > mtype <- getWord8 > > getSpecific s mtype > > where > > getSpecific s mt > > | mt == mtRversion = do t <- getWord16le > > ms <- getWord32le > > ss <- getWord16le > > v <- > > getRemainingLazyByteString > > return $ MessageClient $ > > Rversion {size=s, > > > > mtype=mt, > > > > tag=t, > > > > msize=ms, > > > > ssize=ss, > > > > version=v} > > | mt == mtRerror = do t <- getWord16le > > ss <- getWord16le > > e <- getLazyByteString $ > > fromIntegral ss > > return $ MessageClient $ > Rerror > > {size=s, > > > > mtype=mt, > > > > tag=t, > > > > ssize=ss, > > > > ename=e} > > > >> > >> On Tue, Jun 2, 2009 at 4:20 PM, David Leimbach > wrote: > >> > The thing is I have 19 bytes in the hex string I provided: > >> > 1300000065ffff000400000600395032303030 > >> > That's 38 characters or 19 bytes. > >> > The last 4 are 9P2000 > >> > 13000000 = 4 bytes for 32bit message payload, This is little endian > >> > for 19 > >> > bytes total. > >> > 65 = 1 byte for message type. 65 is "Rversion" or the response type > for > >> > a > >> > Tversion request > >> > ffff = 2 bytes for 16bit message "tag". > >> > > >> > 00040000 = 4 bytes for the 32 bit maximum message payload size I'm > >> > negotiating with the 9P server. This is little endian for 1024 > >> > 0600 = 2 bytes for 16 bit value for the length of the "string" I'm > >> > sending. > >> > The strings are *NOT* null terminated in 9p, and this is little > endian > >> > for > >> > 6 bytes remaining. > >> > 5032303030 = 6 bytes the ASCII or UTF-8 string "9P2000" which is 6 > bytes > >> > 4 + 1 + 2 + 4 + 2 + 6 = 19 bytes. > >> > As far as I can see, my "get" code does NOT ask for a 20th byte, so > why > >> > am I > >> > getting that error? > >> > get = do s <- getWord32le -- 4 > >> > mtype <- getWord8 -- 1 > >> > getSpecific s mtype > >> > where > >> > getSpecific s mt > >> > | mt == mtRversion = do t <- getWord16le -- 2 > >> > ms <- getWord32le -- 4 > >> > ss <- getWord16le -- 2 > >> > v <- > >> > getRemainingLazyByteString -- remaining should be 6 bytes. > >> > return $ MessageClient $ > >> > Rversion {size=s, > >> > > >> > mtype=mt, > >> > > >> > tag=t, > >> > > >> > msize=ms, > >> > > >> > ssize=ss, > >> > > >> > version=v} > >> > Should I file a bug? I don't believe I should be seeing an error > >> > message > >> > claiming a failure at the 20th byte when I've never asked for one. > >> > Dave > >> > > >> > On Tue, Jun 2, 2009 at 10:51 AM, John Van Enk > wrote: > >> >> > >> >> Thomas, > >> >> > >> >> You're correct. For some reason, I based my advice on the thought > that > >> >> 19 was the minimum size instead of 13. > >> >> > >> >> On Tue, Jun 2, 2009 at 1:24 PM, Thomas DuBuisson > >> >> wrote: > >> >> >> I think getRemainingLazyByteString expects at least one byte > >> >> > No, it works with an empty bytestring. Or, my tests do with binary > >> >> > 0.5.0.1. > >> >> > > >> >> > The specific error means you are requiring more data than > providing. > >> >> > First check the length of the bytestring you pass in to the to > level > >> >> > decode (or 'get') routine and walk though that to figure out how > much > >> >> > it should be consuming. I notice you have a guard on the > >> >> > 'getSpecific' function, hopefully you're sure the case you gave us > is > >> >> > the branch being taken. > >> >> > > >> >> > I think the issue isn't with the code provided. I cleaned up the > >> >> > code > >> >> > (which did change behavior due to the guard and data declarations > >> >> > that > >> >> > weren't in the mailling) and it works fine all the way down to the > >> >> > expected minimum of 13 bytes. > >> >> > > >> >> > > >> >> >> import Data.ByteString.Lazy > >> >> >> import Data.Binary > >> >> >> import Data.Binary.Get > >> >> >> > >> >> >> data RV = > >> >> >> Rversion { size :: Word32, > >> >> >> mtype :: Word8, > >> >> >> tag :: Word16, > >> >> >> msize :: Word32, > >> >> >> ssize :: Word16, > >> >> >> version :: ByteString} > >> >> >> deriving (Eq, Ord, Show) > >> >> > > >> >> >> instance Binary RV where > >> >> >> get = do s <- getWord32le > >> >> >> mtype <- getWord8 > >> >> >> getSpecific s mtype > >> >> >> where > >> >> >> getSpecific s mt = do t <- getWord16le > >> >> >> ms <- getWord32le > >> >> >> ss <- getWord16le > >> >> >> v <- getRemainingLazyByteString > >> >> >> return $ Rversion {size=s, > >> >> >> mtype=mt, > >> >> >> tag=t, > >> >> >> msize=ms, > >> >> >> ssize=ss, > >> >> >> version=v } > >> >> >> put _ = undefined > >> >> > > >> >> > >> >> > >> >> > >> >> -- > >> >> /jve > >> > > >> > > >> > _______________________________________________ > >> > Haskell-Cafe mailing list > >> > Haskell-Cafe@haskell.org > >> > http://www.haskell.org/mailman/listinfo/haskell-cafe > >> > > >> > > >> > >> > >> > >> -- > >> /jve > > > > > > _______________________________________________ > > Haskell-Cafe mailing list > > Haskell-Cafe@haskell.org > > http://www.haskell.org/mailman/listinfo/haskell-cafe > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090602/c0d31816/attachment.html From thomas.dubuisson at gmail.com Tue Jun 2 17:09:46 2009 From: thomas.dubuisson at gmail.com (Thomas DuBuisson) Date: Tue Jun 2 16:53:45 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: <3e1162e60906021407ne796214n5e91798230663638@mail.gmail.com> References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> <3e1162e60906021320r1937f22er284154ed56861e7d@mail.gmail.com> <3e1162e60906021331u5f26433at83a94fc190a3c388@mail.gmail.com> <4c44d90b0906021356x4ef19fbax98cfb146a3c7b502@mail.gmail.com> <3e1162e60906021407ne796214n5e91798230663638@mail.gmail.com> Message-ID: <4c44d90b0906021409x6ed6c644nd72431251d53d8b9@mail.gmail.com> It will run the instance of the inferred type (or you can provide a type signature to force it). I've done this often before with lists - trying to read in some arbitrary, typically high, number of elements causes issues :-) Thomas On Tue, Jun 2, 2009 at 2:07 PM, David Leimbach wrote: > > > On Tue, Jun 2, 2009 at 1:56 PM, Thomas DuBuisson > wrote: >> >> Again, I can't reproduce your problem. ?Are you getting data through >> some previous Binary instance before calling the routines you show us >> here? > > Ah good question... I'm calling "decode", but it's not clear that it's even > running my instance of Get!!!! > If I have a lazy bytestring, and call "decode", which instance of "Get" > runs? ?Probably not my 9P message version I'll bet... > geeze... ?:-( > >> >> The code I tested with is below - I've tried it with both >> 'getSpecific' paths by commenting out one path at a time. ?Both >> methods work, shown below. >> >> Thomas >> >> *Main> decode test :: RV >> Rversion {size = 19, mtype = 101, tag = 65535, msize = 1024, ssize = >> 6, version = Chunk "9P2000" Empty} >> *Main> :q >> Leaving GHCi. >> [... edit ...] >> [1 of 1] Compiling Main ? ? ? ? ? ? ( p.hs, interpreted ) >> Ok, modules loaded: Main. >> *Main> decode test :: RV >> Rerror {size = 19, mtype = 101, tag = 65535, ssize = 1024, ename = >> Chunk "\NUL\NUL\ACK\NUL9P2000" Empty} >> *Main> >> >> >> >> import Data.ByteString.Lazy >> import Data.Binary >> import Data.Binary.Get >> >> data RV = >> ?Rversion { ? ? size ? ?:: Word32, >> ? ? ? ? ? ? ? ?mtype ? :: Word8, >> ? ? ? ? ? ? ? ?tag ? ? :: Word16, >> ? ? ? ? ? ? ? ?msize ? :: Word32, >> ? ? ? ? ? ? ? ?ssize ? :: Word16, >> ? ? ? ? ? ? ? ?version :: ByteString} >> ?| Rerror { ? ? size ? ?:: Word32, >> ? ? ? ? ? ? ? ?mtype ? :: Word8, >> ? ? ? ? ? ? ? ?tag ? ? :: Word16, >> ? ? ? ? ? ? ? ?ssize ? :: Word16, >> ? ? ? ? ? ? ? ?ename :: ByteString} >> ? ? ? ?deriving (Eq, Ord, Show) >> >> instance Binary RV where >> ?put = undefined >> ?get = do s <- getWord32le >> ? ? ? ? ?mtype <- getWord8 >> ? ? ? ? ?getSpecific s mtype >> ? ? ? ?where >> ? ? ? ? ?getSpecific s mt >> {- ? ? ? ? ? ? ? ? ? ? ?= do t <- getWord16le >> ? ? ? ? ? ? ? ? ? ? ? ? ? ms <- getWord32le >> ? ? ? ? ? ? ? ? ? ? ? ? ? ss <- getWord16le >> ? ? ? ? ? ? ? ? ? ? ? ? ? v <- getRemainingLazyByteString >> ? ? ? ? ? ? ? ? ? ? ? ? ? return $ Rversion {size=s, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?mtype=mt, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?tag=t, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?msize=ms, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ssize=ss, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?version=v} >> -} >> ? ? ? ? ? ? ? ? ? ? ?= do t <- getWord16le >> ? ? ? ? ? ? ? ? ? ? ? ? ? ss <- getWord16le >> ? ? ? ? ? ? ? ? ? ? ? ? ? e <- getLazyByteString $ fromIntegral ss >> ? ? ? ? ? ? ? ? ? ? ? ? ? return $ Rerror {size=s, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?mtype=mt, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?tag=t, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ssize=ss, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ename=e} >> >> test = pack >> ? ? ? ?[ 0x13 >> ? ? ? ?, 0x00 >> ? ? ? ?, 0x00 >> ? ? ? ?, 0x00 >> ? ? ? ?, 0x65 >> ? ? ? ?, 0xff >> ? ? ? ?, 0xff >> ? ? ? ?, 0x00 >> ? ? ? ?, 0x04 >> ? ? ? ?, 0x00 >> ? ? ? ?, 0x00 >> ? ? ? ?, 0x06 >> ? ? ? ?, 0x00 >> ? ? ? ?, 0x39 >> ? ? ? ?, 0x50 >> ? ? ? ?, 0x32 >> ? ? ? ?, 0x30 >> ? ? ? ?, 0x30 >> ? ? ? ?, 0x30 ] >> >> On Tue, Jun 2, 2009 at 1:31 PM, David Leimbach wrote: >> > >> > >> > On Tue, Jun 2, 2009 at 1:28 PM, John Van Enk wrote: >> >> >> >> I think Thomas' point was that some other branch in `getSpecific' is >> >> running. Is there a chance we can see the rest of `getSpecific'? >> > >> > Sure: ?(In the meantime, I'll try the suggested code from before) >> > ?get = do s <- getWord32le >> > ?? ? ? ? ? ? mtype <- getWord8 >> > ?? ? ? ? ? ? getSpecific s mtype >> > ?? ? ? ?where >> > ?? ? ? ? ?getSpecific s mt >> > ?? ? ? ? ? ? ? ? ? ? ?| mt == mtRversion = do t <- getWord16le >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?v <- >> > getRemainingLazyByteString >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return $ MessageClient $ >> > Rversion {size=s, >> > >> > ? ? mtype=mt, >> > >> > ? ? tag=t, >> > >> > ? ? msize=ms, >> > >> > ? ? ssize=ss, >> > >> > ? ? version=v} >> > ?? ? ? ? ? ? ? ? ? ? ?| mt == mtRerror = do t <- getWord16le >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?e <- getLazyByteString $ >> > fromIntegral ss >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return $ MessageClient $ >> > Rerror >> > {size=s, >> > >> > mtype=mt, >> > >> > tag=t, >> > >> > ssize=ss, >> > >> > ename=e} >> > >> >> >> >> On Tue, Jun 2, 2009 at 4:20 PM, David Leimbach >> >> wrote: >> >> > The thing is I have 19 bytes in the hex string I provided: >> >> > 1300000065ffff000400000600395032303030 >> >> > That's 38 characters or 19 bytes. >> >> > The last 4 are 9P2000 >> >> > 13000000 ?= 4 bytes for 32bit message payload, ?This is little endian >> >> > for 19 >> >> > bytes total. >> >> > 65 = 1 byte for message type. ?65 is "Rversion" or the response type >> >> > for >> >> > a >> >> > Tversion request >> >> > ffff = 2 bytes for 16bit message "tag". >> >> > >> >> > 00040000 = 4 bytes for the 32 bit maximum message payload size I'm >> >> > negotiating with the 9P server. ?This is little endian for 1024 >> >> > 0600 = ?2?bytes for 16 bit value for the length of the "string" I'm >> >> > sending. >> >> > ?The strings are *NOT* null terminated in 9p, and this is little >> >> > endian >> >> > for >> >> > 6 bytes remaining. >> >> > 5032303030 = 6 bytes the ASCII or UTF-8 string "9P2000" which is 6 >> >> > bytes >> >> > 4 + 1 + 2 + 4 + 2 + 6 = 19 bytes. >> >> > As far as I can see, my "get" code does NOT ask for a 20th byte, so >> >> > why >> >> > am I >> >> > getting that error? >> >> > get = do s <- getWord32le ?-- 4 >> >> > ?? ? ? ? ? ? mtype <- getWord8 ?-- 1 >> >> > ?? ? ? ? ? ? getSpecific s mtype >> >> > ?? ? ? ?where >> >> > ?? ? ? ? ?getSpecific s mt >> >> > ?? ? ? ? ? ? ? ? ? ? ?| mt == mtRversion = do t <- getWord16le -- 2 >> >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le ?-- 4 >> >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le -- 2 >> >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?v <- >> >> > getRemainingLazyByteString ?-- remaining should be 6 bytes. >> >> > ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return $ MessageClient >> >> > $ >> >> > Rversion {size=s, >> >> > >> >> > ? ? ? ? ? ? ? ? ? ? ? ? mtype=mt, >> >> > >> >> > ? ? ? ? ? ? ? ? ? ? ? ? tag=t, >> >> > >> >> > ? ? ? ? ? ? ? ? ? ? ? ? msize=ms, >> >> > >> >> > ? ? ? ? ? ? ? ? ? ? ? ? ssize=ss, >> >> > >> >> > ? ? ? ? ? ? ? ? ? ? ? ? version=v} >> >> > Should I file a bug? ?I don't believe I should be seeing an error >> >> > message >> >> > claiming a failure at the 20th byte when I've never asked for one. >> >> > Dave >> >> > >> >> > On Tue, Jun 2, 2009 at 10:51 AM, John Van Enk >> >> > wrote: >> >> >> >> >> >> Thomas, >> >> >> >> >> >> You're correct. For some reason, I based my advice on the thought >> >> >> that >> >> >> 19 was the minimum size instead of 13. >> >> >> >> >> >> On Tue, Jun 2, 2009 at 1:24 PM, Thomas DuBuisson >> >> >> wrote: >> >> >> >> I think getRemainingLazyByteString expects at least one byte >> >> >> > No, it works with an empty bytestring. ?Or, my tests do with >> >> >> > binary >> >> >> > 0.5.0.1. >> >> >> > >> >> >> > The specific error means you are requiring more data than >> >> >> > providing. >> >> >> > First check the length of the bytestring you pass in to the to >> >> >> > level >> >> >> > decode (or 'get') routine and walk though that to figure out how >> >> >> > much >> >> >> > it should be consuming. ?I notice you have a guard on the >> >> >> > 'getSpecific' function, hopefully you're sure the case you gave us >> >> >> > is >> >> >> > the branch being taken. >> >> >> > >> >> >> > I think the issue isn't with the code provided. ?I cleaned up the >> >> >> > code >> >> >> > (which did change behavior due to the guard and data declarations >> >> >> > that >> >> >> > weren't in the mailling) and it works fine all the way down to the >> >> >> > expected minimum of 13 bytes. >> >> >> > >> >> >> > >> >> >> >> import Data.ByteString.Lazy >> >> >> >> import Data.Binary >> >> >> >> import Data.Binary.Get >> >> >> >> >> >> >> >> data RV = >> >> >> >> Rversion { ? ? size ? :: Word32, >> >> >> >> ? ? ? ? ? ? ? ?mtype ?:: Word8, >> >> >> >> ? ? ? ? ? ? ? ?tag ? ?:: Word16, >> >> >> >> ? ? ? ? ? ? ? ?msize ?:: Word32, >> >> >> >> ? ? ? ? ? ? ? ?ssize ?:: Word16, >> >> >> >> ? ? ? ? ? ? ? ?version :: ByteString} >> >> >> >> ? ? ? deriving (Eq, Ord, Show) >> >> >> > >> >> >> >> instance Binary RV where >> >> >> >> ?get = do s <- getWord32le >> >> >> >> ? ? ? ? ?mtype <- getWord8 >> >> >> >> ? ? ? ? ?getSpecific s mtype >> >> >> >> ? where >> >> >> >> ? ?getSpecific s mt = do t <- getWord16le >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?ms <- getWord32le >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?ss <- getWord16le >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?v <- getRemainingLazyByteString >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ?return $ Rversion {size=s, >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mtype=mt, >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tag=t, >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? msize=ms, >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ssize=ss, >> >> >> >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? version=v } >> >> >> >> ?put _ = undefined >> >> >> > >> >> >> >> >> >> >> >> >> >> >> >> -- >> >> >> /jve >> >> > >> >> > >> >> > _______________________________________________ >> >> > Haskell-Cafe mailing list >> >> > Haskell-Cafe@haskell.org >> >> > http://www.haskell.org/mailman/listinfo/haskell-cafe >> >> > >> >> > >> >> >> >> >> >> >> >> -- >> >> /jve >> > >> > >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > Haskell-Cafe@haskell.org >> > http://www.haskell.org/mailman/listinfo/haskell-cafe >> > >> > > > From leimy2k at gmail.com Tue Jun 2 17:10:26 2009 From: leimy2k at gmail.com (David Leimbach) Date: Tue Jun 2 16:54:25 2009 Subject: [Haskell-cafe] Success and one last issue with Data.Binary In-Reply-To: <3e1162e60906021407ne796214n5e91798230663638@mail.gmail.com> References: <3e1162e60906020920u2f7093f6w4e1d32c7e1456701@mail.gmail.com> <4c44d90b0906021024p7eb4ccc9y2a4be6a41ddfbe2e@mail.gmail.com> <3e1162e60906021320r1937f22er284154ed56861e7d@mail.gmail.com> <3e1162e60906021331u5f26433at83a94fc190a3c388@mail.gmail.com> <4c44d90b0906021356x4ef19fbax98cfb146a3c7b502@mail.gmail.com> <3e1162e60906021407ne796214n5e91798230663638@mail.gmail.com> Message-ID: <3e1162e60906021410q396b6246hf20dfa96eaec82d1@mail.gmail.com> On Tue, Jun 2, 2009 at 2:07 PM, David Leimbach wrote: > > > On Tue, Jun 2, 2009 at 1:56 PM, Thomas DuBuisson < > thomas.dubuisson@gmail.com> wrote: > >> Again, I can't reproduce your problem. Are you getting data through >> some previous Binary instance before calling the routines you show us >> here? > > > Ah good question... I'm calling "decode", but it's not clear that it's even > running my instance of Get!!!! > > If I have a lazy bytestring, and call "decode", which instance of "Get" > runs? Probably not my 9P message version I'll bet... > > geeze... :-( > AAAAANd... that was it. I totally didn't decode with the right decoder. By the expression I had, it appears it was trying to decode a ByteString as a String, and that was causing a big darned mess. Thanks for all the help guys. I'm glad it's not a bug in the library, just my dumb code Dave > > > >> The code I tested with is below - I've tried it with both >> 'getSpecific' paths by commenting out one path at a time. Both >> methods work, shown below. >> >> Thomas >> >> *Main> decode test :: RV >> Rversion {size = 19, mtype = 101, tag = 65535, msize = 1024, ssize = >> 6, version = Chunk "9P2000" Empty} >> *Main> :q >> Leaving GHCi. >> [... edit ...] >> [1 of 1] Compiling Main ( p.hs, interpreted ) >> Ok, modules loaded: Main. >> *Main> decode test :: RV >> Rerror {size = 19, mtype = 101, tag = 65535, ssize = 1024, ename = >> Chunk "\NUL\NUL\ACK\NUL9P2000" Empty} >> *Main> >> >> >> >> import Data.ByteString.Lazy >> import Data.Binary >> import Data.Binary.Get >> >> data RV = >> Rversion { size :: Word32, >> mtype :: Word8, >> tag :: Word16, >> msize :: Word32, >> ssize :: Word16, >> version :: ByteString} >> | Rerror { size :: Word32, >> mtype :: Word8, >> tag :: Word16, >> ssize :: Word16, >> ename :: ByteString} >> deriving (Eq, Ord, Show) >> >> instance Binary RV where >> put = undefined >> get = do s <- getWord32le >> mtype <- getWord8 >> getSpecific s mtype >> where >> getSpecific s mt >> {- = do t <- getWord16le >> ms <- getWord32le >> ss <- getWord16le >> v <- getRemainingLazyByteString >> return $ Rversion {size=s, >> mtype=mt, >> tag=t, >> msize=ms, >> ssize=ss, >> version=v} >> -} >> = do t <- getWord16le >> ss <- getWord16le >> e <- getLazyByteString $ fromIntegral ss >> return $ Rerror {size=s, >> mtype=mt, >> tag=t, >> ssize=ss, >> ename=e} >> >> test = pack >> [ 0x13 >> , 0x00 >> , 0x00 >> , 0x00 >> , 0x65 >> , 0xff >> , 0xff >> , 0x00 >> , 0x04 >> , 0x00 >> , 0x00 >> , 0x06 >> , 0x00 >> , 0x39 >> , 0x50 >> , 0x32 >> , 0x30 >> , 0x30 >> , 0x30 ] >> >> On Tue, Jun 2, 2009 at 1:31 PM, David Leimbach wrote: >> > >> > >> > On Tue, Jun 2, 2009 at 1:28 PM, John Van Enk wrote: >> >> >> >> I think Thomas' point was that some other branch in `getSpecific' is >> >> running. Is there a chance we can see the rest of `getSpecific'? >> > >> > Sure: (In the meantime, I'll try the suggested code from before) >> > get = do s <- getWord32le >> > mtype <- getWord8 >> > getSpecific s mtype >> > where >> > getSpecific s mt >> > | mt == mtRversion = do t <- getWord16le >> > ms <- getWord32le >> > ss <- getWord16le >> > v <- >> > getRemainingLazyByteString >> > return $ MessageClient $ >> > Rversion {size=s, >> > >> > mtype=mt, >> > >> > tag=t, >> > >> > msize=ms, >> > >> > ssize=ss, >> > >> > version=v} >> > | mt == mtRerror = do t <- getWord16le >> > ss <- getWord16le >> > e <- getLazyByteString $ >> > fromIntegral ss >> > return $ MessageClient $ >> Rerror >> > {size=s, >> > >> > mtype=mt, >> > >> > tag=t, >> > >> > ssize=ss, >> > >> > ename=e} >> > >> >> >> >> On Tue, Jun 2, 2009 at 4:20 PM, David Leimbach >> wrote: >> >> > The thing is I have 19 bytes in the hex string I provided: >> >> > 1300000065ffff000400000600395032303030 >> >> > That's 38 characters or 19 bytes. >> >> > The last 4 are 9P2000 >> >> > 13000000 = 4 bytes for 32bit message payload, This is little endian >> >> > for 19 >> >> > bytes total. >> >> > 65 = 1 byte for message type. 65 is "Rversion" or the response type >> for >> >> > a >> >> > Tversion request >> >> > ffff = 2 bytes for 16bit message "tag". >> >> > >> >> > 00040000 = 4 bytes for the 32 bit maximum message payload size I'm >> >> > negotiating with the 9P server. This is little endian for 1024 >> >> > 0600 = 2 bytes for 16 bit value for the length of the "string" I'm >> >> > sending. >> >> > The strings are *NOT* null terminated in 9p, and this is little >> endian >> >> > for >> >> > 6 bytes remaining. >> >> > 5032303030 = 6 bytes the ASCII or UTF-8 string "9P2000" which is 6 >> bytes >> >> > 4 + 1 + 2 + 4 + 2 + 6 = 19 bytes. >> >> > As far as I can see, my "get" code does NOT ask for a 20th byte, so >> why >> >> > am I >> >> > getting that error? >> >> > get = do s <- getWord32le -- 4 >> >> > mtype <- getWord8 -- 1 >> >> > getSpecific s mtype >> >> > where >> >> > getSpecific s mt >> >> > | mt == mtRversion = do t <- getWord16le -- 2 >> >> > ms <- getWord32le -- 4 >> >> > ss <- getWord16le -- 2 >> >> > v <- >> >> > getRemainingLazyByteString -- remaining should be 6 bytes. >> >> > return $ MessageClient >> $ >> >> > Rversion {size=s, >> >> > >> >> > mtype=mt, >> >> > >> >> > tag=t, >> >> > >> >> > msize=ms, >> >> > >> >> > ssize=ss, >> >> > >> >> > version=v} >> >> > Should I file a bug? I don't believe I should be seeing an error >> >> > message >> >> > claiming a failure at the 20th byte when I've never asked for one. >> >> > Dave >> >> > >> >> > On Tue, Jun 2, 2009 at 10:51 AM, John Van Enk >> wrote: >> >> >> >> >> >> Thomas, >> >> >> >> >> >> You're correct. For some reason, I based my advice on the thought >> that >> >> >> 19 was the minimum size instead of 13. >> >> >> >> >> >> On Tue, Jun 2, 2009 at 1:24 PM, Thomas DuBuisson >> >> >> wrote: >> >> >> >> I think getRemainingLazyByteString expects at least one byte >> >> >> > No, it works with an empty bytestring. Or, my tests do with >> binary >> >> >> > 0.5.0.1. >> >> >> > >> >> >> > The specific error means you are requiring more data than >> providing. >> >> >> > First check the length of the bytestring you pass in to the to >> level >> >> >> > decode (or 'get') routine and walk though that to figure out how >> much >> >> >> > it should be consuming. I notice you have a guard on the >> >> >> > 'getSpecific' function, hopefully you're sure the case you gave us >> is >> >> >> > the branch being taken. >> >> >> > >> >> >> > I think the issue isn't with the code provided. I cleaned up the >> >> >> > code >> >> >> > (which did change behavior due to the guard and data declarations >> >> >> > that >> >> >> > weren't in the mailling) and it works fine all the way down to the >> >> >> > expected minimum of 13 bytes. >> >> >> > >> >> >> > >> >> >> >> import Data.ByteString.Lazy >> >> >> >> import Data.Binary >> >> >> >> import Data.Binary.Get >> >> >> >> >> >> >> >> data RV = >> >> >> >> Rversion { size :: Word32, >> >> >> >> mtype :: Word8, >> >> >> >> tag :: Word16, >> >> >> >> msize :: Word32, >> >> >> >> ssize :: Word16, >> >> >> >> version :: ByteString} >> >> >> >> deriving (Eq, Ord, Show) >> >> >> > >> >> >> >> instance Binary RV where >> >> >> >> get = do s <- getWord32le >> >> >> >> mtype <- getWord8 >> >> >> >> getSpecific s mtype >> >> >> >> where >> >> >> >> getSpecific s mt = do t <- getWord16le >> >> >> >> ms <- getWord32le >> >> >> >> ss <- getWord16le >> >> >> >> v <- getRemainingLazyByteString >> >> >> >> return $ Rversion {size=s, >> >> >> >> mtype=mt, >> >> >> >> tag=t, >> >> >> >> msize=ms, >> >> >> >> ssize=ss, >> >> >> >> version=v } >> >> >> >> put _ = undefined >> >> >> > >> >> >> >> >> >> >> >> >> >> >> >> -- >> >> >> /jve >> >> > >> >> > >> >> > _______________________________________________ >> >> > Haskell-Cafe mailing list >> >> > Haskell-Cafe@haskell.org >> >> > http://www.haskell.org/mailman/listinfo/haskell-cafe >> >> > >> >> > >> >> >> >> >> >> >> >> -- >> >> /jve >> > >> > >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > Haskell-Cafe@haskell.org >> > http://www.haskell.org/mailman/listinfo/haskell-cafe >> > >> > >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090602/4d2838bc/attachment-0001.html From flippa at flippac.org Tue Jun 2 17:45:18 2009 From: flippa at flippac.org (Philippa Cowderoy) Date: Tue Jun 2 17:29:29 2009 Subject: [Haskell-cafe] ANN: Anglohaskell 2009 Message-ID: <1243979118.7090.447.camel@flippa-eee> Anglohaskell 2009 is go! I'm taking on the mantle of organiser, and Microsoft Research have offered us space for talks in Cambridge again. The event will be held on the 7th and 8th of August. More info at http://www.haskell.org/haskellwiki/AngloHaskell/2009 , planning and discussion in #anglohaskell on freenode. For those not familiar with Anglohaskell, it's a somewhat-informal get-together featuring a mixture of talks, discussion and socialising with topics from the hobbyist to the pragmatic to the theoretical. All are welcome, regardless of experience, and best of all - it's free! If anyone wants to offer a talk, help with running the event, accomodation for haskellers from out of town or some ideas, please feel free to edit the wiki page appropriately and/or give us a yell in #anglohaskell. -- Philippa Cowderoy From dons at galois.com Tue Jun 2 18:10:22 2009 From: dons at galois.com (Don Stewart) Date: Tue Jun 2 17:56:01 2009 Subject: [Haskell-cafe] ANNOUNCE: The Haskell Platform 2009.2.0.1 Message-ID: <20090602221022.GN4396@whirlpool.galois.com> We're pleased to announce the second release of the Haskell Platform: a single, standard Haskell distribution for everyone. The specification, along with installers (including Windows and Unix installers for a full Haskell environment) are available. Download the Haskell Platform 2009.2.0.1: http://hackage.haskell.org/platform/ The Haskell Platform is a blessed library and tool suite for Haskell distilled from Hackage, along with installers for a wide variety of systems. It saves developers work picking and choosing the best Haskell libraries and tools to use for a task. Distro maintainers that support the Haskell Platform can be confident they're fully supporting Haskell as the developers intend it. Developers targetting the platform can be confident they have a trusted base of code to work with. What you get: http://hackage.haskell.org/platform/contents.html With regular time-based releases, we expect the platform will grow into a rich, indispensable development environment for all Haskell projects. Please note that this is a beta release. We do not expect all the installers to work perfectly, nor every developer need met, and we would appreciate feedback. You can help out by packaging the platform for your distro, or reporting bugs and feature requests, or installing Haskell onto your friends' machines. The process for adding new tools and libraries will be outlined in coming weeks. The Haskell Platform would not have been possible without the hard work of the Cabal development team, the Hackage developers and maintainers, the individual compiler, tool and library authors who contributed to the suite, and the distro maintainers who build and distribute the Haskell Platform. Thanks! -- The Platform Infrastructure Team From hjgtuyl at chello.nl Tue Jun 2 18:58:15 2009 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Tue Jun 2 18:42:17 2009 Subject: [Haskell-cafe] ANN: Anglohaskell 2009 In-Reply-To: <1243979118.7090.447.camel@flippa-eee> References: <1243979118.7090.447.camel@flippa-eee> Message-ID: On Tue, 02 Jun 2009 23:45:18 +0200, Philippa Cowderoy wrote: > Anglohaskell 2009 is go! F.A.B. :) -- Regards, Henk-Jan van Tuyl -- http://functor.bamikanarie.com http://Van.Tuyl.eu/ -- From nrolle at web.de Tue Jun 2 18:59:43 2009 From: nrolle at web.de (Nico Rolle) Date: Tue Jun 2 18:43:43 2009 Subject: [Haskell-cafe] beginners question about fromMaybe Message-ID: <45fccde20906021559l475d9844hdd37209937f94847@mail.gmail.com> hi there heres a code snipped, don't care about the parameters. the thing is i make a lookup on my map "m" and then branch on that return value probePhase is sc [] m = [] probePhase is sc (x:xs) m | val == Nothing = probePhase is sc xs m | otherwise = jr ++ probePhase is sc xs m where jr = joinTuples sc x (fromMaybe [] val) key = getPartialTuple is x val = Map.lookup key m the line "jr = joinTuples sc x (fromMaybe [] val)" is kind of ugly because i know that it is not Nothing. is there a better way to solve this? regards From shinnonoir at gmail.com Tue Jun 2 19:17:19 2009 From: shinnonoir at gmail.com (Raynor Vliegendhart) Date: Tue Jun 2 19:01:18 2009 Subject: [Haskell-cafe] beginners question about fromMaybe In-Reply-To: <45fccde20906021559l475d9844hdd37209937f94847@mail.gmail.com> References: <45fccde20906021559l475d9844hdd37209937f94847@mail.gmail.com> Message-ID: <6d961e560906021617h26c2756n1af9766b09aa1252@mail.gmail.com> If you're absolutely certain that the lookup always succeeds, then you can use pattern matching as follows: where jr = joinTuples sc x val key = getPartialTuple is x Just val = Map.lookup key m On 6/3/09, Nico Rolle wrote: > hi there > > heres a code snipped, don't care about the parameters. > the thing is i make a lookup on my map "m" and then branch on that return value > > probePhase is sc [] m = [] > probePhase is sc (x:xs) m > | val == Nothing = probePhase is sc xs m > | otherwise = jr ++ probePhase is sc xs m > where > jr = joinTuples sc x (fromMaybe [] val) > key = getPartialTuple is x > val = Map.lookup key m > > > the line "jr = joinTuples sc x (fromMaybe [] val)" is kind of ugly > because i know that it is not Nothing. > is there a better way to solve this? > regards > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From lrpalmer at gmail.com Tue Jun 2 19:20:39 2009 From: lrpalmer at gmail.com (Luke Palmer) Date: Tue Jun 2 19:04:38 2009 Subject: [Haskell-cafe] beginners question about fromMaybe In-Reply-To: <45fccde20906021559l475d9844hdd37209937f94847@mail.gmail.com> References: <45fccde20906021559l475d9844hdd37209937f94847@mail.gmail.com> Message-ID: <7ca3f0160906021620r26cfa342j8f59ce6af75287d5@mail.gmail.com> On Tue, Jun 2, 2009 at 4:59 PM, Nico Rolle wrote: > hi there > > heres a code snipped, don't care about the parameters. > the thing is i make a lookup on my map "m" and then branch on that return > value > > probePhase is sc [] m = [] > probePhase is sc (x:xs) m > | val == Nothing = probePhase is sc xs m > | otherwise = jr ++ probePhase is sc xs m > where > jr = joinTuples sc x (fromMaybe [] val) > key = getPartialTuple is x > val = Map.lookup key m Here's my take. This ought to be equivalent, but I haven't tested. probePhase is sc m = concatMap prefix where prefix x = let key = getPartialTuple is x in maybe [] (joinTuples sc x) $ Map.lookup key m > > > the line "jr = joinTuples sc x (fromMaybe [] val)" is kind of ugly > because i know that it is not Nothing. > is there a better way to solve this? > regards > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090602/699f11f1/attachment.html From shinnonoir at gmail.com Tue Jun 2 19:24:46 2009 From: shinnonoir at gmail.com (Raynor Vliegendhart) Date: Tue Jun 2 19:08:47 2009 Subject: [Haskell-cafe] beginners question about fromMaybe In-Reply-To: <6d961e560906021617h26c2756n1af9766b09aa1252@mail.gmail.com> References: <45fccde20906021559l475d9844hdd37209937f94847@mail.gmail.com> <6d961e560906021617h26c2756n1af9766b09aa1252@mail.gmail.com> Message-ID: <6d961e560906021624ydea8d5v2fcd405402bd8abd@mail.gmail.com> I just noticed that my suggestion doesn't work. You're testing whether val is Nothing and in my code snipped val has a different type. On 6/3/09, Raynor Vliegendhart wrote: > If you're absolutely certain that the lookup always succeeds, then you > can use pattern matching as follows: > > > where > jr = joinTuples sc x val > key = getPartialTuple is x > Just val = Map.lookup key m > > > > On 6/3/09, Nico Rolle wrote: > > hi there > > > > heres a code snipped, don't care about the parameters. > > the thing is i make a lookup on my map "m" and then branch on that return value > > > > probePhase is sc [] m = [] > > probePhase is sc (x:xs) m > > | val == Nothing = probePhase is sc xs m > > | otherwise = jr ++ probePhase is sc xs m > > where > > jr = joinTuples sc x (fromMaybe [] val) > > key = getPartialTuple is x > > val = Map.lookup key m > > > > > > the line "jr = joinTuples sc x (fromMaybe [] val)" is kind of ugly > > because i know that it is not Nothing. > > is there a better way to solve this? > > regards > > _______________________________________________ > > Haskell-Cafe mailing list > > Haskell-Cafe@haskell.org > > http://www.haskell.org/mailman/listinfo/haskell-cafe > > > From toby.hutton at gmail.com Tue Jun 2 19:32:14 2009 From: toby.hutton at gmail.com (Toby Hutton) Date: Tue Jun 2 19:16:33 2009 Subject: [Haskell-cafe] beginners question about fromMaybe In-Reply-To: <45fccde20906021559l475d9844hdd37209937f94847@mail.gmail.com> References: <45fccde20906021559l475d9844hdd37209937f94847@mail.gmail.com> Message-ID: <711894390906021632tb54ec63tcc19793e927b30a4@mail.gmail.com> On Wed, Jun 3, 2009 at 8:59 AM, Nico Rolle wrote: > hi there > > heres a code snipped, don't care about the parameters. > the thing is i make a lookup on my map "m" and then branch on that return value > > probePhase is sc [] m = [] > probePhase is sc (x:xs) m > ? ?| val == Nothing ?= probePhase is sc xs m > ? ?| otherwise ? ? ? = jr ++ probePhase is sc xs m > ? ? ? ?where > ? ? ? ? ? ?jr ?= joinTuples sc x (fromMaybe [] val) > ? ? ? ? ? ?key = getPartialTuple is x > ? ? ? ? ? ?val = Map.lookup key m > > > the line "jr ?= joinTuples sc x (fromMaybe [] val)" is kind of ugly > because i know that it is not Nothing. Although pattern matching is probably nicer, there's also fromJust which will throw an exception if you pass it Nothing. I prefer: case Map.lookup key m of Nothing -> next Just val -> (joinTuples sc x val) ++ next where next = probePhase ... key = ... From nowgate at yahoo.com Tue Jun 2 19:33:23 2009 From: nowgate at yahoo.com (michael rice) Date: Tue Jun 2 19:17:24 2009 Subject: [Haskell-cafe] Cabal/primes Message-ID: <112760.56064.qm@web31101.mail.mud.yahoo.com> Finally got adventurous enough to get Cabal working, downloaded the primes package, and got the following error message when trying isPrime. Am I missing something here? Michael ================== [michael@localhost ~]$ ghci GHCi, version 6.10.1: http://www.haskell.org/ghc/? :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> import Data.Numbers.Primes Prelude Data.Numbers.Primes> take 10 primes Loading package syb ... linking ... done. Loading package base-3.0.3.0 ... linking ... done. Loading package primes-0.1.1 ... linking ... done. [2,3,5,7,11,13,17,19,23,29] Prelude Data.Numbers.Primes> isPrime 7 :1:0: Not in scope: `isPrime' Prelude Data.Numbers.Primes> -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090602/09b8ccbb/attachment.html From toby.hutton at gmail.com Tue Jun 2 19:37:29 2009 From: toby.hutton at gmail.com (Toby Hutton) Date: Tue Jun 2 19:21:49 2009 Subject: [Haskell-cafe] beginners question about fromMaybe In-Reply-To: <711894390906021632tb54ec63tcc19793e927b30a4@mail.gmail.com> References: <45fccde20906021559l475d9844hdd37209937f94847@mail.gmail.com> <711894390906021632tb54ec63tcc19793e927b30a4@mail.gmail.com> Message-ID: <711894390906021637p4a6964cfg8c92223c2d643dcd@mail.gmail.com> > ?where next = probePhase ... > ? ? ? ? ? ?key = ... > Argh, I really wish Gmail would allow me to compose in a fixed with width font! Does anyone know of a setting or something that I'm missing? From bertram.felgenhauer at googlemail.com Tue Jun 2 19:47:21 2009 From: bertram.felgenhauer at googlemail.com (Bertram Felgenhauer) Date: Tue Jun 2 19:31:23 2009 Subject: [Haskell-cafe] Cabal/primes In-Reply-To: <112760.56064.qm@web31101.mail.mud.yahoo.com> References: <112760.56064.qm@web31101.mail.mud.yahoo.com> Message-ID: <4a25ba0b.02ab100a.3845.ffffbc23@mx.google.com> michael rice wrote: > Finally got adventurous enough to get Cabal working, downloaded the > primes package, and got the following error message when trying > isPrime. Am I missing something here? The Data.Numbers.Primes module of the primes package does not implement 'isPrime'. The Numbers package is probably the one you want. Bertram From wren at freegeek.org Tue Jun 2 21:48:17 2009 From: wren at freegeek.org (wren ng thornton) Date: Tue Jun 2 21:32:17 2009 Subject: [Haskell-cafe] Checking a value against a passed-in constructor? In-Reply-To: <2f9b2d30906021211o4a012674kd9a01ee51dbc80d1@mail.gmail.com> References: <9F110BD7-C9AA-4007-ADAA-2690513690D1@cs.otago.ac.nz> <20090602115032.686ebc76@dan-laptop> <2f9b2d30906021211o4a012674kd9a01ee51dbc80d1@mail.gmail.com> Message-ID: <4A25D661.6030304@freegeek.org> Ryan Ingram wrote: > Dan wrote: > > I figured there would be a clever Haskell idiom that would give me a > > similarly concise route. Does it really require Template Haskell? I can > > barely parse regular Haskell as it is.. > [...] > Alternatively, you can define a fold[1] once: > > myval :: MyVal -> (Bool -> a) -> (String -> a) -> a > myval (Bool b) bool atom = bool b > myval (Atom s) bool atom = atom s > > f x = myval bool atom where > bool b = ... > atom s = ... In terms of boilerplate, this is often far and away the cleanest solution. I highly recommend if for Write Yourself A Scheme. The one place where it falls down is when, for whatever reason, you end up having collections of MyVals which can't sensibly use some set of constructors. One common example is for type-checking compilers where you guarantee that ill-typed MyVals cannot be constructed (rather than doing a verification pass after construction to ensure they're well-typed). If your type has this problem, using the fold approach often means writing dummy functions to throw errors on invalid inputs, which in turn means sacrificing much of the type safety you'd like (even if you use something like the Maybe or Error monads instead of _|_). A canonical Haskell trick here is to use GADTs to maintain your type invariants, rather than using plain ADTs. This technique isn't really suitable for a first pass at learning Haskell though. > [1] "fold" here is the general term for this type of function. Examples are > foldr: http://haskell.org/ghc/docs/latest/html/libraries/base/src/GHC-Base.html#foldr > maybe: http://haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Maybe.html#maybe > either: http://haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Either.html#either Two more good resources for folds are: * http://knol.google.com/k/edward-kmett/catamorphisms/ This has an implementation in Control.Morphism.Cata from category-extras[1], though the documentation is scarce. If you're interested in the theory of why folds look and work the way they do, then this knol is the best starting point. If you're familiar with OOP, a catamorphism is extremely similar to the recursive Visitor pattern. The big difference you'll see between this generic solution and specialized catamorphisms (foldr, maybe, either,...) is that the specialized versions unpack the Algebra into separate arguments. Also, this generic solution defines MyVal types with open-recursive functors and explicit fixed-point operators, whereas the specialized versions just use Haskell's regular ability to define recursive types (since the result of |fmap (cata f)| is consumed immediately). Don't let these trees obscure the forest. * http://www.cs.nott.ac.uk/~wss/Publications/DataTypesALaCarte.pdf This paper presents an innovative solution to the "expression problem" of defining an open set of constructors for a type. It uses the same open-recursive functor trick as above and may provide some illustration of why we may want to bother with it. If you're hungry for more details, there's an interesting discussion of the paper at [2]. [1] http://hackage.haskell.org/packages/archive/category-extras/ [2] http://wadler.blogspot.com/2008/02/data-types-la-carte.html -- Live well, ~wren From ryani.spam at gmail.com Tue Jun 2 21:49:25 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Tue Jun 2 21:33:24 2009 Subject: [Haskell-cafe] beginners question about fromMaybe In-Reply-To: <7ca3f0160906021620r26cfa342j8f59ce6af75287d5@mail.gmail.com> References: <45fccde20906021559l475d9844hdd37209937f94847@mail.gmail.com> <7ca3f0160906021620r26cfa342j8f59ce6af75287d5@mail.gmail.com> Message-ID: <2f9b2d30906021849pda5bc57obfdcc5b4c6e39d7b@mail.gmail.com> Luke's answer is great (although it changes argument order). Hint: http://www.haskell.org/haskellwiki/Things_to_avoid#Avoid_explicit_recursion I also like the "pattern guards" GHC extension; I tend to use it over "maybe" and "either". I find the resulting code more readable: > {-# LANGUAGE PatternGuards #-} > probePhase is sc xs m = concatMap prefix xs where > prefix x > | Just val <- Map.lookup (getPartialTuple is x) m = joinTuples sc x val > | otherwise = [] Alternatively, I might write it like this: > import Control.Monad > maybeM :: MonadPlus m => Maybe a -> m a > maybeM = maybe mzero return > probePhase is sc xs m = do > x <- xs > val <- maybeM $ Map.lookup (getPartialTuple is x) m > joinTuples sc x val This now works for any xs that is an instance of MonadPlus (assuming joinTuples is also polymorphic). Both of these examples are more wordy than Luke's quick two-liner, but, to me, it's worth it for the additional "maintainability" of that code. I am perhaps in the minority on this issue, though :) -- ryan On Tue, Jun 2, 2009 at 4:20 PM, Luke Palmer wrote: > > > On Tue, Jun 2, 2009 at 4:59 PM, Nico Rolle wrote: >> >> hi there >> >> heres a code snipped, don't care about the parameters. >> the thing is i make a lookup on my map "m" and then branch on that return >> value >> >> probePhase is sc [] m = [] >> probePhase is sc (x:xs) m >> ? ?| val == Nothing ?= probePhase is sc xs m >> ? ?| otherwise ? ? ? = jr ++ probePhase is sc xs m >> ? ? ? ?where >> ? ? ? ? ? ?jr ?= joinTuples sc x (fromMaybe [] val) >> ? ? ? ? ? ?key = getPartialTuple is x >> ? ? ? ? ? ?val = Map.lookup key m > > Here's my take. ? This ought to be equivalent, but I haven't tested. > probePhase is sc m = concatMap prefix > ?? ?where > ?? ?prefix x = let key = getPartialTuple is x in > ?? ? ? ? ? ? ? maybe [] (joinTuples sc x) $ Map.lookup key m >> >> >> >> the line "jr ?= joinTuples sc x (fromMaybe [] val)" is kind of ugly >> because i know that it is not Nothing. >> is there a better way to solve this? >> regards >> _______________________________________________ >> 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 vigalchin at gmail.com Tue Jun 2 23:59:58 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Tue Jun 2 23:43:57 2009 Subject: [Haskell-cafe] type checking that I can't figure out .... Message-ID: <5ae4f2ba0906022059y74ba392dlf18960a8e9d2375b@mail.gmail.com> Hello Haskellers, I isolated to a not so small piece: > {-# OPTIONS -fglasgow-exts #-} > {-# LANGUAGE UndecidableInstances #-} > import Control.Monad.Identity > import Control.Monad.Reader > import Control.Monad.State > import qualified Data.List as L > import qualified Data.Map as M > import Data.Array import IOExts The type of a regular expression. > data Re t > = ReOr [Re t] > | ReCat [Re t] > | ReStar (Re t) > | RePlus (Re t) > | ReOpt (Re t) > | ReTerm [t] > deriving (Show) The internal type of a regular expression. > type SimplRe t = Int > data SimplRe' t > = SReOr (SimplRe t) (SimplRe t) > | SReCat (SimplRe t) (SimplRe t) > | SReStar (SimplRe t) > | SReLambda > | SReNullSet > | SReTerm t > deriving (Eq, Ord, Show) The regular expression builder monad. > data (Ord t) => ReRead t > = ReRead { > rerNullSet :: SimplRe t, > rerLambda :: SimplRe t > } > data (Ord t) => ReState t > = ReState { > resFwdMap :: M.Map (SimplRe t) (ReInfo t), > resBwdMap :: M.Map (SimplRe' t) (SimplRe t), > resNext :: Int, > resQueue :: ([SimplRe t], [SimplRe t]), > resStatesDone :: [SimplRe t] > } > type ReM m t a = StateT (ReState t) (ReaderT (ReRead t) m) a TEMP WNH Dfa construction > data ReDfaState t > = ReDfaState { > dfaFinal :: Bool, > dfaTrans :: [(t, SimplRe t)] > } > deriving (Show) TEMP WNH The ReInfo type > data ReInfo t > = ReInfo { > reiSRE :: SimplRe' t, > reiNullable :: Bool, > reiDfa :: Maybe (ReDfaState t) > } > deriving (Show) TEMP WNH > class (Monad m, Ord t) => ReVars m t where { } > instance (Monad m, Ord t) => ReVars m t where { } TEMP WNH > remLookupFwd :: (ReVars m t) => SimplRe t -> ReM m t (ReInfo t) > remLookupFwd re > = do fwd <- gets resFwdMap > -- let { Just reinfo = M.lookup fwd re } -- PROBLEM > reinfo <- M.lookup fwd re -- PROBLEM > return reinfo When I "compile" with ghci I get: Dfa_exp.lhs:91:32: Couldn't match expected type `M.Map (M.Map (SimplRe t) (ReInfo t)) t1' against inferred type `SimplRe t2' In the second argument of `M.lookup', namely `re' In a 'do' expression: reinfo <- M.lookup fwd re In the expression: do fwd <- gets resFwdMap reinfo <- M.lookup fwd re return reinfo I trimmed the original code down a lot! But still can't why I am getting type check errors!!! Help! Kind regards, Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090602/c9c8c0bf/attachment.html From michael at snoyman.com Wed Jun 3 00:12:46 2009 From: michael at snoyman.com (Michael Snoyman) Date: Tue Jun 2 23:56:45 2009 Subject: [Haskell-cafe] type checking that I can't figure out .... In-Reply-To: <5ae4f2ba0906022059y74ba392dlf18960a8e9d2375b@mail.gmail.com> References: <5ae4f2ba0906022059y74ba392dlf18960a8e9d2375b@mail.gmail.com> Message-ID: <29bf512f0906022112r1e2163a4oe8070d72e889f039@mail.gmail.com> > remLookupFwd :: (ReVars m t) => SimplRe t -> ReM m t (ReInfo t) > remLookupFwd re > = do fwd <- gets resFwdMap > -- let { Just reinfo = M.lookup fwd re } -- PROBLEM > reinfo <- liftMaybe $ M.lookup re fwd -- PROBLEM > return reinfo > > liftMaybe :: Monad m => Maybe a -> m a > liftMaybe Nothing = fail "Nothing" > liftMaybe (Just x) = return x I made two changes: 1. You had the arguments to M.lookup backwards. 2. lookup does not return any generalized Monad, just Maybe (I think that should be changed). I added the simple liftMaybe function to convert the Maybe result into something that will work with your state monad. Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090602/82a590a1/attachment.html From vigalchin at gmail.com Wed Jun 3 00:16:38 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Wed Jun 3 00:00:36 2009 Subject: [Haskell-cafe] type checking that I can't figure out .... In-Reply-To: <29bf512f0906022112r1e2163a4oe8070d72e889f039@mail.gmail.com> References: <5ae4f2ba0906022059y74ba392dlf18960a8e9d2375b@mail.gmail.com> <29bf512f0906022112r1e2163a4oe8070d72e889f039@mail.gmail.com> Message-ID: <5ae4f2ba0906022116y17436508vf2cd5b5daac7d9f8@mail.gmail.com> Hi Michael, Let me look tomorrow morning. In any case, many thanks! Kind regards, Vasili On Tue, Jun 2, 2009 at 11:12 PM, Michael Snoyman wrote: > > remLookupFwd :: (ReVars m t) => SimplRe t -> ReM m t (ReInfo t) > > remLookupFwd re > > = do fwd <- gets resFwdMap > > -- let { Just reinfo = M.lookup fwd re } -- > PROBLEM > > reinfo <- liftMaybe $ M.lookup re fwd -- > PROBLEM > > return reinfo > > > > liftMaybe :: Monad m => Maybe a -> m a > > liftMaybe Nothing = fail "Nothing" > > liftMaybe (Just x) = return x > > I made two changes: > > 1. You had the arguments to M.lookup backwards. > 2. lookup does not return any generalized Monad, just Maybe (I think that > should be changed). I added the simple liftMaybe function to convert the > Maybe result into something that will work with your state monad. > > Michael > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090603/4b231be5/attachment.html From ajb at spamcop.net Wed Jun 3 00:35:22 2009 From: ajb at spamcop.net (ajb@spamcop.net) Date: Wed Jun 3 00:19:19 2009 Subject: [Haskell-cafe] type checking that I can't figure out .... In-Reply-To: <5ae4f2ba0906022059y74ba392dlf18960a8e9d2375b@mail.gmail.com> References: <5ae4f2ba0906022059y74ba392dlf18960a8e9d2375b@mail.gmail.com> Message-ID: <20090603003522.4hihq481csc4g0so-nwo@webmail.spamcop.net> G'day Vasili. This should do it: remLookupFwd :: (ReVars m t) => SimplRe t -> ReM m t (ReInfo t) remLookupFwd re = do fwd <- gets resFwdMap let { Just reinfo = fromJust (M.lookup re fwd) } return reinfo The FiniteMap lookup operation took its arguments in the opposite order. That's really the only problem here AFAICT. Wow, this brings back memories. I wrote this module about ten years ago, and I'm shocked that it's still getting use. I'd appreciate a copy when you're done updating it for the modern era. Cheers, Andrew Bromage From magnus at therning.org Wed Jun 3 01:31:44 2009 From: magnus at therning.org (Magnus Therning) Date: Wed Jun 3 01:15:52 2009 Subject: [Haskell-cafe] ANN: Anglohaskell 2009 In-Reply-To: References: <1243979118.7090.447.camel@flippa-eee> Message-ID: <4A260AC0.9010904@therning.org> Henk-Jan van Tuyl wrote: > On Tue, 02 Jun 2009 23:45:18 +0200, Philippa Cowderoy > wrote: > >> Anglohaskell 2009 is go! > > F.A.B. :) Yes, excellent news, and this time I'll make sure to attend, especially since it's back in Cambridge again. /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 197 bytes Desc: OpenPGP digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090603/40f77fb0/signature.bin From daniel.is.fischer at web.de Wed Jun 3 01:42:32 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Jun 3 01:27:11 2009 Subject: [Haskell-cafe] type checking that I can't figure out .... In-Reply-To: <29bf512f0906022112r1e2163a4oe8070d72e889f039@mail.gmail.com> References: <5ae4f2ba0906022059y74ba392dlf18960a8e9d2375b@mail.gmail.com> <29bf512f0906022112r1e2163a4oe8070d72e889f039@mail.gmail.com> Message-ID: <200906030742.32810.daniel.is.fischer@web.de> Am Mittwoch 03 Juni 2009 06:12:46 schrieb Michael Snoyman: > I made two changes: > > 1. You had the arguments to M.lookup backwards. > 2. lookup does not return any generalized Monad, just Maybe (I think that > should be changed). Data.Map.lookup used to return a value in any monad you wanted, I believe until 6.8 inclusive. I don't think it's going to change again soon. > I added the simple liftMaybe function to convert the > Maybe result into something that will work with your state monad. > > Michael From bluescreen303 at gmail.com Wed Jun 3 04:03:27 2009 From: bluescreen303 at gmail.com (Mathijs Kwik) Date: Wed Jun 3 03:47:25 2009 Subject: [Haskell-cafe] Datastructure with some business-rules Message-ID: <775c14610906030103p3a7a6f98i283e51b10492b2ba@mail.gmail.com> Hi all, I'm building a tree-like structure that somewhat resembles a package/ dependency structure as most packagemanagers/ports-systems have them. It's tree-like (Data.Tree at the moment), but I will probably need to make some structural changes to allow for more complex stuff like circular dependencies and stuff like 'alternatives'. While I'm still on the Tree (nice & simple), I want to explore some business-rules & validation stuff. This is a bit of a contrived example: Let's say that nodes are (NodeType, Int) pairs, where the Nodetype is just a simple algebra?c type. Now certain types of nodes are only allowed to 'grow' on top of some other nodes, but up to 10 levels deep. So certain nodes are only allowed if one of 10 ancestors is of some other type. Or to make this a bit weirder (maybe too contrived): its parent should have a 'brother' of some type. Ofcourse I can make a 'validate' function that checks if a tree plays by the rules, but I would like to put the typesystem to use somehow, since there aren't that many rules. So I would like to have an error thrown any time an invalid structure is used/created instead of having to validate myself every time. I would like this, because in the future I will need to 'morph' trees into each other so inbetween steps that exist must still be valid. First I thought about creating some auto-validate monad that just validates the result after every step, but before going that way I would like to make sure this is the way to go. I understand that Data.Tree (and other functors) just take 1 type 'payload' and they don't mind what's in there, while my 'validation' rules are about the payload _and_ the place in the tree, so I will probably have to change a bit here. Is this at all possible? Is it ok to do or is a 'external' validation/validation monad clearer? What would be the way to go? Thanks for any help! Mathijs From matthijs at stdin.nl Wed Jun 3 04:19:06 2009 From: matthijs at stdin.nl (Matthijs Kooijman) Date: Wed Jun 3 04:03:07 2009 Subject: [Haskell-cafe] ANNOUNCE: The Haskell Platform 2009.2.0.1 In-Reply-To: <20090602221022.GN4396@whirlpool.galois.com> References: <20090602221022.GN4396@whirlpool.galois.com> Message-ID: <20090603081905.GY11821@katherina.student.utwente.nl> Hi Don, > We're pleased to announce the second release of the Haskell Platform: a > single, standard Haskell distribution for everyone. is there a changelog somewhere? Gr. Matthijs -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: Digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090603/21d4d0ff/attachment.bin From duncan.coutts at worc.ox.ac.uk Wed Jun 3 06:36:51 2009 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Wed Jun 3 06:20:57 2009 Subject: [Haskell-cafe] Notice for package authors Message-ID: <1244025411.29805.412.camel@localhost> Package authors, We are about to add an additional quality check in the Hackage upload process that will affect many packages. Hackage will require an upper bound on the version of the base package and reject packages that omit it. Lots of packages currently specify: build-depends: base or build-depends: base >= 3 This is bad. There is no way for the tools to discover if you mean base 3 or 4 and yet most packages break when we pick the wrong one. You must specify an upper bound so that your package does not break when the next major version of the base library is released. For example, if you've tested with base 3 and 4 then use: build-depends: base >= 3 && < 5 Or if it needs version 4 then use: build-depends: base == 4.* Background ---------- When base 4 was released with ghc-6.10.x the vast majority of packages would have broken were it not for a compatibility shim that we added to the cabal-install tool. It defaulted to picking base 3 when the version constraints did not otherwise specify the use of base 4. The same trick will not work when base 5 is released because it will likely not be possible to continue to ship base 3. It is also important that we start to move towards making the majority of packages compatible with base 4. cabal-install changes --------------------- We will shortly release a minor update to cabal-install to change the way it picks between base 3 and 4. Currently if it has the choice it picks version 3. However that is not optimal for cases like: build-depends: base >= 3 && < 5 where it is clear that it is supposed to work with both. In this case we should not be pessimistic in going with the old base 3 and should instead pick base 4. More precisely, we will only apply the compatibility shim when the version is unbounded above. When it is bounded above, as Hackage will soon require, the normal preference to use the latest version applies. If you'd like to help us check this feature is working properly then grab the latest darcs version of cabal-install (which needs the latest darcs version the Cabal lib). See also http://hackage.haskell.org/trac/hackage/ticket/485 Duncan From ndmitchell at gmail.com Wed Jun 3 07:36:51 2009 From: ndmitchell at gmail.com (Neil Mitchell) Date: Wed Jun 3 07:20:49 2009 Subject: [Haskell-cafe] HXT XmlPicklers - TH Derivation In-Reply-To: <4A9146CE-64C0-4D4C-836D-E242BD5C737A@gmail.com> References: <4A9146CE-64C0-4D4C-836D-E242BD5C737A@gmail.com> Message-ID: <404396ef0906030436ub416fefwe6bf4843ca034e46@mail.gmail.com> Hi Max, > I have developed some simple TH code to automatically derive XmlPickler > instances for my types and if there is interest, I will clean it up and > submit a patch. ?Its not complete, but is a start. ?Any interest? Why not submit it to derive: http://community.haskell.org/~ndm/derive Thanks Neil From duncan.coutts at worc.ox.ac.uk Wed Jun 3 07:56:19 2009 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Wed Jun 3 07:40:24 2009 Subject: [Haskell-cafe] Notice for package authors In-Reply-To: <1244025411.29805.412.camel@localhost> References: <1244025411.29805.412.camel@localhost> Message-ID: <1244030179.29805.434.camel@localhost> On Wed, 2009-06-03 at 11:36 +0100, Duncan Coutts wrote: > Package authors, > > We are about to add an additional quality check in the Hackage upload > process that will affect many packages. Hackage will require an upper > bound on the version of the base package and reject packages that omit > it. The check is now active. If you upload and think that your package is rejected in error then please email the cabal-devel list or file a ticket: http://hackage.haskell.org/trac/hackage/ Note that currently "cabal upload [--check]" is pretty awful at reporting the package quality errors that hackage generates. The current workaround is to use -v3 to see the whole HTTP conversation, the tail of which will include package quality error messages. This should be improved for a future release (see ticket #549 if you'd like to work on it). Duncan From huschi at gmx.org Wed Jun 3 08:27:53 2009 From: huschi at gmx.org (Martin Huschenbett) Date: Wed Jun 3 08:11:54 2009 Subject: [Haskell-cafe] GHCI & Curl under Windows Message-ID: <4A266C49.3080207@gmx.org> Hi Haskellers, I've installed the newest Haskell Platform under Vista and downloaded a pre compiled version of curl-7.19.4 for MinGW. After changing the build type in curl.cabal to Simple and supplying the needed paths I could even build and install curl for haskell. If I write a program using curl and compile it with GHC everything works fine. But if I try to execute the main function of my program in GHCI I always get the following error message: Loading package curl-1.3.5 ... linking ... : C:\Devel\Haskell\curl-1.3.5\ghc-6.10.3\HScurl-1.3.5.o: unknown symbol `__imp__curl_easy_getinfo': unable to load package `curl-1.3.5' Did anybody have the same problem and knows how to fix it? Thanks in advance, Martin. From tomamundsen at gmail.com Wed Jun 3 09:10:30 2009 From: tomamundsen at gmail.com (Tom.Amundsen) Date: Wed Jun 3 08:54:27 2009 Subject: [Haskell-cafe] Functors and the Visitor Pattern Message-ID: <23851113.post@talk.nabble.com> So, last night, I was having this problem with my Java code where I couldn't figure out for the life of me how to write a piece of code without a big if {} else if {} else if {} ... else {} structure. I was Googling "Java Reflection" to try to determine how to "cast to the most concerete subclass at runtime." Then it dawned on me that what I was trying to do has already been solved by using the Visitor design pattern. Then, after reading the Visitor design pattern page on Wiki, it said that the visitor pattern is essentially an implementation of a functor. Aha! It totally clicked. The Visitor pattern allows you to collect code for similar operations, while spreading apart code for similar objects. Now that really sounds like a functor! Although, now I'm second guessing myself, because I can't figure out how we could create some design pattern that simulates an applicative functor. I'm pretty sure the Visitor pattern doesn't take you this far (but I am willing to be corrected). So, is there a way to create applicative functors in non-functional languages? What would that pattern look like? - Tom -- View this message in context: http://www.nabble.com/Functors-and-the-Visitor-Pattern-tp23851113p23851113.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From deduktionstheorem at web.de Wed Jun 3 09:28:13 2009 From: deduktionstheorem at web.de (Stephan Friedrichs) Date: Wed Jun 3 09:12:17 2009 Subject: [Haskell-cafe] ANN: heap-1.0.0 Message-ID: <4A267A6D.7090704@web.de> Hello haskell-cafe, I'm pleased to announce a rewrite of the heap package, heap-1.0.0 [1]. It is not 100% compatible to the version 0.6.0, but provides major improvements: - The HeapPolicy type class hack used to distinguish between min- max-, min-prio- and max-prio-heaps has been replaced by the HeapItem type family (the type family provides functions to convert insertable 'items' to (priority, value) pairs and back. Thus a static min-heap (HeapT) can be used as underlying implementation, but the package can still provide MinHeap, MaxHeap, MinPrioHeap and MaxPrioHeap. - A nice side effect of the above is, that ({Min,Max}PrioHeap p) now is an instance of Functor - Faster {from,to}{Asc,Desc}List conversions - A binary with quickcheck test cases can now be built from cabal (with a "Test" flag) (the old versions already had lots of test cases, but cabal didn't know about them). Regards, Stephan [1] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/heap-1.0.0 -- Fr?her hie? es ja: Ich denke, also bin ich. Heute wei? man: Es geht auch so. - Dieter Nuhr From nowgate at yahoo.com Wed Jun 3 09:57:32 2009 From: nowgate at yahoo.com (michael rice) Date: Wed Jun 3 09:41:32 2009 Subject: [Haskell-cafe] Cabal/primes Message-ID: <789035.55505.qm@web31103.mail.mud.yahoo.com> OK, I downloaded Numbers. Still missing the three functions I wanted, which are primes, isPrime, and isProbablyPrime. How do I get these? Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090603/561785f3/attachment-0001.html From andres at cs.uu.nl Wed Jun 3 10:21:58 2009 From: andres at cs.uu.nl (Andres Loeh) Date: Wed Jun 3 10:05:56 2009 Subject: [Haskell-cafe] Functors and the Visitor Pattern In-Reply-To: <23851113.post@talk.nabble.com> References: <23851113.post@talk.nabble.com> Message-ID: <20090603142158.GM4109@cs.uu.nl> > Although, now I'm second guessing myself, because I can't figure out how we > could create some design pattern that simulates an applicative functor. I'm > pretty sure the Visitor pattern doesn't take you this far (but I am willing > to be corrected). So, is there a way to create applicative functors in > non-functional languages? What would that pattern look like? Perhaps this paper can answer your question: Jeremy Gibbons, Bruno C.d.S. Oliveira The essence of the Iterator pattern http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/iterator.pdf HTH, Andres -- Andres Loeh, Universiteit Utrecht mailto:andres@cs.uu.nl mailto:mail@andres-loeh.de http://www.andres-loeh.de From patai_gergely at fastmail.fm Wed Jun 3 10:28:50 2009 From: patai_gergely at fastmail.fm (Patai Gergely) Date: Wed Jun 3 10:12:46 2009 Subject: [Haskell-cafe] GSoC update: sneak peek at the live heap profiler Message-ID: <1244039330.4357.1318584653@webmail.messagingengine.com> Hello everyone, finally there's a bit of eye candy for anyone interested in the heap profiling project: http://just-bottom.blogspot.com/ Feel encouraged to comment and check out the project page too, where you can already see the beginnings of the core library. Gergely -- http://www.fastmail.fm - The way an email service should be From ndmitchell at gmail.com Wed Jun 3 10:40:42 2009 From: ndmitchell at gmail.com (Neil Mitchell) Date: Wed Jun 3 10:24:41 2009 Subject: [Haskell-cafe] GSoC update: sneak peek at the live heap profiler In-Reply-To: <1244039330.4357.1318584653@webmail.messagingengine.com> References: <1244039330.4357.1318584653@webmail.messagingengine.com> Message-ID: <404396ef0906030740k1fd18421j78560613dae14acd@mail.gmail.com> Hi Gergely, I haven't seen this blog on planet.haskell.org, but it definitely should be! Instructions on how to have it added are on that page. Thanks, Neil 2009/6/3 Patai Gergely : > Hello everyone, > > finally there's a bit of eye candy for anyone interested in the heap > profiling project: > > http://just-bottom.blogspot.com/ > > Feel encouraged to comment and check out the project page too, where you > can already see the beginnings of the core library. > > Gergely > > -- > http://www.fastmail.fm - The way an email service should be > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From briand at aracnet.com Wed Jun 3 10:46:29 2009 From: briand at aracnet.com (brian) Date: Wed Jun 3 10:30:32 2009 Subject: [Haskell-cafe] Cabal/primes In-Reply-To: <789035.55505.qm@web31103.mail.mud.yahoo.com> References: <789035.55505.qm@web31103.mail.mud.yahoo.com> Message-ID: <8D7FCF28-9A2E-4909-B768-0994DA9570D2@aracnet.com> Prelude> :m + Data.Numbers.Primes Prelude Data.Numbers.Primes> :browse isPrime :: Integer -> Bool isProbablyPrime :: (System.Random.RandomGen g) => Integer -> g -> (Bool, g) primes :: [Integer] Prelude Data.Numbers.Primes> isPrime 3525266 Loading package syb ... linking ... done. Loading package base-3.0.3.0 ... linking ... done. Loading package old-locale-1.0.0.1 ... linking ... done. Loading package old-time-1.0.0.1 ... linking ... done. Loading package random-1.0.0.1 ... linking ... done. Loading package Numbers-0.2.1 ... linking ... done. False Prelude Data.Numbers.Primes> On Jun 3, 2009, at 6:57 AM, michael rice wrote: > OK, I downloaded Numbers. Still missing the three functions I > wanted, which are primes, isPrime, and isProbablyPrime. How do I get > these? > > Michael > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From patai_gergely at fastmail.fm Wed Jun 3 10:49:57 2009 From: patai_gergely at fastmail.fm (Patai Gergely) Date: Wed Jun 3 10:33:53 2009 Subject: [Haskell-cafe] GSoC update: sneak peek at the live heap profiler In-Reply-To: <404396ef0906030740k1fd18421j78560613dae14acd@mail.gmail.com> References: <1244039330.4357.1318584653@webmail.messagingengine.com> <404396ef0906030740k1fd18421j78560613dae14acd@mail.gmail.com> Message-ID: <1244040597.9270.1318589141@webmail.messagingengine.com> > I haven't seen this blog on planet.haskell.org, but it definitely > should be! Instructions on how to have it added are on that page. Yes, I did that not long after starting the blog. Maybe someone should flush the queue. ;) -- http://www.fastmail.fm - The way an email service should be From sigbjorn.finne at gmail.com Wed Jun 3 10:59:09 2009 From: sigbjorn.finne at gmail.com (Sigbjorn Finne) Date: Wed Jun 3 10:42:56 2009 Subject: [Haskell-cafe] GHCI & Curl under Windows In-Reply-To: <4A266C49.3080207@gmx.org> References: <4A266C49.3080207@gmx.org> Message-ID: On Wed, 03 Jun 2009 05:27:53 -0700, Martin Huschenbett wrote: > Hi Haskellers, > > I've installed the newest Haskell Platform under Vista and downloaded a > pre compiled version of curl-7.19.4 for MinGW. After changing the build > type in curl.cabal to Simple and supplying the needed paths I could even > build and install curl for haskell. > > If I write a program using curl and compile it with GHC everything works > fine. But if I try to execute the main function of my program in GHCI I > always get the following error message: > > Loading package curl-1.3.5 ... linking ... : > C:\Devel\Haskell\curl-1.3.5\ghc-6.10.3\HScurl-1.3.5.o: unknown symbol > `__imp__curl_easy_getinfo': unable to load package `curl-1.3.5' > > Did anybody have the same problem and knows how to fix it? > Hi Martin, perhaps you already have, but did you go through this writeup http://haskell.forkio.com/Home/curl-win32 and see if there are useful pointers there that might help? --sigbjorn -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/ From michael at snoyman.com Wed Jun 3 11:11:22 2009 From: michael at snoyman.com (Michael Snoyman) Date: Wed Jun 3 10:55:21 2009 Subject: [Haskell-cafe] type checking that I can't figure out .... In-Reply-To: <200906030742.32810.daniel.is.fischer@web.de> References: <5ae4f2ba0906022059y74ba392dlf18960a8e9d2375b@mail.gmail.com> <29bf512f0906022112r1e2163a4oe8070d72e889f039@mail.gmail.com> <200906030742.32810.daniel.is.fischer@web.de> Message-ID: <29bf512f0906030811v189ec5ebj8f5cd283df95e08d@mail.gmail.com> On Wed, Jun 3, 2009 at 8:42 AM, Daniel Fischer wrote: > Am Mittwoch 03 Juni 2009 06:12:46 schrieb Michael Snoyman: > > > I made two changes: > > > > 1. You had the arguments to M.lookup backwards. > > 2. lookup does not return any generalized Monad, just Maybe (I think that > > should be changed). > > Data.Map.lookup used to return a value in any monad you wanted, I believe > until 6.8 > inclusive. > I don't think it's going to change again soon. > Is there a reason why it only returns in the Maybe monad? I often times have to write a liftMaybe function to deal with that. Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090603/e8214255/attachment.html From ekmett at gmail.com Wed Jun 3 11:26:46 2009 From: ekmett at gmail.com (Edward Kmett) Date: Wed Jun 3 11:10:43 2009 Subject: [Haskell-cafe] Functors and the Visitor Pattern In-Reply-To: <23851113.post@talk.nabble.com> References: <23851113.post@talk.nabble.com> Message-ID: <7fb8f82f0906030826m74983a93mbbaa6ff22c2c667b@mail.gmail.com> The concepts are fairly closely related but each entails something the other does not. Functor entails parametric polymorphism with respect to the contents of the container. And a visitor can extract a result from the traversal. As a result you may want to think in terms of a Traversable or Foldable functor rather than just a Functor. These will let you extract a monadic or applicative result from your container. Now, as for your actual question, Applicative functors are really hard to model in other languages. With C++ templates you can probably get a weak approximation with something like the encoding used here, possibly mixed with some boost magic for a usable function type: http://www.reddit.com/r/programming/comments/8bx33/a_comparison_of_c_concepts_and_haskell_type/ But I can't think of anyone that would try to use it in production code, and there are many common idioms that that style of translation can't account for (i.e. polymorphic recursion). -Edward Kmett On Wed, Jun 3, 2009 at 9:10 AM, Tom.Amundsen wrote: > > So, last night, I was having this problem with my Java code where I > couldn't > figure out for the life of me how to write a piece of code without a big if > {} else if {} else if {} ... else {} structure. I was Googling "Java > Reflection" to try to determine how to "cast to the most concerete subclass > at runtime." Then it dawned on me that what I was trying to do has already > been solved by using the Visitor design pattern. > > Then, after reading the Visitor design pattern page on Wiki, it said that > the visitor pattern is essentially an implementation of a functor. Aha! It > totally clicked. The Visitor pattern allows you to collect code for similar > operations, while spreading apart code for similar objects. Now that really > sounds like a functor! > > Although, now I'm second guessing myself, because I can't figure out how we > could create some design pattern that simulates an applicative functor. I'm > pretty sure the Visitor pattern doesn't take you this far (but I am willing > to be corrected). So, is there a way to create applicative functors in > non-functional languages? What would that pattern look like? > > - Tom > -- > View this message in context: > http://www.nabble.com/Functors-and-the-Visitor-Pattern-tp23851113p23851113.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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090603/62d999ae/attachment.html From jochem at functor.nl Wed Jun 3 11:28:19 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Wed Jun 3 11:12:19 2009 Subject: [Haskell-cafe] GSoC update: sneak peek at the live heap profiler In-Reply-To: <1244039330.4357.1318584653@webmail.messagingengine.com> References: <1244039330.4357.1318584653@webmail.messagingengine.com> Message-ID: <4A269693.8020701@functor.nl> Patai Gergely wrote: > Hello everyone, > > finally there's a bit of eye candy for anyone interested in the heap > profiling project: > > http://just-bottom.blogspot.com/ > > Feel encouraged to comment and check out the project page too, where you > can already see the beginnings of the core library. Seems pretty cool :) Will this graph be interactive during the run of the program? (I tried to comment on the web page -- however, it didn't let me. Firefox 3.0 on Debian) Cheers, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From Malcolm.Wallace at cs.york.ac.uk Wed Jun 3 12:03:36 2009 From: Malcolm.Wallace at cs.york.ac.uk (Malcolm Wallace) Date: Wed Jun 3 11:51:26 2009 Subject: [Haskell-cafe] GSoC update: sneak peek at the live heap profiler In-Reply-To: <1244040597.9270.1318589141@webmail.messagingengine.com> References: <1244039330.4357.1318584653@webmail.messagingengine.com> <404396ef0906030740k1fd18421j78560613dae14acd@mail.gmail.com> <1244040597.9270.1318589141@webmail.messagingengine.com> Message-ID: <20090603170336.6811c64a.Malcolm.Wallace@cs.york.ac.uk> > > I haven't seen this blog on planet.haskell.org, but it definitely > > should be! ... > > Yes, I did that not long after starting the blog. Maybe someone should > flush the queue. ;) There are other requests from GSoC students to join planet.haskell.org, also still stuck in the queue. (I have prodded a planet maintainer, but got no response). Regards, Malcolm From lemming at henning-thielemann.de Wed Jun 3 12:14:14 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Wed Jun 3 11:58:12 2009 Subject: [Haskell-cafe] Bool as type class to serve EDSLs. In-Reply-To: <76CE077128014A86A2D61E5918F8BFE8@cr3lt> References: <638ABD0A29C8884A91BC5FB5C349B1C337FC71304F@EA-EXMSG-C334.europe.corp.microsoft.com> <381509001.20090528170702@gmail.com> <9C76A33A-B007-4F3C-B516-3F2352529587@informatik.uni-kiel.de> <76CE077128014A86A2D61E5918F8BFE8@cr3lt> Message-ID: <4A26A156.9060702@henning-thielemann.de> Claus Reinke wrote: >>> Do you argue that overloading logical operations like this in Haskell >>> sacrifices type safety? Could programs "go wrong" [1] that use such >>> abstractions? >> >> If I understand your point correctly, you are suggesting that such >> programs >> are still type safe. I agree with the claim that such features are >> detrimental in practice though. Instead of lumping it with type safety, >> then what do we call it? I think I've heard of languages that do such >> conversions as "weakly" typed. Really the issue is with implicit >> conversions, right? > > Isn't it merely a matter of balance? You are completely right. I have to rephrase: The concrete example of interpreting lists as booleans leads to too weak typing for my taste. Let me give Python as an example: It has no static check whether a sub-routine contains a 'return' statement. If it calls 'return', you might call it a function, if it does not call 'return', you might call it a procedure. Whether 'return' is called may vary at run-time, thus a sub-routine can be both function and procedure. However, if the sub-routine does not call 'return' it implicitly calls 'return None' when leaving the scope of the sub-routine. 'None' is a value of every type, just like bottom in Haskell. But in contrast to Haskell 'None' is a well-defined value. As far as I remember, it is considered 'false' in logical expressions. (PHP is even more extreme in interpreting all kinds of values as booleans.) Now, whenever you forget to call 'return' the resulting 'None' goes unnoticed through your program until at a very unrelated place an error like "you tried to access the 5-th element of the list None, which does not exist" pops up. Sure we can implement this behaviour in Haskell, too, e.g. using the Maybe type - but should we do it? I prefer an interpreter which refuses to start the program with the message: 'you forgot a return'. -- Mit freundlichen Gruessen Henning Thielemann Viele Gruesse Henning Martin-Luther-Universitaet Halle-Wittenberg, Institut fuer Informatik Tel. +49 - 345 - 55 24773 Fax +49 - 345 - 55 27333 From simon at joyful.com Wed Jun 3 12:18:19 2009 From: simon at joyful.com (Simon Michael) Date: Wed Jun 3 12:02:16 2009 Subject: [Haskell-cafe] understanding regex libs Message-ID: <5F799E77-BC24-4A61-8CE9-3A00FF5912FC@joyful.com> Hi Chris.. thanks for your extensive work on haskell regex libs. I'm looking for a good way to make my regex-using app more portable to windows. I couldn't figure out the difference between the regex-pcre and regex- pcre-builtin on hackage. Could you clarify ? Best regards, -Simon From dons at galois.com Wed Jun 3 12:21:15 2009 From: dons at galois.com (Don Stewart) Date: Wed Jun 3 12:07:00 2009 Subject: [Haskell-cafe] understanding regex libs In-Reply-To: <5F799E77-BC24-4A61-8CE9-3A00FF5912FC@joyful.com> References: <5F799E77-BC24-4A61-8CE9-3A00FF5912FC@joyful.com> Message-ID: <20090603162115.GB8909@whirlpool.galois.com> simon: > Hi Chris.. thanks for your extensive work on haskell regex libs. > > I'm looking for a good way to make my regex-using app more portable to > windows. > I couldn't figure out the difference between the regex-pcre and regex- > pcre-builtin on hackage. Could you clarify ? pcre-builtin ships the PCRE C library internally. Regular regex-pcre relies on the DLL somewhere on your system. -- Don From simon at joyful.com Wed Jun 3 12:35:01 2009 From: simon at joyful.com (Simon Michael) Date: Wed Jun 3 12:19:14 2009 Subject: [Haskell-cafe] Re: ANNOUNCE: The Haskell Platform 2009.2.0.1 In-Reply-To: <20090603081905.GY11821@katherina.student.utwente.nl> References: <20090602221022.GN4396@whirlpool.galois.com> <20090603081905.GY11821@katherina.student.utwente.nl> Message-ID: Thanks a lot to all working on this. This is just a small experience report. I successfully installed the HP on a borrowed windows XP professional, version 5.1.2600. It was very smooth. It felt like a largeish install; I was glad I had a fast link. Afterward I had a GHC submenu in start menu -> all programs. (I renamed it Haskell since my girlfriend has at least heard me ramble on about that.) Opening a standard CMD prompt, I ghc-pkg and cabal worked just as usual - great. My first cabal install failed, telling me I needed to cabal update first. After that, cabal install worked just fine until I tried some regex libs: regex-posix failed with a bunch of errors, the first being could not find regex.h. I installed the latest stable cygwin with default options and tried again with: cabal install regex-posix --extra-include-dirs=/cygwin/usr/include --extra-lib-dirs=/cygwin/usr/lib. This worked fine. regex-pcre failed telling me I needed the pcre c library. The basic cygwin install didn't affect this. That's as far as I got. Best - Simon From patai_gergely at fastmail.fm Wed Jun 3 12:40:49 2009 From: patai_gergely at fastmail.fm (Patai Gergely) Date: Wed Jun 3 12:24:45 2009 Subject: [Haskell-cafe] GSoC update: sneak peek at the live heap profiler In-Reply-To: <4A269693.8020701@functor.nl> References: <1244039330.4357.1318584653@webmail.messagingengine.com> <4A269693.8020701@functor.nl> Message-ID: <1244047249.5507.1318608425@webmail.messagingengine.com> > Seems pretty cool :) Will this graph be interactive during the run of > the program? What kind of interaction do you have in mind? I intend to add at least zooming-panning, filtering and a few different views (at least independent cost centres like now and cumulative modes like hp2ps). > (I tried to comment on the web page -- however, it didn't let me. > Firefox 3.0 on Debian) Hmm, strange. I have no such problems with Opera, and it's usually much less supported. Gergely -- http://www.fastmail.fm - Does exactly what it says on the tin From simon at joyful.com Wed Jun 3 12:47:11 2009 From: simon at joyful.com (Simon Michael) Date: Wed Jun 3 12:31:21 2009 Subject: [Haskell-cafe] Re: understanding regex libs In-Reply-To: <20090603162115.GB8909@whirlpool.galois.com> References: <5F799E77-BC24-4A61-8CE9-3A00FF5912FC@joyful.com> <20090603162115.GB8909@whirlpool.galois.com> Message-ID: > pcre-builtin ships the PCRE C library internally. Regular regex-pcre > relies on the DLL somewhere on your system. Thanks, this sounds like what I need for windows installability. Maybe this should be mentioned in regex-pcre-builtin's hackage page and haddock docs. Is there any downside to using it ? I notice the hackage page does not mention ghc 6.8, while regex-pcre's does. From vigalchin at gmail.com Wed Jun 3 13:18:28 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Wed Jun 3 13:02:27 2009 Subject: [Haskell-cafe] type checking that I can't figure out ... Message-ID: <5ae4f2ba0906031018t38bca616q4ca6e92e61a886e7@mail.gmail.com> Hi Andrew (Bromage), I reversed the parameter order to Data.Map.lookup and calling fromJust to pull out value from Maybe wrapper ... all as you suggested: > remLookupFwd :: (ReVars m t) => SimplRe t -> ReM m t (ReInfo t) > remLookupFwd re > = do fwd <- gets resFwdMap > let { Just reinfo = fromJust(M.lookup re fwd) } -- PROBLEM > return reinfo I am still getting a type mismatch: Swish\HaskellRDF\Dfa\Dfa.lhs:162:29: Couldn't match expected type `Maybe t' against inferred type `ReInfo t1' In the expression: fromJust (M.lookup re fwd) In a pattern binding: Just reinfo = fromJust (M.lookup re fwd) In the expression: do fwd <- gets resFwdMap let Just reinfo = fromJust (M.lookup re fwd) return reinfo Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090603/f37a6534/attachment.html From rmm-haskell at z.odi.ac Wed Jun 3 13:26:52 2009 From: rmm-haskell at z.odi.ac (Ross Mellgren) Date: Wed Jun 3 13:10:53 2009 Subject: [Haskell-cafe] type checking that I can't figure out ... In-Reply-To: <5ae4f2ba0906031018t38bca616q4ca6e92e61a886e7@mail.gmail.com> References: <5ae4f2ba0906031018t38bca616q4ca6e92e61a886e7@mail.gmail.com> Message-ID: <89EDF41C-92E7-40B7-9B50-130E86D2C541@z.odi.ac> You've applied two solutions to get the value out -- pattern matching (Just reinfo) and fromJust. You should use one or the other, but not both: -- pattern matching remLookupFwd :: (ReVars m t) => SimplRe t -> ReM m t (ReInfo t) remLookupFwd re = do fwd <- gets resFwdMap let { Just reinfo = M.lookup re fwd } -- PROBLEM return reinfo -- fromJust remLookupFwd :: (ReVars m t) => SimplRe t -> ReM m t (ReInfo t) remLookupFwd re = do fwd <- gets resFwdMap let { reinfo = fromJust (M.lookup re fwd) } -- PROBLEM return reinfo BTW, I would personally write this as one line (untested) gets (fromJust . M.lookup re . resFwdMap) -Ross On Jun 3, 2009, at 1:18 PM, Vasili I. Galchin wrote: > Hi Andrew (Bromage), > > I reversed the parameter order to Data.Map.lookup and > calling fromJust to pull out value from Maybe wrapper ... all as you > suggested: > > > remLookupFwd :: (ReVars m t) => SimplRe t -> ReM m t (ReInfo t) > > remLookupFwd re > > = do fwd <- gets resFwdMap > > let { Just reinfo = fromJust(M.lookup re > fwd) } -- PROBLEM > > return reinfo > > > I am still getting a type mismatch: > > > Swish\HaskellRDF\Dfa\Dfa.lhs:162:29: > Couldn't match expected type `Maybe t' > against inferred type `ReInfo t1' > In the expression: fromJust (M.lookup re fwd) > In a pattern binding: Just reinfo = fromJust (M.lookup re fwd) > In the expression: > do fwd <- gets resFwdMap > let Just reinfo = fromJust (M.lookup re fwd) > return reinfo > > Vasili > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From dmehrtash at gmail.com Wed Jun 3 13:32:40 2009 From: dmehrtash at gmail.com (Daryoush Mehrtash) Date: Wed Jun 3 13:16:36 2009 Subject: [Haskell-cafe] Functors and the Visitor Pattern In-Reply-To: <23851113.post@talk.nabble.com> References: <23851113.post@talk.nabble.com> Message-ID: There was a google talk on Visitor pattern in Java and Common Lisp that you might find interesting http://www.youtube.com/watch?v=VeAdryYZ7ak Daryoush On Wed, Jun 3, 2009 at 6:10 AM, Tom.Amundsen wrote: > > So, last night, I was having this problem with my Java code where I > couldn't > figure out for the life of me how to write a piece of code without a big if > {} else if {} else if {} ... else {} structure. I was Googling "Java > Reflection" to try to determine how to "cast to the most concerete subclass > at runtime." Then it dawned on me that what I was trying to do has already > been solved by using the Visitor design pattern. > > Then, after reading the Visitor design pattern page on Wiki, it said that > the visitor pattern is essentially an implementation of a functor. Aha! It > totally clicked. The Visitor pattern allows you to collect code for similar > operations, while spreading apart code for similar objects. Now that really > sounds like a functor! > > Although, now I'm second guessing myself, because I can't figure out how we > could create some design pattern that simulates an applicative functor. I'm > pretty sure the Visitor pattern doesn't take you this far (but I am willing > to be corrected). So, is there a way to create applicative functors in > non-functional languages? What would that pattern look like? > > - Tom > -- > View this message in context: > http://www.nabble.com/Functors-and-the-Visitor-Pattern-tp23851113p23851113.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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090603/2e80164e/attachment.html From nrolle at web.de Wed Jun 3 14:47:23 2009 From: nrolle at web.de (Nico Rolle) Date: Wed Jun 3 14:31:19 2009 Subject: [Haskell-cafe] measure a function in ghci Message-ID: <45fccde20906031147w78128959l40a4aa8cec7c0513@mail.gmail.com> hi there is there a quick way to check which function is doing the job quicker? i have 2 functions which i want to compare. both give the same output but they do it in different manner. i want to test which one is faster. i use ghci. thanks regards From coreyoconnor at gmail.com Wed Jun 3 14:49:09 2009 From: coreyoconnor at gmail.com (Corey O'Connor) Date: Wed Jun 3 14:33:05 2009 Subject: [Haskell-cafe] Using type families to define runtime representation and evaluation strategy? Message-ID: I'm interested in the feasibility of extending the compiler using a construct similar to type synonym families to determine runtime representation and evaluation strategy for types. Can anybody point me to existing work in this area? I'm not sure of the exact terminology to be using here so my description is going to be fuzzy and probably off the mark on a few points. If anybody could help me clarify what I'm trying to described that would be appreciated. What I imagine is an open construct that be evaluated at compile time to determine: - How the data for a type is represented in memory. Whether values are boxed or unboxed etc. - How an expression should be represented. As a lazy evaluation thunk (weak head normal form?) or evaluated to normal form. - How a expression should be reduced. Since "the best" evaluation strategy depends on the application the equations should be open. For one application a data structure should be evaluated the normal form but not another. This is why the construct should be open much like type synonym families. One application could define an instance that declares the value should be reduced to HNF when defined while the other application could define an instance that declares the value to be reduced to WHNF. Still, the library implementor needs the ability to define reasonable defaults. If the construct was closed I don't think these requirements could be satisfied. This resembles extending the Control.Parallel.Strategies evaluation strategies and adaptive-container's container representation to be represented by type level equations. Control.Parallel.Strategies has a good interface but littering the equations with expressions declaring the evaluation strategy seems awkward. Preferably the evaluation strategy should be definable in parallel to the equations when possible. Strictness annotations already resemble the start of such a construct. And any such construct would have to be able to take the place of strictness annotations. Cheers, Corey O'Connor From jochem at functor.nl Wed Jun 3 15:04:06 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Wed Jun 3 14:48:07 2009 Subject: [Haskell-cafe] measure a function in ghci In-Reply-To: <45fccde20906031147w78128959l40a4aa8cec7c0513@mail.gmail.com> References: <45fccde20906031147w78128959l40a4aa8cec7c0513@mail.gmail.com> Message-ID: <4A26C926.6080507@functor.nl> Nico Rolle wrote: > is there a quick way to check which function is doing the job quicker? > i have 2 functions which i want to compare. > both give the same output but they do it in different manner. > i want to test which one is faster. > i use ghci. For simple testing in the interactive environment, use :set +s and after each evaluation the memory usage and the number of elapsed seconds will be displayed. If you want more, look up the profiling support in the documentation of GHC http://www.haskell.org/ghc/docs/latest/html/users_guide/profiling.html GHC provides both memory and time profiling. Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From dagit at codersbase.com Wed Jun 3 15:20:09 2009 From: dagit at codersbase.com (Jason Dagit) Date: Wed Jun 3 15:04:11 2009 Subject: [Haskell-cafe] measure a function in ghci In-Reply-To: <45fccde20906031147w78128959l40a4aa8cec7c0513@mail.gmail.com> References: <45fccde20906031147w78128959l40a4aa8cec7c0513@mail.gmail.com> Message-ID: On Wed, Jun 3, 2009 at 11:47 AM, Nico Rolle wrote: > hi there > > is there a quick way to check which function is doing the job quicker? > i have 2 functions which i want to compare. > both give the same output but they do it in different manner. > i want to test which one is faster. > i use ghci. Be wary of timing things in GHCi. By default there are no optimizations in ghci so you could find that one implementation is much worse than the other but the situation might be completely different when optimizations are enabled. I'm pretty sure if you start ghci with the -O flag that it will use optimizations. Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090603/3c445583/attachment.html From gdweber at indiana.edu Wed Jun 3 15:23:37 2009 From: gdweber at indiana.edu (Gregory D. Weber) Date: Wed Jun 3 15:07:45 2009 Subject: [Haskell-cafe] Linkage errors in scenegraph In-Reply-To: <200905171221.09100.Sven.Panne@aedion.de> References: <20090516230754.GA32509@squirrel.localdomain> <200905171221.09100.Sven.Panne@aedion.de> Message-ID: <20090603192337.GF2873@squirrel.localdomain> Thank you very much. Adding these lines to scenegraph.cabal makes it work: other-modules: Graphics.SceneGraph.Matrix Graphics.SceneGraph.MySTM Graphics.SceneGraph.ReadImage Graphics.SceneGraph.TGA Graphics.SceneGraph.Utils I've contacted the author, who seems willing to fix the "official" package -- although he'd like to find someone else to maintain it. Greg On 2009-May-17, Sven Panne wrote: > Am Sonntag, 17. Mai 2009 01:07:55 schrieb Gregory D. Weber: > > I'd like to get the scenegraph package > > (http://hackage.haskell.org/cgi-bin/hackage-scripts/package/scenegraph) > > to work, but am encountering linkage errors. > > [...] > > Also, I notice that in the cabal file for scenegraph, the > > list of exposed modules > > > > Exposed-Modules: Graphics.SceneGraph, > > Graphics.SceneGraph.Basic, > > Graphics.SceneGraph.Vector, > > Graphics.SceneGraph.Render, > > Graphics.SceneGraph.SimpleViewport, > > Graphics.SceneGraph.GraphViz, > > Graphics.SceneGraph.Library, > > Graphics.SceneGraph.Dump, > > Graphics.SceneGraph.Textures > > > > does not include Graphics.SceneGraph.Matrix, but that should only mean > > that I can't call functions of that module directly -- not that the > > other SceneGraph modules can't call them -- right? [...] > > That basically means that the scenegraph package is broken. ;-) Internal > modules have to be listed in "other-modules:", a section the Cabal file > doesn't contain. As a quick fix, you can add all missing modules in this > section, but this should of course be fixed in the official package, too. > > http://www.haskell.org/cabal/release/cabal-latest/doc/users- > guide/authors.html#buildinfo > > Cheers, > S. -- ___ ___ __ _ / _ \ / _ \| | | | Gregory D. Weber, Associate Professor / /_\// / | | | /\ | | Indiana University East / /_\\/ /__| | |/ \| | http://mypage.iu.edu/~gdweber/ \____/\_____/\___/\__/ Tel. (765) 973-8420; FAX (765) 973-8550 From pumpkingod at gmail.com Wed Jun 3 15:28:26 2009 From: pumpkingod at gmail.com (Daniel Peebles) Date: Wed Jun 3 15:12:38 2009 Subject: [Haskell-cafe] measure a function in ghci In-Reply-To: <45fccde20906031147w78128959l40a4aa8cec7c0513@mail.gmail.com> References: <45fccde20906031147w78128959l40a4aa8cec7c0513@mail.gmail.com> Message-ID: Just use unamb[1] and let the program decide which to use at runtime! Just kidding, but only sort of :) Dan [1] http://www.haskell.org/haskellwiki/Unamb On Wed, Jun 3, 2009 at 2:47 PM, Nico Rolle wrote: > hi there > > is there a quick way to check which function is doing the job quicker? > i have 2 functions which i want to compare. > both give the same output but they do it in different manner. > i want to test which one is faster. > i use ghci. > > thanks > > regards > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From nowgate at yahoo.com Wed Jun 3 15:46:42 2009 From: nowgate at yahoo.com (michael rice) Date: Wed Jun 3 15:30:40 2009 Subject: [Haskell-cafe] Cabal/primes Message-ID: <773825.94993.qm@web31102.mail.mud.yahoo.com> This is working differently than it did last night, when at least import was working. Michael [michael@localhost ~]$ ghci GHCi, version 6.10.1: http://www.haskell.org/ghc/? :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> import Data.Numbers.Primes Could not find module `Data.Numbers.Primes': ? it was found in multiple packages: Numbers-0.2.1 primes-0.1.1 Prelude> :m + Data.Numbers.Primes Could not find module `Data.Numbers.Primes': ? it was found in multiple packages: Numbers-0.2.1 primes-0.1.1 Prelude> Data.Numbers.Primes> :browse :1:21: parse error on input `:' Prelude> isPrime 3525266 :1:0: Not in scope: `isPrime' Prelude> ========== [michael@localhost ~]$ cd .cabal [michael@localhost .cabal]$ ls -l total 20 -rw-rw-r-- 1 michael michael 1729 2009-06-02 18:59 config drwxrwxr-x 4 michael michael 4096 2009-06-02 22:14 lib drwxrwxr-x 2 michael michael 4096 2009-06-02 19:05 logs drwxrwxr-x 3 michael michael 4096 2009-06-02 18:59 packages drwxrwxr-x 3 michael michael 4096 2009-06-02 19:05 share [michael@localhost .cabal]$ cd packages [michael@localhost packages]$ ls -l total 4 drwxrwxr-x 4 michael michael 4096 2009-06-02 22:14 hackage.haskell.org [michael@localhost packages]$ cd hackage.haskell.org [michael@localhost hackage.haskell.org]$ ls -l total 12464 -rw------- 1 michael michael 11735040 2009-06-02 22:14 00-index.tar -rw------- 1 michael michael?? 992994 2009-06-02 22:14 00-index.tar.gz -rw-rw-r-- 1 michael michael????? 418 2009-06-02 22:14 build-reports.log drwxrwxr-x 3 michael michael???? 4096 2009-06-02 22:14 Numbers drwxrwxr-x 3 michael michael???? 4096 2009-06-02 19:05 primes [michael@localhost hackage.haskell.org]$ [michael@localhost hackage.haskell.org]$ pwd /home/michael/.cabal/packages/hackage.haskell.org [michael@localhost hackage.haskell.org]$ ============= --- On Wed, 6/3/09, brian wrote: From: brian Subject: Re: [Haskell-cafe] Cabal/primes To: "michael rice" Cc: haskell-cafe@haskell.org Date: Wednesday, June 3, 2009, 10:46 AM Prelude> :m + Data.Numbers.Primes Prelude Data.Numbers.Primes> :browse isPrime :: Integer -> Bool isProbablyPrime :: ? (System.Random.RandomGen g) => Integer -> g -> (Bool, g) primes :: [Integer] Prelude Data.Numbers.Primes> isPrime 3525266 Loading package syb ... linking ... done. Loading package base-3.0.3.0 ... linking ... done. Loading package old-locale-1.0.0.1 ... linking ... done. Loading package old-time-1.0.0.1 ... linking ... done. Loading package random-1.0.0.1 ... linking ... done. Loading package Numbers-0.2.1 ... linking ... done. False Prelude Data.Numbers.Primes> On Jun 3, 2009, at 6:57 AM, michael rice wrote: > OK, I downloaded Numbers. Still missing the three functions I wanted, which are primes, isPrime, and isProbablyPrime. How do I get these? > > Michael > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090603/54208f89/attachment.html From ptrash at web.de Wed Jun 3 16:01:24 2009 From: ptrash at web.de (ptrash) Date: Wed Jun 3 15:45:21 2009 Subject: [Haskell-cafe] comprehension problem Message-ID: <23858359.post@talk.nabble.com> Hi, what does this to code rows mean: newtype Probability = P Float newtype Dist a = D {unD :: [(a, Probability)]} newtype definies a new type called Probability. But what does P Float mean? And what is the a in Dist a? What does D {...} mean? Thanks for your help. -- View this message in context: http://www.nabble.com/comprehension-problem-tp23858359p23858359.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From dons at galois.com Wed Jun 3 16:09:57 2009 From: dons at galois.com (Don Stewart) Date: Wed Jun 3 15:55:40 2009 Subject: [Haskell-cafe] Using type families to define runtime representation and evaluation strategy? In-Reply-To: References: Message-ID: <20090603200957.GF9163@whirlpool.galois.com> coreyoconnor: > I'm interested in the feasibility of extending the compiler using a > construct similar to type synonym families to determine runtime > representation and evaluation strategy for types. Can anybody point me > to existing work in this area? There's a lot of work on controlling data representations with associated types -- indeed, that was their original use case! Also related might be the new paper "Types are calling conventions" -- Don From ekmett at gmail.com Wed Jun 3 16:22:01 2009 From: ekmett at gmail.com (Edward Kmett) Date: Wed Jun 3 16:05:57 2009 Subject: [Haskell-cafe] ANN: new version of uu-parsinglib In-Reply-To: <20090531232147.GA14703@soi.city.ac.uk> References: <20090531232147.GA14703@soi.city.ac.uk> Message-ID: <7fb8f82f0906031322h1ceb54ddhce1286298f4e90@mail.gmail.com> On Sun, May 31, 2009 at 7:21 PM, Ross Paterson wrote: > Perhaps we should make some and many methods of Alternative, <* and *> > methods of Applicative and <$ a method of Functor, all with the current > definitions as defaults. (John Meacham was also asking for the first > of these.) +1 As a justification, (*>) and (>>) serve much the same purpose, and (>>) is already exposed via Monad to permit the same kinds of optimizations that an explicit override of (*>) proffers. -Edward Kmett -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090603/0281b039/attachment.html From rmm-haskell at z.odi.ac Wed Jun 3 16:27:57 2009 From: rmm-haskell at z.odi.ac (Ross Mellgren) Date: Wed Jun 3 16:11:59 2009 Subject: [Haskell-cafe] comprehension problem In-Reply-To: <23858359.post@talk.nabble.com> References: <23858359.post@talk.nabble.com> Message-ID: P Float is the constructor to create a value of this type, similar to data declarations. That is, 0.5 :: Float, P 0.5 :: Probability The {} notation after D creates a record accessor, also similar to data declarations. It's equivalent to making an unD that unwraps the value yourself: newtype Dist a = D { unD :: [(a, Probability)] } is the same as newtype Dist a = D [(a, Probability)] unD :: Dist a -> [(a, Probability)] unD (D x) = x a in Dist a is a type variable, for example you could have Dist Float (containing [(Float, Probability)]), or Dist String (containing [(String, Probability)]) -Ross On Jun 3, 2009, at 4:01 PM, ptrash wrote: > > Hi, > > what does this to code rows mean: > > newtype Probability = P Float > newtype Dist a = D {unD :: [(a, Probability)]} > > newtype definies a new type called Probability. But what does P > Float mean? > > And what is the a in Dist a? > What does D {...} mean? > > Thanks for your help. > -- > View this message in context: http://www.nabble.com/comprehension-problem-tp23858359p23858359.html > Sent from the Haskell - Haskell-Cafe mailing list archive at > Nabble.com. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From nowgate at yahoo.com Wed Jun 3 16:35:18 2009 From: nowgate at yahoo.com (michael rice) Date: Wed Jun 3 16:19:15 2009 Subject: [Haskell-cafe] Cabal/primes Message-ID: <971337.28849.qm@web31106.mail.mud.yahoo.com> Got it working. I downloaded two packages, primes and Numbers. Since Numbers has the three functions I want to use, primes, isPrime and isProbablyPrime, how do I uninstall the primes package so there won't be a conflict? Michael ================= [michael@localhost hackage.haskell.org]$ ghc-pkg hide primes Writing new package config file... done. [michael@localhost hackage.haskell.org]$ isPrime 7 bash: isPrime: command not found [michael@localhost hackage.haskell.org]$ ghci GHCi, version 6.10.1: http://www.haskell.org/ghc/? :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> :m + Data.Numbers.Primes Prelude Data.Numbers.Primes> isPrime 7 Loading package syb ... linking ... done. Loading package base-3.0.3.0 ... linking ... done. Loading package old-locale-1.0.0.1 ... linking ... done. Loading package old-time-1.0.0.1 ... linking ... done. Loading package random-1.0.0.1 ... linking ... done. Loading package Numbers-0.2.1 ... linking ... done. True Prelude Data.Numbers.Primes> take 10 primes [2,3,5,7,11,13,17,19,23,29] Prelude Data.Numbers.Primes> --- On Wed, 6/3/09, michael rice wrote: From: michael rice Subject: Re: [Haskell-cafe] Cabal/primes To: "brian" Cc: haskell-cafe@haskell.org Date: Wednesday, June 3, 2009, 3:46 PM This is working differently than it did last night, when at least import was working. Michael [michael@localhost ~]$ ghci GHCi, version 6.10.1: http://www.haskell.org/ghc/? :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> import Data.Numbers.Primes Could not find module `Data.Numbers.Primes': ? it was found in multiple packages: Numbers-0.2.1 primes-0.1.1 Prelude> :m + Data.Numbers.Primes Could not find module `Data.Numbers.Primes': ? it was found in multiple packages: Numbers-0.2.1 primes-0.1.1 Prelude> Data.Numbers.Primes> :browse :1:21: parse error on input `:' Prelude> isPrime 3525266 :1:0: Not in scope: `isPrime' Prelude> ========== [michael@localhost ~]$ cd .cabal [michael@localhost .cabal]$ ls -l total 20 -rw-rw-r-- 1 michael michael 1729 2009-06-02 18:59 config drwxrwxr-x 4 michael michael 4096 2009-06-02 22:14 lib drwxrwxr-x 2 michael michael 4096 2009-06-02 19:05 logs drwxrwxr-x 3 michael michael 4096 2009-06-02 18:59 packages drwxrwxr-x 3 michael michael 4096 2009-06-02 19:05 share [michael@localhost .cabal]$ cd packages [michael@localhost packages]$ ls -l total 4 drwxrwxr-x 4 michael michael 4096 2009-06-02 22:14 hackage.haskell.org [michael@localhost packages]$ cd hackage.haskell.org [michael@localhost hackage.haskell.org]$ ls -l total 12464 -rw------- 1 michael michael 11735040 2009-06-02 22:14 00-index.tar -rw------- 1 michael michael?? 992994 2009-06-02 22:14 00-index.tar.gz -rw-rw-r-- 1 michael michael????? 418 2009-06-02 22:14 build-reports.log drwxrwxr-x 3 michael michael???? 4096 2009-06-02 22:14 Numbers drwxrwxr-x 3 michael michael???? 4096 2009-06-02 19:05 primes [michael@localhost hackage.haskell.org]$ [michael@localhost hackage.haskell.org]$ pwd /home/michael/.cabal/packages/hackage.haskell.org [michael@localhost hackage.haskell.org]$ ============= --- On Wed, 6/3/09, brian wrote: From: brian Subject: Re: [Haskell-cafe] Cabal/primes To: "michael rice" Cc: haskell-cafe@haskell.org Date: Wednesday, June 3, 2009, 10:46 AM Prelude> :m + Data.Numbers.Primes Prelude Data.Numbers.Primes> :browse isPrime :: Integer -> Bool isProbablyPrime :: ? (System.Random.RandomGen g) => Integer -> g -> (Bool, g) primes :: [Integer] Prelude Data.Numbers.Primes> isPrime 3525266 Loading package syb ... linking ... done. Loading package base-3.0.3.0 ... linking ... done. Loading package old-locale-1.0.0.1 ... linking ... done. Loading package old-time-1.0.0.1 ... linking ... done. Loading package random-1.0.0.1 ... linking ... done. Loading package Numbers-0.2.1 ... linking ... done. False Prelude Data.Numbers.Primes> On Jun 3, 2009, at 6:57 AM, michael rice wrote: > OK, I downloaded Numbers. Still missing the three functions I wanted, which are primes, isPrime, and isProbablyPrime. How do I get these? > > Michael > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe -----Inline Attachment Follows----- _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090603/b077afd3/attachment.html From coreyoconnor at gmail.com Wed Jun 3 17:43:15 2009 From: coreyoconnor at gmail.com (Corey O'Connor) Date: Wed Jun 3 17:27:10 2009 Subject: [Haskell-cafe] Using type families to define runtime representation and evaluation strategy? In-Reply-To: <20090603200957.GF9163@whirlpool.galois.com> References: <20090603200957.GF9163@whirlpool.galois.com> Message-ID: On Wed, Jun 3, 2009 at 1:09 PM, Don Stewart wrote: > coreyoconnor: >> I'm interested in the feasibility of extending the compiler using a >> construct similar to type synonym families to determine runtime >> representation and evaluation strategy for types. Can anybody point me >> to existing work in this area? > > There's a lot of work on controlling data representations with > associated types -- indeed, that was their original use case! What I'm imagining as a use case would be taking the canonical example from the adaptive-containers: l :: [(Int, Int)] l = [ (x,y) | x <- [1..3], y <- [x..3] ] A module that uses "l" that requires the same data representation as the List(Pair Int Int) type when using adaptive containers would then include an equation somewhat like the following: type instance DataRep [(Int, Int)] = List(Pair Int Int) However all list code would then need to be augmented to take into consideration the DataRep associated type. Correct? Seems like this augmentation could be done implicitly by the compiler. Potentially going off the deep end: Data representation is how a block of memory represents a type such that the representation supports the required evaluation semantic. The data representation for a data constructor where the definition equation is evaluated lazily is different than the data representation for the same constructor where the definition is evaluated strictly. One requires representing the state of the thunk in memory while the other does not. Assuming that is accurate then equations could be represented implicitly parametrized over the data representation equations for each type. Kinda akin to how equations using type class equations are implicitly parametrized by the dictionary representing the witness of that type class for a given type. Except I'm imagining something at the type level instead of value level. Regardless. I need to read up on associated types and try some experiments before I can make claims on what they can and what they cannot do. :-) > Also related might be the new paper "Types are calling conventions" >From the abstract it does sound related. Thanks! I'll add it to my reading pile. Cheers, Corey O'Connor From wss at Cs.Nott.AC.UK Wed Jun 3 17:37:13 2009 From: wss at Cs.Nott.AC.UK (Wouter Swierstra) Date: Wed Jun 3 17:28:13 2009 Subject: [Haskell-cafe] Using type families to define runtime representation and evaluation strategy? In-Reply-To: References: Message-ID: On 3 Jun 2009, at 20:49, Corey O'Connor wrote: > I'm interested in the feasibility of extending the compiler using a > construct similar to type synonym families to determine runtime > representation and evaluation strategy for types. Can anybody point me > to existing work in this area? You may also want to look at work by Paul Levy on "Call-by-push-value" and more recently, Noam Zeilberger (and others at CMU) on focussing. Both use types to control when and how evaluation happens. Hope this helps, Wouter This message has been checked for viruses but the contents of an attachment may still contain software viruses, which could damage your computer system: you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. From lemming at henning-thielemann.de Wed Jun 3 17:57:35 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Wed Jun 3 17:40:03 2009 Subject: [Haskell-cafe] type checking that I can't figure out ... In-Reply-To: <89EDF41C-92E7-40B7-9B50-130E86D2C541@z.odi.ac> References: <5ae4f2ba0906031018t38bca616q4ca6e92e61a886e7@mail.gmail.com> <89EDF41C-92E7-40B7-9B50-130E86D2C541@z.odi.ac> Message-ID: <4A26F1CF.5070006@henning-thielemann.de> Ross Mellgren schrieb: > You've applied two solutions to get the value out -- pattern matching > (Just reinfo) and fromJust. You should use one or the other, but not both: > > -- pattern matching > remLookupFwd :: (ReVars m t) => SimplRe t -> ReM m t (ReInfo t) > remLookupFwd re > = do fwd <- gets resFwdMap > let { Just reinfo = M.lookup re fwd } -- PROBLEM > return reinfo > > -- fromJust > remLookupFwd :: (ReVars m t) => SimplRe t -> ReM m t (ReInfo t) > remLookupFwd re > = do fwd <- gets resFwdMap > let { reinfo = fromJust (M.lookup re fwd) } > -- PROBLEM > return reinfo > > BTW, I would personally write this as one line (untested) > > gets (fromJust . M.lookup re . resFwdMap) fromJust should be avoided, since it is partial and if it results in an error, the error message points to the implementation of fromJust, not its application. Pattern matching is better, but 'maybe' and 'fromMaybe' are best. From rmm-haskell at z.odi.ac Wed Jun 3 17:58:11 2009 From: rmm-haskell at z.odi.ac (Ross Mellgren) Date: Wed Jun 3 17:42:22 2009 Subject: [Haskell-cafe] type checking that I can't figure out ... In-Reply-To: <4A26F1CF.5070006@henning-thielemann.de> References: <5ae4f2ba0906031018t38bca616q4ca6e92e61a886e7@mail.gmail.com> <89EDF41C-92E7-40B7-9B50-130E86D2C541@z.odi.ac> <4A26F1CF.5070006@henning-thielemann.de> Message-ID: <4310A4E7-F9D8-4FC6-8E08-8E2AA3E80511@z.odi.ac> True, so perhaps better written as: import Data.Maybe (fromMaybe) gets (fromMaybe (error "could not find re in resFwdMap") . M.lookup re . resFwdMap) with more detail in error message as appropriate. -Ross On Jun 3, 2009, at 5:57 PM, Henning Thielemann wrote: > Ross Mellgren schrieb: >> You've applied two solutions to get the value out -- pattern matching >> (Just reinfo) and fromJust. You should use one or the other, but >> not both: >> >> -- pattern matching >> remLookupFwd :: (ReVars m t) => SimplRe t -> ReM m t (ReInfo t) >> remLookupFwd re >> = do fwd <- gets resFwdMap >> let { Just reinfo = M.lookup re fwd } -- >> PROBLEM >> return reinfo >> >> -- fromJust >> remLookupFwd :: (ReVars m t) => SimplRe t -> ReM m t (ReInfo t) >> remLookupFwd re >> = do fwd <- gets resFwdMap >> let { reinfo = fromJust (M.lookup re fwd) } >> -- PROBLEM >> return reinfo >> >> BTW, I would personally write this as one line (untested) >> >> gets (fromJust . M.lookup re . resFwdMap) > > fromJust should be avoided, since it is partial and if it results in > an > error, the error message points to the implementation of fromJust, not > its application. Pattern matching is better, but 'maybe' and > 'fromMaybe' > are best. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From tomahawkins at gmail.com Wed Jun 3 18:15:51 2009 From: tomahawkins at gmail.com (Tom Hawkins) Date: Wed Jun 3 17:59:47 2009 Subject: [Haskell-cafe] ANN: atom-0.0.5 Message-ID: <594c1e830906031515i79343d49u9d290c6e0dfebe51@mail.gmail.com> A few bug fixes and doc improvements. Thanks to John Van Enk and Brian Lewis for the patches! http://hackage.haskell.org/cgi-bin/hackage-scripts/package/atom -Tom From dons at galois.com Wed Jun 3 18:40:33 2009 From: dons at galois.com (Don Stewart) Date: Wed Jun 3 18:26:11 2009 Subject: [Haskell-cafe] Cabal/primes In-Reply-To: <971337.28849.qm@web31106.mail.mud.yahoo.com> References: <971337.28849.qm@web31106.mail.mud.yahoo.com> Message-ID: <20090603224033.GN9163@whirlpool.galois.com> nowgate: > Got it working. > > I downloaded two packages, primes and Numbers. Since Numbers has the three > functions I want to use, primes, isPrime and isProbablyPrime, how do I > uninstall the primes package so there won't be a conflict? Easy! $ ghc-pkg unregister primes -- Don From nowgate at yahoo.com Wed Jun 3 19:11:57 2009 From: nowgate at yahoo.com (michael rice) Date: Wed Jun 3 18:55:52 2009 Subject: [Haskell-cafe] Cabal/primes Message-ID: <177774.16329.qm@web31101.mail.mud.yahoo.com> Excellent! Thanks. Michael --- On Wed, 6/3/09, Don Stewart wrote: From: Don Stewart Subject: Re: [Haskell-cafe] Cabal/primes To: "michael rice" Cc: "brian" , haskell-cafe@haskell.org Date: Wednesday, June 3, 2009, 6:40 PM nowgate: > Got it working. > > I downloaded two packages, primes and Numbers. Since Numbers has the three > functions I want to use, primes, isPrime and isProbablyPrime, how do I > uninstall the primes package so there won't be a conflict? Easy! ? ? $ ghc-pkg unregister primes -- Don -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090603/ba7b7c81/attachment.html From bertram.felgenhauer at googlemail.com Wed Jun 3 20:13:59 2009 From: bertram.felgenhauer at googlemail.com (Bertram Felgenhauer) Date: Wed Jun 3 19:57:59 2009 Subject: [Haskell-cafe] type checking that I can't figure out .... In-Reply-To: <29bf512f0906030811v189ec5ebj8f5cd283df95e08d@mail.gmail.com> References: <5ae4f2ba0906022059y74ba392dlf18960a8e9d2375b@mail.gmail.com> <29bf512f0906022112r1e2163a4oe8070d72e889f039@mail.gmail.com> <200906030742.32810.daniel.is.fischer@web.de> <29bf512f0906030811v189ec5ebj8f5cd283df95e08d@mail.gmail.com> Message-ID: <4a2711ca.09a8100a.2340.fffff888@mx.google.com> Michael Snoyman wrote: > On Wed, Jun 3, 2009 at 8:42 AM, Daniel Fischer wrote: > > Am Mittwoch 03 Juni 2009 06:12:46 schrieb Michael Snoyman: > > > 2. lookup does not return any generalized Monad, just Maybe (I think that > > > should be changed). > > > > Data.Map.lookup used to return a value in any monad you wanted, I believe > > until 6.8 > > inclusive. > > I don't think it's going to change again soon. > > Is there a reason why it only returns in the Maybe monad? I often times have > to write a liftMaybe function to deal with that. Here's the proposal that changed it: http://hackage.haskell.org/trac/ghc/ticket/2309 The discussion about the proposal can be found here: http://www.haskell.org/pipermail/libraries/2008-May/009698.html (There's even the suggestion of adding a function like liftMaybe to Data.Maybe, but apparently nobody turned that into a formal proposal.) Regards, Bertram From pumpkingod at gmail.com Wed Jun 3 21:52:03 2009 From: pumpkingod at gmail.com (Daniel Peebles) Date: Wed Jun 3 21:35:57 2009 Subject: [Haskell-cafe] type checking that I can't figure out .... In-Reply-To: <4a2711ca.09a8100a.2340.fffff888@mx.google.com> References: <5ae4f2ba0906022059y74ba392dlf18960a8e9d2375b@mail.gmail.com> <29bf512f0906022112r1e2163a4oe8070d72e889f039@mail.gmail.com> <200906030742.32810.daniel.is.fischer@web.de> <29bf512f0906030811v189ec5ebj8f5cd283df95e08d@mail.gmail.com> <4a2711ca.09a8100a.2340.fffff888@mx.google.com> Message-ID: It seems like if we could get fail out of Monad and into something like MonadFail/Zero, then it might make sense to make a lookup that returned an instance of that instead? Dan On Wed, Jun 3, 2009 at 8:13 PM, Bertram Felgenhauer wrote: > Michael Snoyman wrote: >> On Wed, Jun 3, 2009 at 8:42 AM, Daniel Fischer wrote: >> > Am Mittwoch 03 Juni 2009 06:12:46 schrieb Michael Snoyman: >> > > 2. lookup does not return any generalized Monad, just Maybe (I think that >> > > should be changed). >> > >> > Data.Map.lookup used to return a value in any monad you wanted, I believe >> > until 6.8 >> > inclusive. >> > I don't think it's going to change again soon. >> >> Is there a reason why it only returns in the Maybe monad? I often times have >> to write a liftMaybe function to deal with that. > > Here's the proposal that changed it: > ?http://hackage.haskell.org/trac/ghc/ticket/2309 > > The discussion about the proposal can be found here: > ?http://www.haskell.org/pipermail/libraries/2008-May/009698.html > > (There's even the suggestion of adding a function like liftMaybe to > Data.Maybe, but apparently nobody turned that into a formal proposal.) > > Regards, > > Bertram > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From jgoerzen at complete.org Wed Jun 3 22:41:24 2009 From: jgoerzen at complete.org (John Goerzen) Date: Wed Jun 3 22:25:24 2009 Subject: [Haskell-cafe] ANN: HSH 2.0.0 Message-ID: <20090604024124.GA24287@complete.org> Hi, I'm pleased to announce the release of version 2.0.0 of HSH, the Haskell shell scripting library. This version features a complete rewrite of the core. Since System.Process has finally become capable enough to be the low-level of HSH, HSH has been reimplemented in terms of it. This has produced a dramatic reduction in code size and complexity. It also gains cross-platform support; HSH now works on Windows. Finally, the API is both simpler and more flexible. The 180-test suite for HSH continues to run and pass with only minor tweaks for the new API. Optional support for setting environment variables on commands to be run has been added as well. It will stay out of your way unless you need it, in which case it is easy. As a reminder, HSH lets you easily set up shell command pipelines. You can also pipe data between Haskell functions and shell commands with complete ease. The package also provides Haskell versions of a number of familiar shell primitives to help you get up and running quickly. HSH 2.0.0 has been uploaded to Hackage. -- John From jvlask at hotmail.com Wed Jun 3 22:57:45 2009 From: jvlask at hotmail.com (John Lask) Date: Wed Jun 3 22:44:07 2009 Subject: [Haskell-cafe] GHCI & Curl under Windows References: <4A266C49.3080207@gmx.org> Message-ID: The issue you are experiencing is the result of ghci not using import libraries to resolve external symbols. Just a bit of explanation for reference, which will also help you understand the solution to your problem. Take for example the function declared as int myexport(int x){...} when creating a dll the exported definitions will be included in the dll, if your using mingw to create the dll, as _myexport or, if your using ms visual c: myexport The import libraries (.a,.lib) will contain _myexport __imp__myexport in the case of mingw .a lib, and also .lib for ms visual c. These entries enable the compiler to resolve the linkage. A client of the library will, generally speaking, have the following declaration __declspec(dllimport) int myexport(int x); the object file created will reference __imp__myexport obviously if you have an object file with __imp__myexport and no import file you will not be able to resolve __imp__myexport to _myexport (or myexport) in the dll and ghci does not use import libraries but just searches for the symbols defined directly. It would be nice if ghci could directly resolve symbols decorated like __imp__ . what to do? Notice that the import libraries (for compilation) contain both symbols _myexport and __imp__myexport, therefore if you can get the haskell modules to reference the _myexport rather than __imp__myexport all will be ok both for ghci and also ghc compilation. so how did the __imp__ get there in the first place? notice the curl has the cabal option via-C, consequently the curl headers will be read in ... #if (defined(WIN32) || defined(_WIN32)) && !defined(CURL_STATICLIB) ... #define CURL_EXTERN __declspec(dllimport) ... i.e. by default curls sais link me to the dynamic library, if in the cabal file you define an option cc-options: -DCURL_STATICLIB then the but retain the link to the dynamic library Extra-libraries: curl where libcurl is the name of the dynamic import library ie libcurl.a (you need to rename libcurl.dll.a, libcurldll.a or whatever your import is called) as it needs to match the dll name as otherwise ghci will not find it eg libcurl.dll and that's it - all should work fine now! AN EXTRA NOTE ON IMPORT LIBRARIES on my system I like to have both the static import and the dynamic import libraries which are named libcurl.a (static) libcurl.dll.a (dynamic import) to make this work with both GHC and GHCI you need to do the following cabal ... Extra-libraries: curl.dll -- reference the dynamic import library, whatever name you have after building the package and installing (your versions will be different) ghc-pkg unregister curl-1.3.2.1 edit the dist\installed-pkg-config and add "extra-ghci-libraries: libcurl", or whatever the name of your .dll file is. Then run ghc-pkg update dist\installed-pkg-config what this will do, is tell ghci the dll name to search for, rather than relying on the name that you have specified with "Extra-libraries: curl.dll" the benefit of this process is that it will enable you to leave the names of your import libraries and dll files for curl untouched, which could otherwise break other dependencies you may have. The long and the short of it is --- much work still needs to be done to ensure that building and maintaining packages on windows platforms via cabal and ghc is painless - so far every package I have used that relied on external libraries has required some tweaking (and not just setting library paths). ----- Original Message ----- From: "Sigbjorn Finne" To: "Martin Huschenbett" Cc: "haskell" Sent: Thursday, June 04, 2009 12:59 AM Subject: Re: [Haskell-cafe] GHCI & Curl under Windows > On Wed, 03 Jun 2009 05:27:53 -0700, Martin Huschenbett > wrote: > >> Hi Haskellers, >> >> I've installed the newest Haskell Platform under Vista and downloaded a >> pre compiled version of curl-7.19.4 for MinGW. After changing the build >> type in curl.cabal to Simple and supplying the needed paths I could even >> build and install curl for haskell. >> >> If I write a program using curl and compile it with GHC everything works >> fine. But if I try to execute the main function of my program in GHCI I >> always get the following error message: >> >> Loading package curl-1.3.5 ... linking ... : >> C:\Devel\Haskell\curl-1.3.5\ghc-6.10.3\HScurl-1.3.5.o: unknown symbol >> `__imp__curl_easy_getinfo': unable to load package `curl-1.3.5' >> >> Did anybody have the same problem and knows how to fix it? >> > > Hi Martin, > > perhaps you already have, but did you go through this writeup > > http://haskell.forkio.com/Home/curl-win32 > > and see if there are useful pointers there that might help? > > --sigbjorn > > -- > Using Opera's revolutionary e-mail client: http://www.opera.com/mail/ > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From aslatter at gmail.com Thu Jun 4 00:40:49 2009 From: aslatter at gmail.com (Antoine Latter) Date: Thu Jun 4 00:24:45 2009 Subject: [Haskell-cafe] type checking that I can't figure out .... In-Reply-To: References: <5ae4f2ba0906022059y74ba392dlf18960a8e9d2375b@mail.gmail.com> <29bf512f0906022112r1e2163a4oe8070d72e889f039@mail.gmail.com> <200906030742.32810.daniel.is.fischer@web.de> <29bf512f0906030811v189ec5ebj8f5cd283df95e08d@mail.gmail.com> <4a2711ca.09a8100a.2340.fffff888@mx.google.com> Message-ID: <694519c50906032140p6ab9decei448b6824381c46b5@mail.gmail.com> On Wed, Jun 3, 2009 at 8:52 PM, Daniel Peebles wrote: > It seems like if we could get fail out of Monad and into something > like MonadFail/Zero, then it might make sense to make a lookup that > returned an instance of that instead? > > Dan > Do you mean splitting up MonadPlus/Alternative into two classes? Or we could just return in MonadPlus/Alternative. Antoine From vigalchin at gmail.com Thu Jun 4 00:58:22 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Thu Jun 4 00:42:17 2009 Subject: [Haskell-cafe] cabalizing "legacy' source Message-ID: <5ae4f2ba0906032158l37e58849j8eac09ced9947308@mail.gmail.com> Hello, I have cabalizing some "legacy" Haskell source. By "legacy", I totally don't mean in a pejorative sense ... code has been designed and written well. I am making good progress ... I have succeeded in building an archive file(library) on a POSIX platform, i.e. Linux. The original author intended to build several executables from this .a file. In addition there are many pairings of .hs/.lhs along with "main" test files. Currently I have only one .cabal file. This is inadequate for the author's intent: 1) I need to build "n" test executables. 2) I need to build 1/2 CLI executables. I need advice on the cabal front. E.g. should I first run the library .cabal and then run several subsidary .cabal files, e.g. "n"test .cabals and also 1/2 CLI executable .cabals??? I am looking for advice so that I don't have a clumsy cabal build process/tree! Thanks, Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090604/84e4c904/attachment.html From vigalchin at gmail.com Thu Jun 4 01:20:02 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Thu Jun 4 01:03:58 2009 Subject: [Haskell-cafe] Re: cabalizing "legacy' source In-Reply-To: <5ae4f2ba0906032158l37e58849j8eac09ced9947308@mail.gmail.com> References: <5ae4f2ba0906032158l37e58849j8eac09ced9947308@mail.gmail.com> Message-ID: <5ae4f2ba0906032220m5e29d824nf62219634e869d47@mail.gmail.com> BTW there is no "Test" directory and also no "CLI" directory .... I am pretty familiar with cabal but not as much with "Unix" Makefile. Probably I need to restructure source directory tree ... to have "library" source in one subtree, tests in another CLI executables in a third BUT can I set up cabal files to do recursive directory "visits" like Makefiles? Vasili On Wed, Jun 3, 2009 at 11:58 PM, Vasili I. Galchin wrote: > Hello, > > I have cabalizing some "legacy" Haskell source. By "legacy", I totally > don't mean in a pejorative sense ... code has been designed and written > well. I am making good progress ... I have succeeded in building an archive > file(library) on a POSIX platform, i.e. Linux. The original author intended > to build several executables from this .a file. In addition there are many > pairings of .hs/.lhs along with "main" test files. Currently I have only one > .cabal file. This is inadequate for the author's intent: > > 1) I need to build "n" test executables. > > 2) I need to build 1/2 CLI executables. > > I need advice on the cabal front. E.g. should I first run the library > .cabal and then run several subsidary .cabal files, e.g. "n"test .cabals and > also 1/2 CLI executable .cabals??? I am looking for advice so that I don't > have a clumsy cabal build process/tree! > > Thanks, Vasili > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090604/e0bc0c41/attachment.html From pumpkingod at gmail.com Thu Jun 4 01:26:32 2009 From: pumpkingod at gmail.com (Daniel Peebles) Date: Thu Jun 4 01:10:27 2009 Subject: [Haskell-cafe] type checking that I can't figure out .... In-Reply-To: <694519c50906032140p6ab9decei448b6824381c46b5@mail.gmail.com> References: <5ae4f2ba0906022059y74ba392dlf18960a8e9d2375b@mail.gmail.com> <29bf512f0906022112r1e2163a4oe8070d72e889f039@mail.gmail.com> <200906030742.32810.daniel.is.fischer@web.de> <29bf512f0906030811v189ec5ebj8f5cd283df95e08d@mail.gmail.com> <4a2711ca.09a8100a.2340.fffff888@mx.google.com> <694519c50906032140p6ab9decei448b6824381c46b5@mail.gmail.com> Message-ID: Yeah, in a way similar to ArrowPlus/ArrowZero. Then again, I'm not sure whether it would be meaningful to split up MonadPlus like that. On Thu, Jun 4, 2009 at 12:40 AM, Antoine Latter wrote: > On Wed, Jun 3, 2009 at 8:52 PM, Daniel Peebles wrote: >> It seems like if we could get fail out of Monad and into something >> like MonadFail/Zero, then it might make sense to make a lookup that >> returned an instance of that instead? >> >> Dan >> > > Do you mean splitting up MonadPlus/Alternative into two classes? Or we > could just return in MonadPlus/Alternative. > > Antoine > From kyagrd at gmail.com Thu Jun 4 01:39:03 2009 From: kyagrd at gmail.com (Ahn, Ki Yung) Date: Thu Jun 4 01:22:56 2009 Subject: [Haskell-cafe] Scary type inference for monadic function definitions Message-ID: Scary type inference for monadic function definitions (or, why you'd want to annotate types for monadic function definitions) This is a real example that I've experienced. I defined the following function. > checkOneVerseByLineWith readLine v = > do mg <- readLine > case mg of > Just g -> return Just (v==g) > Nothing -> return Nothing My intention was to use it something like this: checkOneVerseByLineWith (readline "% ") where readline is the library function from System.Console.Readline. As you can see, there is an obvious mistake which I forgot to group (Just (v==g)) in parenthesis. However, GHC or any other Haskell 98 compliant implementation will infer a type for you and this will type check! Try it yourself if in doubt. Of course, checkOneVerseByLineWith (readline "% ") won't type check because checkOneVerseByLineWith has strange type. The reason why the above definition type checks is because ((->) r) is an instance of Monad. From kyagrd at gmail.com Thu Jun 4 01:56:56 2009 From: kyagrd at gmail.com (Ahn, Ki Yung) Date: Thu Jun 4 01:40:48 2009 Subject: [Haskell-cafe] Re: Scary type inference for monadic function definitions Message-ID: Ahn, Ki Yung ? ?: > Scary type inference for monadic function definitions > (or, why you'd want to annotate types for monadic function definitions) > > This is a real example that I've experienced. > > I defined the following function. > >> checkOneVerseByLineWith readLine v = >> do mg <- readLine >> case mg of >> Just g -> return Just (v==g) >> Nothing -> return Nothing > > My intention was to use it something like this: > > checkOneVerseByLineWith (readline "% ") > > where readline is the library function from System.Console.Readline. > > As you can see, there is an obvious mistake which I forgot to > group (Just (v==g)) in parenthesis. However, GHC or any other > Haskell 98 compliant implementation will infer a type for you > and this will type check! Try it yourself if in doubt. > > Of course, checkOneVerseByLineWith (readline "% ") won't type check > because checkOneVerseByLineWith has strange type. The reason why > the above definition type checks is because ((->) r) is an instance > of Monad. Oh, I happened to be importing Control.Monad.Trans somehow, it just doesn't work with Prelude import itself. And, there were already some discussions on this last year: [Haskell-cafe] The danger of Monad ((->) r) http://www.mail-archive.com/haskell-cafe@haskell.org/msg23680.html Tomasz Zielonka Tue, 15 May 2007 03:05:30 -0700 From wren at freegeek.org Thu Jun 4 03:13:26 2009 From: wren at freegeek.org (wren ng thornton) Date: Thu Jun 4 02:57:22 2009 Subject: [Haskell-cafe] Functors and the Visitor Pattern In-Reply-To: <23851113.post@talk.nabble.com> References: <23851113.post@talk.nabble.com> Message-ID: <4A277416.8040707@freegeek.org> Tom.Amundsen wrote: > So, last night, I was having this problem with my Java code where I couldn't > figure out for the life of me how to write a piece of code without a big if > {} else if {} else if {} ... else {} structure. I was Googling "Java > Reflection" to try to determine how to "cast to the most concerete subclass > at runtime." Then it dawned on me that what I was trying to do has already > been solved by using the Visitor design pattern. > > Then, after reading the Visitor design pattern page on Wiki, it said that > the visitor pattern is essentially an implementation of a functor. Aha! It > totally clicked. The Visitor pattern allows you to collect code for similar > operations, while spreading apart code for similar objects. Now that really > sounds like a functor! > > Although, now I'm second guessing myself, because I can't figure out how we > could create some design pattern that simulates an applicative functor. I'm > pretty sure the Visitor pattern doesn't take you this far (but I am willing > to be corrected). So, is there a way to create applicative functors in > non-functional languages? What would that pattern look like? The Visitor pattern isn't a functor, it's a collection of things. The type being visited is the functor[1], the set of methods on that type for accepting a visitor is a catamorphism[2], and the visitor itself is an algebra for the functor[3]. [1] Or rather, the coproduct of all related classes that can chain a visitor forms a type, and that type is a functor. [2] For the recursive Visitor pattern I use most often, that is. For the non-recursive version it's usually fmap. This is the part where the pattern gets a bit shaky because there are actually many different patterns all called "Visitor". The main points of interest are whether it's recursive or not, and whether it applies the visitor to itself, to its children, or both. non-recursive + itself == ($) non-recursive + children == fmap (under open-recursion interpretation of the type, aka all nodes are elements) recursive + children == fmap (under closed-recursion interpretation, aka only fringe nodes are elements) recursive + both == cata (usually, though it depends how you aggregate) recursive + itself == This is actually a variant of the Iterator pattern [3] Though again there's some variation in different "Visitor" patterns. Some variants of the pattern include some of the recursion pattern in the visitor itself rather than in the methods on the visited type. It can be harder to maintain since it's less modular, though it allows the visit methods to serve as many different functions which can be helpful if you need more than one of ($), fmap, cata, traverse,... -- Live well, ~wren From ketil at malde.org Thu Jun 4 03:14:58 2009 From: ketil at malde.org (Ketil Malde) Date: Thu Jun 4 02:59:03 2009 Subject: [Haskell-cafe] measure a function in ghci In-Reply-To: (Jason Dagit's message of "Wed\, 3 Jun 2009 12\:20\:09 -0700") References: <45fccde20906031147w78128959l40a4aa8cec7c0513@mail.gmail.com> Message-ID: <878wk8zczx.fsf@malde.org> Jason Dagit writes: > Be wary of timing things in GHCi. By default there are no optimizations in > ghci so you could find that one implementation is much worse than the other > but the situation might be completely different when optimizations are > enabled. I'm pretty sure if you start ghci with the -O flag that it will > use optimizations. ...or if you compile your module first (ghc -c), I believe GHCi will use the compiled code. -k -- If I haven't seen further, it is by standing in the footprints of giants From kyagrd at gmail.com Thu Jun 4 03:40:09 2009 From: kyagrd at gmail.com (Ahn, Ki Yung) Date: Thu Jun 4 03:24:04 2009 Subject: [Haskell-cafe] ANN: memscript-0.0.0.2 (Command line utility for memorizing scriptures or any other text) Message-ID: memscript: Command line utility for memorizing scriptures or any other text http://hackage.haskell.org/cgi-bin/hackage-scripts/package/memscript "memscript " Run memscript with a UTF-8 (or ASCII since ASCII is a subset of UTF8) plain text file. Try to exactly guess the text line by line. If your guess is wrong it will show you a diff like output comparing your guess and the original verse. This will repeat until you get all the verses right. For the test data I included four beloved Psalms (1,23,121,127) from the Old Testament, each in Revised Korean Version (RKV) and New International Version (NIV), which I happened to have had to memorize. You can use it for any other text you'd want to memorize, such as your favorite poems, quotes, or whatsoever. No craft or ticks, really simple and straightforward utility but serves well for the purpose. I used readline because that was the only sane way I know of handling multibyte inputs. ==== an example usage ==== kyagrd@kyagrd:~/cscs/memscript$ memscript 001en.txt % Blessed is the man who does not walk in the counsel of the wicked or stand in the way of sinners or sit in the seat of mockers. % But his delight is in the law of the LORD, and on his law he meditates night and day. === < But his delight is in the law of the LORD, and on his law he meditates day and night. --- > But his delight is in the law of the LORD, and on his law he meditates night and day. === % But his delight is in the law of the LORD, and on his law he meditates day and night. % He is like a tree planted by streams of water, which yields its fruit in season and whose leaf does not wither. Whatever he does prospers. % Not so the wicked! They are like chaff that the wind blows away. % The wicked will not stand in the judgment, nor sinners in the assembly of the righteous. === < Therefore the wicked will not stand in the judgment, nor sinners in the assembly of the righteous. --- > The wicked will not stand in the judgment, nor sinners in the assembly of the righteous. === % Therefore the wicked will not stand in the judgment, nor sinners in the assembly of the righteous. % For the LORD watches over the way of the righteous, but the way of the wicked will perish. kyagrd@kyagrd:~/cscs/memscript$ From evan at eklitzke.org Thu Jun 4 03:41:17 2009 From: evan at eklitzke.org (Evan Klitzke) Date: Thu Jun 4 03:25:12 2009 Subject: [Haskell-cafe] Text formatting question Message-ID: I'm writing code with hslogger, and I'm finding myself frequently writing things like this: infoM $ printf "%s saw %s with %s" (show x) (show y) (show z) On #haskell I asked about why you can't have use %s with any instance of (Show a), and augustss, the Text.Printf maintainer, pointed out that it's not possible in Haskell 98 because of overlapping instances. So I'm trying to figure out the best way to work around this in my code. Some of the logging statements can get kind of long, so the ability to elide the calls to `show` would be nice. So what's the best way to do this? I was thinking of making my own variant of printf that only accepted the %s formatter and took (Show a)'s as arguments, but there might be a simpler way? Another thing is the code is already fairly GHC specific at this point, so if there are GHC extensions that might be useful here that I don't know about, I'm interested in hearing about them. Thanks. -- Evan Klitzke :wq From wren at freegeek.org Thu Jun 4 03:52:12 2009 From: wren at freegeek.org (wren ng thornton) Date: Thu Jun 4 03:36:07 2009 Subject: [Haskell-cafe] type checking that I can't figure out .... In-Reply-To: References: <5ae4f2ba0906022059y74ba392dlf18960a8e9d2375b@mail.gmail.com> <29bf512f0906022112r1e2163a4oe8070d72e889f039@mail.gmail.com> <200906030742.32810.daniel.is.fischer@web.de> <29bf512f0906030811v189ec5ebj8f5cd283df95e08d@mail.gmail.com> <4a2711ca.09a8100a.2340.fffff888@mx.google.com> <694519c50906032140p6ab9decei448b6824381c46b5@mail.gmail.com> Message-ID: <4A277D2C.7040705@freegeek.org> Daniel Peebles wrote: > Yeah, in a way similar to ArrowPlus/ArrowZero. Then again, I'm not > sure whether it would be meaningful to split up MonadPlus like that. Well, we could always have: class MonadZero m => MonadPlus m The suggestion is just to broaden the scope of mzero so that you can have it without requiring mplus as well (since mplus is much more specific than mzero). If we have a MonadZero, then the call to fail when pattern binds fail could be replaced with calls to mzero (or at the very least, fail can be moved to MonadZero as well to clean up Monad). Then Monad is clean and accurate, and people just depend on MonadZero if they choose to do pattern binds rather than catching all patterns with a case expression. -- Live well, ~wren From johan.tibell at gmail.com Thu Jun 4 03:55:11 2009 From: johan.tibell at gmail.com (Johan Tibell) Date: Thu Jun 4 03:39:25 2009 Subject: [Haskell-cafe] Functors and the Visitor Pattern In-Reply-To: <4A277416.8040707@freegeek.org> References: <23851113.post@talk.nabble.com> <4A277416.8040707@freegeek.org> Message-ID: <90889fe70906040055w2da66abdv58465566dfb8a611@mail.gmail.com> On Thu, Jun 4, 2009 at 9:13 AM, wren ng thornton wrote: > The Visitor pattern isn't a functor, it's a collection of things. The type > being visited is the functor[1], the set of methods on that type for > accepting a visitor is a catamorphism[2], and the visitor itself is an > algebra for the functor[3]. > > > [1] Or rather, the coproduct of all related classes that can chain a > visitor forms a type, and that type is a functor. > > > [2] For the recursive Visitor pattern I use most often, that is. For the > non-recursive version it's usually fmap. This is the part where the pattern > gets a bit shaky because there are actually many different patterns all > called "Visitor". The main points of interest are whether it's recursive or > not, and whether it applies the visitor to itself, to its children, or both. > > non-recursive + itself == ($) > > non-recursive + children == fmap (under open-recursion interpretation of > the type, aka all nodes are elements) > > recursive + children == fmap (under closed-recursion interpretation, aka > only fringe nodes are elements) > > recursive + both == cata (usually, though it depends how you aggregate) > > recursive + itself == This is actually a variant of the Iterator pattern Could you be so kind to give an example for each? Cheers, Johan -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090604/e0d6257b/attachment.html From magnus at therning.org Thu Jun 4 04:48:07 2009 From: magnus at therning.org (Magnus Therning) Date: Thu Jun 4 04:32:05 2009 Subject: [Haskell-cafe] understanding regex libs In-Reply-To: <5F799E77-BC24-4A61-8CE9-3A00FF5912FC@joyful.com> References: <5F799E77-BC24-4A61-8CE9-3A00FF5912FC@joyful.com> Message-ID: On Wed, Jun 3, 2009 at 5:18 PM, Simon Michael wrote: > Hi Chris.. thanks for your extensive work on haskell regex libs. > > I'm looking for a good way to make my regex-using app more portable to > windows. > I couldn't figure out the difference between the regex-pcre and > regex-pcre-builtin on hackage. Could you clarify ? Once you find out please update the page on the wiki covering the different regular expression libs available for Haskell: http://haskell.org/haskellwiki/Regular_expressions AFAICS it lacks information on portability of the non-native libs. /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe From lemming at henning-thielemann.de Thu Jun 4 06:53:29 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Thu Jun 4 06:37:27 2009 Subject: [Haskell-cafe] cabalizing "legacy' source In-Reply-To: <5ae4f2ba0906032158l37e58849j8eac09ced9947308@mail.gmail.com> References: <5ae4f2ba0906032158l37e58849j8eac09ced9947308@mail.gmail.com> Message-ID: <4A27A7A9.2040604@henning-thielemann.de> Vasili I. Galchin wrote: > Hello, > > I have cabalizing some "legacy" Haskell source. By "legacy", I > totally don't mean in a pejorative sense ... code has been designed and > written well. I am making good progress ... I have succeeded in building > an archive file(library) on a POSIX platform, i.e. Linux. The original > author intended to build several executables from this .a file. In > addition there are many pairings of .hs/.lhs along with "main" test > files. Currently I have only one .cabal file. This is inadequate for the > author's intent: > > 1) I need to build "n" test executables. > > 2) I need to build 1/2 CLI executables. > > I need advice on the cabal front. E.g. should I first run the library > .cabal and then run several subsidary .cabal files, e.g. "n"test .cabals > and also 1/2 CLI executable .cabals??? I am looking for advice so that I > don't have a clumsy cabal build process/tree! You can build several executables from one cabal file. I propose to enable compilation of test programs only by user request. See for example: http://code.haskell.org/~thielema/tagchup/tagchup.cabal From lemming at henning-thielemann.de Thu Jun 4 06:56:02 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Thu Jun 4 06:40:38 2009 Subject: [Haskell-cafe] Scary type inference for monadic function definitions In-Reply-To: References: Message-ID: <4A27A842.9050208@henning-thielemann.de> Ahn, Ki Yung wrote: > Scary type inference for monadic function definitions > (or, why you'd want to annotate types for monadic function definitions) > > This is a real example that I've experienced. > > I defined the following function. > >> checkOneVerseByLineWith readLine v = >> do mg <- readLine >> case mg of >> Just g -> return Just (v==g) >> Nothing -> return Nothing How about liftM (fmap (v==)) readLine ? -- Mit freundlichen Gruessen Henning Thielemann Viele Gruesse Henning Martin-Luther-Universitaet Halle-Wittenberg, Institut fuer Informatik Tel. +49 - 345 - 55 24773 Fax +49 - 345 - 55 27333 From jwlato at gmail.com Thu Jun 4 07:26:53 2009 From: jwlato at gmail.com (John Lato) Date: Thu Jun 4 07:10:48 2009 Subject: [Haskell-cafe] Re: Strange type error with associated type synonyms Message-ID: <9979e72e0906040426o2fcbfb1cp72e3ab436c0bf546@mail.gmail.com> Hello, Apologies for the late contribution; I've been away recently. I have a very strong opinion on this, though. > From: Bulat Ziganshin > > Thursday, May 28, 2009, 2:06:36 AM, HT wrote: > > Prelude>> let a = 'a'; b = "b" in a==b > >> :1:27: >> ? ? ?Couldn't match expected type `Char' against inferred type `[Char]' >> ? ? ?.... > >> Is the type of 'a' wrong or that of 'b'? > > it is not important, well, at least we can live with it. Compiler > should say: > > First argument of == should be of type String > while a is of type Char I find this to be a somewhat important issue. If there weren't so many polymorphic functions it wouldn't be as big of a problem. The only reason the first argument of == should be a String is because the second argument is (or alternatively 2nd should be Char, etc.). For polymorphic functions, in which the type of one argument is fixed by another, I think the error message should ideally point out how the compiler is getting expected/inferred types. E.g. Couldn't match expected type `Char' against inferred type `[Char]' Type of [first argument] to `==' must match type of [second argument] where [first|second argument] is filled in with the appropriate expressions. I've become somewhat adept at figuring this out, but I think it would be helpful for those who haven't experienced it before. A related issue is with multiple function definitions. Here's a short example: foo n = ... where bar (Just a) = return $ somefunc a bar (Nothing) = somefunc n a = otherfunc assume that 'a' and 'n' have the same type. Now the type checker won't allow bar, because the two definitions have differing types. GHC's error message would ideally state that the definitions for 'bar' have differing types, but instead we get a message about mismatched types within one of the definitions. I know this example is rather contrived, but I don't have any real code to hand because I've fixed it already. You get a better message if you give a type signature for 'bar', but that requires lexical scoping (at least in my case), which means the code would no longer be Haskell98 (which it otherwise is IIRC). Cheers, John Lato From pkeir at dcs.gla.ac.uk Thu Jun 4 08:01:45 2009 From: pkeir at dcs.gla.ac.uk (Paul Keir) Date: Thu Jun 4 07:45:39 2009 Subject: [Haskell-cafe] Nested Lists Message-ID: <3CDFB8AFEA98E34CB599475AB11589C82C3DB6@EX2.ad.dcs.gla.ac.uk> Hi all, If I have a list, and I'd like to convert it to a list of lists, each of length n, I can use a function like bunch: bunch _ [] = [] bunch n as = let (c,cs) = splitAt n as in c:bunch n cs > bunch 8 [1..16] [[1,2,3,4,5,6,7,8],[9,10,11,12,13,14,15,16]] If I now want to do the same for the nested lists, I can compose an application involving both map and bunch: > map (bunch 4) . bunch 8 $ [1..16] [[[1,2,3,4],[5,6,7,8]],[[9,10,11,12],[13,14,15,16]]] and I can "bunch" the new length 4 lists again: > map (map (bunch 2)) . map (bunch 4) . bunch 8 $ [1..16] [[[[1,2],[3,4]],[[5,6],[7,8]]],[[[9,10],[11,12]],[[13,14],[15,16]]]] Clearly there is a pattern here involving the bunch function and latterly, three Int parameters; 2, 4 and 8. My question is, can I create a function that will take such parameters as a list, and give the same result, for example: > f [2,4,8] [1..16] [[[[1,2],[3,4]],[[5,6],[7,8]]],[[[9,10],[11,12]],[[13,14],[15,16]]]] or perhaps: > f [bunch 2, bunch 4, bunch 8] [1..16] [[[[1,2],[3,4]],[[5,6],[7,8]]],[[[9,10],[11,12]],[[13,14],[15,16]]]] I think it may not be possible because the type signature of f would depend on the length of its list parameter; but I'm not sure. -Paul -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090604/39bb4ea9/attachment.html From emax at chalmers.se Thu Jun 4 08:26:58 2009 From: emax at chalmers.se (Emil Axelsson) Date: Thu Jun 4 08:06:39 2009 Subject: [Haskell-cafe] Nested Lists In-Reply-To: <3CDFB8AFEA98E34CB599475AB11589C82C3DB6@EX2.ad.dcs.gla.ac.uk> References: <3CDFB8AFEA98E34CB599475AB11589C82C3DB6@EX2.ad.dcs.gla.ac.uk> Message-ID: <4A27BD92.2040201@chalmers.se> Hi Paul, I don't have time to solve your actual problem, but I think it's doable using associated type families. I attach a module which I'm using in my current project that does things quite similar to what you're asking for. For example: *Main> replicateArray (3 :> IntArr) 4 [4,4,4] *Main> replicateArray (4 :> 3 :> IntArr) 4 [[4,4,4],[4,4,4],[4,4,4],[4,4,4]] Hope it helps! / Emil Paul Keir skrev: > Hi all, > > If I have a list, and I'd like to convert it to a list of lists, > each of length n, I can use a function like bunch: > > bunch _ [] = [] > bunch n as = let (c,cs) = splitAt n as in c:bunch n cs > > > bunch 8 [1..16] > [[1,2,3,4,5,6,7,8],[9,10,11,12,13,14,15,16]] > > If I now want to do the same for the nested lists, I can compose > an application involving both map and bunch: > > > map (bunch 4) . bunch 8 $ [1..16] > [[[1,2,3,4],[5,6,7,8]],[[9,10,11,12],[13,14,15,16]]] > > and I can "bunch" the new length 4 lists again: > > > map (map (bunch 2)) . map (bunch 4) . bunch 8 $ [1..16] > [[[[1,2],[3,4]],[[5,6],[7,8]]],[[[9,10],[11,12]],[[13,14],[15,16]]]] > > Clearly there is a pattern here involving the bunch function and > latterly, three Int parameters; 2, 4 and 8. My question is, can I > create a function that will take such parameters as a list, and > give the same result, for example: > > > f [2,4,8] [1..16] > [[[[1,2],[3,4]],[[5,6],[7,8]]],[[[9,10],[11,12]],[[13,14],[15,16]]]] > > or perhaps: > > > f [bunch 2, bunch 4, bunch 8] [1..16] > [[[[1,2],[3,4]],[[5,6],[7,8]]],[[[9,10],[11,12]],[[13,14],[15,16]]]] > > I think it may not be possible because the type signature of f would > depend on the length of its list parameter; but I'm not sure. > > -Paul > > > ------------------------------------------------------------------------ > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe -------------- next part -------------- A non-text attachment was scrubbed... Name: Bunch.hs Type: text/x-haskell Size: 1061 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090604/45a3895c/Bunch.bin From felipe.lessa at gmail.com Thu Jun 4 08:49:48 2009 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Thu Jun 4 08:33:45 2009 Subject: [Haskell-cafe] Nested Lists In-Reply-To: <3CDFB8AFEA98E34CB599475AB11589C82C3DB6@EX2.ad.dcs.gla.ac.uk> References: <3CDFB8AFEA98E34CB599475AB11589C82C3DB6@EX2.ad.dcs.gla.ac.uk> Message-ID: <20090604124948.GA31105@kira.casa> How about... *Main> bunch () [1..16] [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] *Main> bunch (8 :+: ()) [1..16] [[1,2,3,4,5,6,7,8],[9,10,11,12,13,14,15,16]] *Main> bunch (8 :+: 4 :+: ()) [1..16] [[[1,2,3,4],[5,6,7,8]],[[9,10,11,12],[13,14,15,16]]] *Main> bunch (8 :+: 4 :+: 2 :+: ()) [1..16] [[[[1,2],[3,4]],[[5,6],[7,8]]],[[[9,10],[11,12]],[[13,14],[15,16]]]] Here's the hack :) > {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TypeFamilies #-} > > infixr 6 :+: > data Bunch b = Int :+: b > > class Bunchable b a where > type Bunched b a :: * > bunch :: b -> [a] -> Bunched b a > > instance Bunchable () a where > type Bunched () a = [a] > bunch () = id > > instance Bunchable b a => Bunchable (Bunch b) a where > type Bunched (Bunch b) a = [Bunched b a] > bunch (n :+: r) = map (bunch r) . simpleBunch n > > simpleBunch :: Int -> [a] -> [[a]] > simpleBunch _ [] = [] > simpleBunch n as = let (c,cs) = splitAt n as in c:simpleBunch n cs The key here is that 'Bunch' reflects its lenght on its type, but '[]' doesn't. It may be possible to keep using a list, but it would be very ugly, I guess. -- Felipe. From jgoerzen at complete.org Thu Jun 4 09:20:36 2009 From: jgoerzen at complete.org (John Goerzen) Date: Thu Jun 4 09:04:33 2009 Subject: [Haskell-cafe] Static link to packages on Hackage? Message-ID: <4A27CA24.8020809@complete.org> Hi, I'd like to be able to put a static link to the Haddock docs for the current version of various packages on my homepage. Right now, I can't find any such URL; they all look like: http://hackage.haskell.org/packages/archive/HSH/2.0.0/doc/html/HSH.html I'd like if there could be something like: http://hackage.haskell.org/packages/archive/HSH/latest/doc/html/HSH.html Incidentally, you can click on this "latest" URL but it doesn't go to the correct version. I can't just link to the package page either, because sometimes it won't have docs (such as shortly after I've uploaded a new version). Ideas? From martijn at van.steenbergen.nl Thu Jun 4 10:22:30 2009 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Thu Jun 4 10:06:30 2009 Subject: [Haskell-cafe] A small puzzle: inTwain as function of foldr Message-ID: <4A27D8A6.1090605@van.steenbergen.nl> Bonjour caf?, A small puzzle: Consider the function inTwain that splits a list of even length evenly into two sublists: > inTwain "Hello world!" ("Hello ","world!") Is it possible to implement inTwain such that the recursion is done by one of the standard list folds? Is there a general way to tell if a problem can be expressed as a fold? Thank you, Martijn. From ganesh.sittampalam at credit-suisse.com Thu Jun 4 10:32:45 2009 From: ganesh.sittampalam at credit-suisse.com (Sittampalam, Ganesh) Date: Thu Jun 4 10:17:04 2009 Subject: [Haskell-cafe] A small puzzle: inTwain as function of foldr In-Reply-To: <4A27D8A6.1090605@van.steenbergen.nl> References: <4A27D8A6.1090605@van.steenbergen.nl> Message-ID: <16442B752A06A74AB4D9F9A5FF076E4B01ABABEC@ELON17P32001A.csfb.cs-group.com> Martijn van Steenbergen wrote: > Consider the function inTwain that splits a list of even length > evenly into two sublists: > > > inTwain "Hello world!" > ("Hello ","world!") > > Is it possible to implement inTwain such that the recursion is done > by one of the standard list folds? Does this help? http://www.brics.dk/RS/02/12/BRICS-RS-02-12.pdf Ganesh =============================================================================== Please access the attached hyperlink for an important electronic communications disclaimer: http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html =============================================================================== From chaddai.fouche at gmail.com Thu Jun 4 10:33:36 2009 From: chaddai.fouche at gmail.com (=?UTF-8?B?Q2hhZGRhw68gRm91Y2jDqQ==?=) Date: Thu Jun 4 10:17:30 2009 Subject: [Haskell-cafe] A small puzzle: inTwain as function of foldr In-Reply-To: <4A27D8A6.1090605@van.steenbergen.nl> References: <4A27D8A6.1090605@van.steenbergen.nl> Message-ID: On Thu, Jun 4, 2009 at 4:22 PM, Martijn van Steenbergen wrote: > Bonjour caf?, > > A small puzzle: > > Consider the function inTwain that splits a list of even length evenly into > two sublists: > >> inTwain "Hello world!" > ("Hello ","world!") > > Is it possible to implement inTwain such that the recursion is done by one > of the standard list folds? I don't think it is without a length before at least. On the other hand if your specification is just "splits a list of even length evenly into two sublists", you can contrive something with a simple foldr : inTwain = foldr (\x ~(xs,ys) -> (ys, x:xs)) ([],[]) -- Jeda? From lemming at henning-thielemann.de Thu Jun 4 10:54:44 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Thu Jun 4 10:38:51 2009 Subject: [Haskell-cafe] Nested Lists In-Reply-To: <3CDFB8AFEA98E34CB599475AB11589C82C3DB6@EX2.ad.dcs.gla.ac.uk> References: <3CDFB8AFEA98E34CB599475AB11589C82C3DB6@EX2.ad.dcs.gla.ac.uk> Message-ID: On Thu, 4 Jun 2009, Paul Keir wrote: > > Hi all, > > If I have a list, and I'd like to convert it to a list of lists, > each of length n, I can use a function like bunch: > > bunch _ [] = [] > bunch n as = let (c,cs) = splitAt n as in c:bunch n cs http://hackage.haskell.org/packages/archive/utility-ht/0.0.5.1/doc/html/Data-List-HT.html#v%3AsliceVertical > > bunch 8 [1..16] > [[1,2,3,4,5,6,7,8],[9,10,11,12,13,14,15,16]] > > If I now want to do the same for the nested lists, I can compose > an application involving both map and bunch: > > > map (bunch 4) . bunch 8 $ [1..16] > [[[1,2,3,4],[5,6,7,8]],[[9,10,11,12],[13,14,15,16]]] > > and I can "bunch" the new length 4 lists again: > > > map (map (bunch 2)) . map (bunch 4) . bunch 8 $ [1..16] > [[[[1,2],[3,4]],[[5,6],[7,8]]],[[[9,10],[11,12]],[[13,14],[15,16]]]] Don't you first break the list into 2-element lists, then the resulting list into 2-element lists and so on? I.e. bunch 2 . bunch 2 . bunch 2 $ [1..16] Calling 'bunch' multiple times is problematic since every call has a different signature, a different depth of list nesting. I guess you have to use a tree type, which allows arbitrary list nesting at run-time. From pkeir at dcs.gla.ac.uk Thu Jun 4 12:09:29 2009 From: pkeir at dcs.gla.ac.uk (Paul Keir) Date: Thu Jun 4 11:55:06 2009 Subject: [Haskell-cafe] RE: Nested Lists References: <3CDFB8AFEA98E34CB599475AB11589C82C3DB6@EX2.ad.dcs.gla.ac.uk> <3CDFB8AFEA98E34CB599475AB11589C82C3DBD@EX2.ad.dcs.gla.ac.uk> Message-ID: <3CDFB8AFEA98E34CB599475AB11589C82C3DBE@EX2.ad.dcs.gla.ac.uk> Emil, Felipe, Thanks. I don't know Type Families, but take the point that the input can be parameterised with something something other than a list. i.e. (8 :+: 4 :+: 2 :+: ()) presumably has the same type as (4 :+: 2 :+: ()). My intention was to use common list functions on the sublists, but always then a concat for each level, to return to a flat list. With that in mind I made the following oddity, which in any case doesn't compile due to its use of infinite types. app (f:fs) es = appUp (f:fs) es where len = genericLength (f:fs) appUp [] es = appDown es len appUp (f:fs) es = appUp (map map fs) (f es) appDown es len = appDown (concat es) (len - 1) appDown es 0 = es Henning, I agree with you, a tree would be much better for this. Thanks. -Paul -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090604/31290354/attachment.html From ttencate at gmail.com Thu Jun 4 12:35:38 2009 From: ttencate at gmail.com (Thomas ten Cate) Date: Thu Jun 4 12:19:32 2009 Subject: [Haskell-cafe] Static link to packages on Hackage? In-Reply-To: <4A27CA24.8020809@complete.org> References: <4A27CA24.8020809@complete.org> Message-ID: http://hackage.haskell.org/packages/archive/HSH/latest/doc/html/HSH.html does take me to a page that says "HSH-2.0.0: Library to mix shell scripting with Haskell programs" in the blue bar at the top. Maybe some kind of cache? Did you try flushing your browser cache and refreshing? Am I missing something? Thomas On Thu, Jun 4, 2009 at 15:20, John Goerzen wrote: > Hi, > > I'd like to be able to put a static link to the Haddock docs for the > current version of various packages on my homepage. ?Right now, I can't > find any such URL; they all look like: > > http://hackage.haskell.org/packages/archive/HSH/2.0.0/doc/html/HSH.html > > I'd like if there could be something like: > > http://hackage.haskell.org/packages/archive/HSH/latest/doc/html/HSH.html > > Incidentally, you can click on this "latest" URL but it doesn't go to > the correct version. > > I can't just link to the package page either, because sometimes it won't > have docs (such as shortly after I've uploaded a new version). > > Ideas? > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From wasserman.louis at gmail.com Thu Jun 4 12:38:09 2009 From: wasserman.louis at gmail.com (Louis Wasserman) Date: Thu Jun 4 12:22:22 2009 Subject: [Haskell-cafe] containers dependency on base Message-ID: I have been unable to compile the stable version of containers-0.2.0.1, having to add the constraint base>=4.0.0.0. Can anybody else duplicate this problem? Should I patch it? (I'm working on another modification to containers and encountered this difficulty when attempting to build the whole package.) Louis Wasserman wasserman.louis@gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090604/0f69f40e/attachment.html From ryani.spam at gmail.com Thu Jun 4 12:52:16 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Thu Jun 4 12:36:10 2009 Subject: [Haskell-cafe] Cabal/primes In-Reply-To: <20090603224033.GN9163@whirlpool.galois.com> References: <971337.28849.qm@web31106.mail.mud.yahoo.com> <20090603224033.GN9163@whirlpool.galois.com> Message-ID: <2f9b2d30906040952i5dc71c6fp325991e652e40ff7@mail.gmail.com> On this note, shouldn't there be "cabal uninstall"? -- ryan On Wed, Jun 3, 2009 at 3:40 PM, Don Stewart wrote: > nowgate: >> Got it working. >> >> I downloaded two packages, primes and Numbers. Since Numbers has the three >> functions I want to use, primes, isPrime and isProbablyPrime, how do I >> uninstall the primes package so there won't be a conflict? > > > Easy! > > ? ?$ ghc-pkg unregister primes > > -- Don > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From gwern0 at gmail.com Thu Jun 4 12:52:58 2009 From: gwern0 at gmail.com (Gwern Branwen) Date: Thu Jun 4 12:36:53 2009 Subject: [Haskell-cafe] ANN: wp-archivebot 0.1 - archive Wikipedia's external links in WebCite Message-ID: I'd like to announce wp-archivebot. # What wp-archivebot is a relatively simple little script which follows all the links in a RSS feed, combs the destination for http:// links, and submits them to WebCite. WebCite https://secure.wikimedia.org/wikipedia/en/wiki/WebCite is an organization much like the more famous Internet Archive. Unlike the Wayback Machine, however, WebCite will archive pages on-demand.* # Why This is good, since link-rot and 404 errors are a fact of life on Wikipedia. Links go stale, fall dead, get banned, edited, censored, etc. If those links are being used as a reference for some important fact or detail, then there is a very big problem. Even the hit-or-miss Internet Archive has proven to be very useful for editors**, so a more reliable way of archiving links would be even better. # Limitations The WebCite FAQhttp://webcitation.org/faq mentions that a good project would be to > develop a wikipedia bot which scans new wikipedia articles for cited URLs, submits an archiving request to WebCite?, and then adds a link to the archived URL behind the cited URL Adding a link would be both quite difficult and require community approval; further, although I have thought about this for years, there's no obvious good way to add a link. Any method is either visually awkward, possibly otiose (if [[Google]] links to google.com as the homepage in its infobox, there's no purpose to have an archived version of google.com!), and certainly will bloat up the markup - even if there's any way to insert links without bolloxing templates and other such constructs. So I'm satisfied to just archive the link. WebCite is searchable, after all. If enough people run bots like this and achieve enough coverage, then perhaps editors can be educated to always check in WebCite as well. # Download & Install As ever, wp-archivebot is Free and is available from Hackage at: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/wp-archivebot You can install with ease by a simple 'cabal install wp-archivebot', or download the tarball and compile it yourself with the usual 'runhaskell Setup configure && runhaskell Setup build && runhaskell Setup install' dance. # Usage wp-archivebot takes one mandatory argument, an email address; WebCite needs to have somewhere to send notices of archival success/failure. wp-archivebot takes a second, optional, argument. This is a RSS feed to use. It defaults to Special:NewPages on the English Wikipedia, but one could just as well follow, say, RecentChanges. Here's an example: > wp-archivebot gwern0@gmail.com 'http://en.wikipedia.org/w/index.php?title=Special:RecentChanges&feed=rss' (This sets my email address as the recipient, and follows RecentChanges. This may not be a good idea as RecentChanges is *much* busier than NewPages.) ## Example Here's an example session's output: [12:35 PM] 829Mb$ wp-archivebot gwern0@gmail.com "http://www.webcitation.org/archive?url=http://en.wikisource.org/wiki/Berkeley,_George,_first_earl_of_Berkeley_(DNB00)&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://www.baseball-reference.com/players/u/uhaltfr01.shtml&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://www.baseball-reference.com/players/u/uhaltfr01.shtml&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://www.baseball-reference.com/minors/player.cgi?id=uhalt-001ber&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://www.baseball-reference.com/minors/player.cgi?id=uhalt-001ber&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://www.timesargus.com/apps/pbcs.dll/article?AID=/20080509/FEATURES02/805090316/1011/FEATURES02&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://www.timesargus.com/apps/pbcs.dll/article?AID=/20080509/FEATURES02/805090316/1011/FEATURES02&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://www.timesargus.com/apps/pbcs.dll/article?AID=/20080509/FEATURES02/805090316/1011/FEATURES02&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://www.timesargus.com/apps/pbcs.dll/article?AID=/20080509/FEATURES02/805090316/1011/FEATURES02&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://www.erniestires.net/&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://www.erniestires.net/&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://thepeerage.com/p4893.htm#i48927&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://thepeerage.com/p4893.htm#i48927&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://www.leighrayment.com/commons/Acommons3.htm&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://www.leighrayment.com/commons/Acommons3.htm&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://thepeerage.com/p4893.htm#i48927&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://thepeerage.com/p4893.htm#i48927&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://www.esec.edu&email=gwern0@gmail.com" "http://www.webcitation.org/archive?url=http://www.esec.edu&email=gwern0@gmail.com" ... # Related The development version (HEAD) of the Gitit wiki has plugin support; one of those plugins, WebArchiver.hs, will on every page-save comb through for off-wiki links and submit them to WebCite in the same way as this bot. It's nice to know that if those links ever disapear, you can retrieve them from WebCite and 'see' the revision with the same set of external links as when the revision was created. * Technically, the Internet Archive will archive on demand as well - but you need to pay them. ** In many more ways than one might expect. For example, not infrequently someone will visit an article and claim it is plagiarizing some other webpage. With the IA, it's easy to go back to the first version of that webpage and crosscheck against the article's history - quite often it is the other website that plagiarized us! -- gwern From ttencate at gmail.com Thu Jun 4 12:57:04 2009 From: ttencate at gmail.com (Thomas ten Cate) Date: Thu Jun 4 12:40:58 2009 Subject: [Haskell-cafe] A small puzzle: inTwain as function of foldr In-Reply-To: <4A27D8A6.1090605@van.steenbergen.nl> References: <4A27D8A6.1090605@van.steenbergen.nl> Message-ID: Possible, yes. Efficient, not really. > inTwain = foldr (\x (ls, rs) -> if length ls == length rs then (x:ls, rs) else (x:(init ls), (last ls):rs)) ([], []) I have a hunch that everything that reduces a list to a fixed-size data structure can be expressed as a fold, simply by carrying around as much intermediate state as necessary. But I'm too lazy and inexperienced to prove this. Thomas On Thu, Jun 4, 2009 at 16:22, Martijn van Steenbergen wrote: > Bonjour caf?, > > A small puzzle: > > Consider the function inTwain that splits a list of even length evenly into > two sublists: > >> inTwain "Hello world!" > ("Hello ","world!") > > Is it possible to implement inTwain such that the recursion is done by one > of the standard list folds? > > Is there a general way to tell if a problem can be expressed as a fold? > > Thank you, > > Martijn. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From thomas.dubuisson at gmail.com Thu Jun 4 13:00:05 2009 From: thomas.dubuisson at gmail.com (Thomas DuBuisson) Date: Thu Jun 4 12:43:59 2009 Subject: [Haskell-cafe] Cabal/primes In-Reply-To: <2f9b2d30906040952i5dc71c6fp325991e652e40ff7@mail.gmail.com> References: <971337.28849.qm@web31106.mail.mud.yahoo.com> <20090603224033.GN9163@whirlpool.galois.com> <2f9b2d30906040952i5dc71c6fp325991e652e40ff7@mail.gmail.com> Message-ID: <4c44d90b0906041000g5035ffc1v91e8ae92fd786a53@mail.gmail.com> On Thu, Jun 4, 2009 at 9:52 AM, Ryan Ingram wrote: > On this note, shouldn't there be "cabal uninstall"? You mean ticket 234? http://hackage.haskell.org/trac/hackage/ticket/234 Yes, its been open for a year and has been quietly waiting for developer time... are you the lucky developer who gets to implement it? Thomas From sebf at informatik.uni-kiel.de Thu Jun 4 13:03:29 2009 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Thu Jun 4 12:47:22 2009 Subject: [Haskell-cafe] containers dependency on base In-Reply-To: References: Message-ID: On Jun 4, 2009, at 6:38 PM, Louis Wasserman wrote: > I have been unable to compile the stable version of > containers-0.2.0.1, having to add the constraint base>=4.0.0.0. Can > anybody else duplicate this problem? I could also not compile containers-0.2.0.1 and as a workaround added the constraint containers ==0.2.0.0 in the cabal file of my package that uses the containers package. Cheers, Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From phunge0 at hotmail.com Thu Jun 4 13:14:36 2009 From: phunge0 at hotmail.com (Brian Bloniarz) Date: Thu Jun 4 12:58:30 2009 Subject: [Haskell-cafe] A small puzzle: inTwain as function of foldr In-Reply-To: <4A27D8A6.1090605@van.steenbergen.nl> References: <4A27D8A6.1090605@van.steenbergen.nl> Message-ID: How about the following, using difference lists? > import Control.Arrow > import qualified Data.DList as D > > start = (Nothing, (D.empty, D.empty)) > > iter (Nothing, (r1, r2)) x = (Just x, (r1, r2)) > iter (Just y, (r1, m)) x = > D.list (Nothing, (D.singleton y, D.singleton x)) > (\r r2 -> let r2' = D.snoc (D.snoc r2 y) x > in (Nothing, (D.snoc r1 r, r2'))) > m > > inTwain :: [a] -> ([a], [a]) > inTwain = (D.toList *** D.toList) . snd . foldl iter start There's no recursion besides the fold. Though using difference lists might be cheating, depending on your definition of cheating :) -Brian > Bonjour caf?, > > A small puzzle: > > Consider the function inTwain that splits a list of even length evenly > into two sublists: > > > inTwain "Hello world!" > ("Hello ","world!") > > Is it possible to implement inTwain such that the recursion is done by > one of the standard list folds? > > Is there a general way to tell if a problem can be expressed as a fold? > > Thank you, > > Martijn. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe _________________________________________________________________ Windows Live?: Keep your life in sync. http://windowslive.com/explore?ocid=TXT_TAGLM_WL_BR_life_in_synch_062009 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090604/661af3a1/attachment.html From ryani.spam at gmail.com Thu Jun 4 13:32:01 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Thu Jun 4 13:15:54 2009 Subject: [Haskell-cafe] Text formatting question In-Reply-To: References: Message-ID: <2f9b2d30906041032n70c71de6r611ffd7d965d26ed@mail.gmail.com> You can use CPS printf, which has the advantage of being completely type-safe: > lit :: String -> (String -> r) -> r > lit s k = k s > str :: (String -> r) -> (String -> r) > str k s = k s > val :: Show a => (String -> r) -> a -> r > val k a = k (show a) > (^) :: ((String -> r) -> s) -> ((String -> s) -> t) -> ((String -> r) -> t) > (a ^ b) k = b $ \s -> a $ \t -> k (s ++ t) > cprintf :: ((String -> String) -> s) -> s > cprintf k = k id ghci> :t cprintf (val ^ lit "a" ^ val) cprintf (val ^ lit "a" ^ val) :: (Show a, Show a1) => a1 -> a -> [Char] ghci> putStrLn $ cprintf (val ^ lit "a" ^ val) 5 () 5a() This can be improved further by using difference lists instead of Strings as the carrier type, to avoid bad behavior in ++, but it's good enough for most uses. It's definitely more wordy than the raw printf, but you can use Template Haskell to build real printf out of it: ghci> putStrLn $ $(sprintf "%va%v") 5 () 5a() Doing so is kind of fun, so I'll leave it as an exercise :) -- ryan On Thu, Jun 4, 2009 at 12:41 AM, Evan Klitzke wrote: > I'm writing code with hslogger, and I'm finding myself frequently > writing things like this: > > infoM $ printf "%s saw %s with %s" (show x) (show y) (show z) > > On #haskell I asked about why you can't have use %s with any instance > of (Show a), and augustss, the Text.Printf maintainer, pointed out > that it's not possible in Haskell 98 because of overlapping instances. > So I'm trying to figure out the best way to work around this in my > code. Some of the logging statements can get kind of long, so the > ability to elide the calls to `show` would be nice. So what's the best > way to do this? > > I was thinking of making my own variant of printf that only accepted > the %s formatter and took (Show a)'s as arguments, but there might be > a simpler way? Another thing is the code is already fairly GHC > specific at this point, so if there are GHC extensions that might be > useful here that I don't know about, I'm interested in hearing about > them. > > Thanks. > > -- > Evan Klitzke :wq > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From simon at joyful.com Thu Jun 4 13:43:28 2009 From: simon at joyful.com (Simon Michael) Date: Thu Jun 4 13:27:36 2009 Subject: [Haskell-cafe] Re: understanding regex libs In-Reply-To: References: <5F799E77-BC24-4A61-8CE9-3A00FF5912FC@joyful.com> Message-ID: Magnus Therning wrote: > Once you find out please update the page on the wiki covering the > different regular expression libs available for Haskell: > http://haskell.org/haskellwiki/Regular_expressions That's a good page, which I've updated a little. It would still be good to clarify the hackage and haddock docs, as they are the front line, and have them link to the above. From florin.craciun at durham.ac.uk Thu Jun 4 13:50:06 2009 From: florin.craciun at durham.ac.uk (CRACIUN F.) Date: Thu Jun 4 13:34:27 2009 Subject: [Haskell-cafe] TASE 2009 - Call for Participation References: <8405C0D818720A45A8C69862358075EE03E3E4@DURMAIL3.mds.ad.dur.ac.uk> <8405C0D818720A45A8C69862358075EE03E3F0@DURMAIL3.mds.ad.dur.ac.uk> Message-ID: <8405C0D818720A45A8C69862358075EE03E3F2@DURMAIL3.mds.ad.dur.ac.uk> TASE 2009 - CALL FOR PARTICIPATION ********************************************************** * 3rd IEEE International Symposium on * Theoretical Aspects of Software Engineering * (TASE 2009) * 29-31 July 2009, Tianjin, China * http://www.dur.ac.uk/ieee.tase2009 * * Early Registration Deadline : 18 June 2009 * For more information email: IEEE.TASE2009@durham.ac.uk ***********************=********************************** TASE 2009 Invited Speakers ========================== Kim G. Larsen, Aalborg University, Denmark Zhong Shao, Yale University, USA Jin-Song Dong, National University of Singapore TASE 2009 Programme ==================== Day 1: 29 July 2009 ------------------- Invited Talk: Verification and Performance Analysis of Embedded Systems Kim G. Larsen (Aalborg University) Session 1 : Real-Time and Embedded Systems Improving Responsiveness of Hard Real-Time Embedded Systems Hugh Anderson (Wellington Institute of Technology) and Siau-Cheng KHOO (National University of Singapore) Environmental Simulation of Real-Time Systems with Nested Interrupts Guoqiang Li (Shanghai Jiao Tong University), Shoji Yuen (Nagoya University) and Masakazu Adachi (Toyota Central R&D Labs. INC.). Semantics for Communicating Actors with Interdependent Real-Time Deadlines Istv??n Knoll (Aalborg University), Anders P. Ravn (Aalborg University) and Arne Skou (Aalborg University). An Efficient Algorithm for Finding Empty Space for Reconfigurable Systems Zhenhua Duan (Xidian University) and Yan Xiao (Xidian University). Session 2 : Semantics State Visibility and Communication in Unifying Theories of Programming Andrew Butterfield (Trinity College Dublin), Pawel Gancarski (Trinity College Dublin) and Jim Woodcock (University of York). Semantics of Metamodels in UML Lijun Shan (National University of Defence Technology) and Hong Zhu (Oxford Brookes University). Refinement Algebra with Explicit Probabilism Tahiry Rabehaja (UNU/IIST) and Jeffrey Sanders (UNU/IIST). Session 3 : Model Checking Environment Abstraction with State Clustering and Parameter Truncating Hong Pan (Institute of Software, Chinese Academy of Sciences), Yi Lv (Institute of Software, Chinese Academy of Sciences) and Huimin Lin (Institute of Software, Chinese Academy of Sciences). Verification of Population Ring Protocols in PAT Yang Liu (National University of Singapore), Jun Pang (University of Luxembourg), Jun Sun (National University of Singapore) and Jianhua Zhao (Nanjing University). Bounded Model Checking of ACTL Formulae Wei Chen (Institute of Software, Chinese Academy of Sciences) and Wenhui Zhang (Institute of Software, Chinese Academy of Sciences). Day 2, 30 July 2009 ------------------- Invited Talk: Modular Development of Certified System Software Zhong Shao (Yale University) Session 4: Specification and Security Coarse Grained Retrenchment and the Mondex Denial of Service Attacks Richard Banach (Manchester University). Specifying and Enforcing Constraints of Artifact Life Cycles Xiangpeng Zhao (Peking University), Jianwen Su (University of California at Santa Barbara), Hongli Yang (Beijing University of Technology) and Zongyan Qiu (Peking University). Consistency Checking for LSC Specifications Hai-Feng Guo (University of Nebraska at Omaha), Wen Zheng (University of Nebraska at Omaha) and Mahadevan Subramaniam (University of Nebraska at Omaha). Integrating Specification and Programs for System Modeling and Verification Jun Sun (National University of Singapore), Yang Liu (National University of Singapore), Jin Song Dong (National University of Singapore) and Chunqing Chen (National University of Singapore). Session 5 : Software Testing I A Framework and Language Support for Automatic Dynamic Testing of Workflow Management Systems Gwan-Hwan Hwang (National Taiwan Normal University), Che-Sheng Lin (National Taiwan Normal University), Li-Te Tsao (National Taiwan Normal University), Kuei-Huan Chen (National Taiwan Normal University) and Yan-You Li (National Taiwan Normal University). Fault-based Test Case Generation for Component Connectors Bernhard Aichernig (Graz University of Technology), Farhad Arbab (CWI), Lacramioara Astefanoaei (CWI), Frank de Boer (CWI), Meng Sun (CWI) and Jan Rutten (CWI). Test Data Generation for Derived Types in C Program Zheng Wang (East China Normal University), Xiao Yu (East China Normal University), Tao Sun (East China Normal University), Geguang Pu (East China Normal University) and Zuohua Ding (Zhejiang Sci-Tech University). Session 6 : Software Models Program Repair as Sound Optimization of Broken Programs Bernd Fischer (University of Southampton), Ando Saabas (Tallinn University of Technology) and Tarmo Uustalu (Tallinn University of Technology). Modeling Web Applications and Generating Tests: A Combination and Interactions-guided Approach Bo Song (Shanghai University) and Huaikou Miao (Shanghai University). Merging of Use Case Models: Semantic Foundations Stephen Barrett (Concordia University), Daniel Sinnig (Concordia University), Patrice Chalin (Concordia University) and Greg Butler (Concordia University). Day 3, 31 July 2009 ------------------- Invited Tutorial: Towards Expressive Specification and Efficient Model Checking Jin Song Dong (National University of Singapore) Session 7 : Verification Verifying Semistructured Data Normalization using SWRL Yuan Fang Li (University of Queensland), Jing Sun (University of Auckland), Gillian Dobbie (University of Auckland), Scott Uk-Jin Lee (University of Auckland) and Hai H. Wang (Aston University). Verifying Self-stabilizing Population Protocols with Coq Yuxin Deng (Shanghai Jiao Tong University) and Jean-fran?ois Monin (Universit?? de Grenoble 1). The Logical Approach to Low-level Stack Reasoning Xinyu Jiang (University of Science and Technology of China), Yu Guo (University of Science and Technology of China) and Yiyun Chen (University of Science and Technology of China). Constructing Program Invariants via Solving QBF Shikun Chen (National University of Defence Technology), Zhoujun Li (Beihang University) and Mengjun Li (National University of Defence Technology). Session 8 : Concurrency Using Architectural Constraints for Deadlock-Freedom of Component Systems with Multiway Cooperation Moritz Martens (University of Mannheim) and Mila Majster-Cederbaum (University of Mannheim). Formal Reasoning about Concurrent Assembly Code with Reentrant Locks Ming Fu (University of Science and Technology of China), Yu Zhang (University of Science and Technology of China) and Yong Li (University of Science and Technology of China). Algorithms for Computing Weak Bisimulation Equivalence Weisong Li (Institute of Software, Chinese Academy of Sciences). Session 9 : Software Testing II Interpreting a Successful Testing Process: Risk and Actual Coverage Marielle Stoelinga (University of Twente) and Mark Timmer (University of Twente). Automated Test Case Generation based on Coverage Analysis Tim A. Majchrzak (University of Muenster) and Herbert Kuchen (University of Muenster). Exploring Topological Structure of Boolean Expressions for Test Data Selection Lian Yu (Peking University), Wei Zhao (IBM China Research Lab), Xiangdong Fan (Peking University) and Jun Zhu (IBM China Research Lab). On Testing 1-Safe Petri Nets Guy-Vincent Jourdan (University of Ottawa) and Gregor von Bochmann (University of Ottawa). The programme also include two poster sessions, comprising of 23 selected poster presentations. This list of posters can be found at http://www.dur.ac.uk/ieee.tase2009/ -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090604/2cf37a05/attachment-0001.html From jgoerzen at complete.org Thu Jun 4 13:52:02 2009 From: jgoerzen at complete.org (John Goerzen) Date: Thu Jun 4 13:35:57 2009 Subject: [Haskell-cafe] Static link to packages on Hackage? In-Reply-To: References: <4A27CA24.8020809@complete.org> Message-ID: <4A2809C2.6010104@complete.org> Thomas ten Cate wrote: > http://hackage.haskell.org/packages/archive/HSH/latest/doc/html/HSH.html > does take me to a page that says > "HSH-2.0.0: Library to mix shell scripting with Haskell programs" > in the blue bar at the top. > > Maybe some kind of cache? Did you try flushing your browser cache and > refreshing? Am I missing something? Weird. I just now hit reload, and it came up to the correct version. I wonder if perhaps it didn't get updated at the same time the docs did? > > Thomas > > On Thu, Jun 4, 2009 at 15:20, John Goerzen wrote: >> Hi, >> >> I'd like to be able to put a static link to the Haddock docs for the >> current version of various packages on my homepage. Right now, I can't >> find any such URL; they all look like: >> >> http://hackage.haskell.org/packages/archive/HSH/2.0.0/doc/html/HSH.html >> >> I'd like if there could be something like: >> >> http://hackage.haskell.org/packages/archive/HSH/latest/doc/html/HSH.html >> >> Incidentally, you can click on this "latest" URL but it doesn't go to >> the correct version. >> >> I can't just link to the package page either, because sometimes it won't >> have docs (such as shortly after I've uploaded a new version). >> >> Ideas? >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > From geoffrey.marchant at gmail.com Thu Jun 4 14:21:05 2009 From: geoffrey.marchant at gmail.com (Geoffrey Marchant) Date: Thu Jun 4 14:04:59 2009 Subject: [Haskell-cafe] A small puzzle: inTwain as function of foldr In-Reply-To: <4A27D8A6.1090605@van.steenbergen.nl> References: <4A27D8A6.1090605@van.steenbergen.nl> Message-ID: <79e6290e0906041121h5d4cf590k9107c9679b5be1ff@mail.gmail.com> The linked paper appears to show the right style. This appears to satisfy the conditions, however: inTwain as = let (x,y,_) = foldr (\a (r,s,t) -> case (t) of {b:(b':bs) -> (r,a:s,bs); _ -> (a:r,s,t)}) ([],[],as) as in (x,y) In the case of a list of odd length, the first half is given the extra element. On Thu, Jun 4, 2009 at 8:22 AM, Martijn van Steenbergen < martijn@van.steenbergen.nl> wrote: > Bonjour caf?, > > A small puzzle: > > Consider the function inTwain that splits a list of even length evenly into > two sublists: > > > inTwain "Hello world!" > ("Hello ","world!") > > Is it possible to implement inTwain such that the recursion is done by one > of the standard list folds? > > Is there a general way to tell if a problem can be expressed as a fold? > > Thank you, > > Martijn. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090604/ced69a63/attachment.html From voidex at yandex.ru Thu Jun 4 14:21:15 2009 From: voidex at yandex.ru (VoidEx) Date: Thu Jun 4 14:06:22 2009 Subject: [Haskell-cafe] Nested Lists Message-ID: <006a01c9e541$3f7077a0$be5166e0$@ru> You can also try this: bunch n f = takeWhile (not . null) . unfoldr (Just . (f *** id) . splitAt n) > (bunch 8 . bunch 4 . bunch 2) id [1..16] Any way, it's not possible to take list [8, 4, 2], because it's length need to be known at compile time. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090604/0d775b88/attachment.html From felipe.lessa at gmail.com Thu Jun 4 15:15:43 2009 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Thu Jun 4 14:59:42 2009 Subject: [Haskell-cafe] RE: Nested Lists In-Reply-To: <3CDFB8AFEA98E34CB599475AB11589C82C3DBE@EX2.ad.dcs.gla.ac.uk> References: <3CDFB8AFEA98E34CB599475AB11589C82C3DB6@EX2.ad.dcs.gla.ac.uk> <3CDFB8AFEA98E34CB599475AB11589C82C3DBD@EX2.ad.dcs.gla.ac.uk> <3CDFB8AFEA98E34CB599475AB11589C82C3DBE@EX2.ad.dcs.gla.ac.uk> Message-ID: <20090604191543.GA25648@kira.casa> On Thu, Jun 04, 2009 at 05:09:29PM +0100, Paul Keir wrote: > Thanks. I don't know Type Families, but take the point that > the input can be parameterised with something something other > than a list. i.e. (8 :+: 4 :+: 2 :+: ()) presumably has the > same type as (4 :+: 2 :+: ()). In fact, no. (4 :+: 2 :+: ()) :: Bunch (Bunch ()) (8 :+: 4 :+: 2 :+: ()) :: Bunch (Bunch (Bunch ())) Maybe you didn't understand something? Perhaps you should try reading the HaskellWiki[1] page on type families. [1] http://www.haskell.org/haskellwiki/GHC/Type_families HTH, -- Felipe. From sfvisser at cs.uu.nl Thu Jun 4 15:41:49 2009 From: sfvisser at cs.uu.nl (Sebastiaan Visser) Date: Thu Jun 4 15:25:49 2009 Subject: [Haskell-cafe] A small puzzle: inTwain as function of foldr In-Reply-To: <16442B752A06A74AB4D9F9A5FF076E4B01ABABEC@ELON17P32001A.csfb.cs-group.com> References: <4A27D8A6.1090605@van.steenbergen.nl> <16442B752A06A74AB4D9F9A5FF076E4B01ABABEC@ELON17P32001A.csfb.cs-group.com> Message-ID: On Jun 4, 2009, at 4:32 PM, Sittampalam, Ganesh wrote: > Martijn van Steenbergen wrote: > >> Consider the function inTwain that splits a list of even length >> evenly into two sublists: >> >>> inTwain "Hello world!" >> ("Hello ","world!") >> >> Is it possible to implement inTwain such that the recursion is done >> by one of the standard list folds? > > Does this help? http://www.brics.dk/RS/02/12/BRICS-RS-02-12.pdf > > Ganesh And maybe this helps: http://www.springerlink.com/content/h1547h551422462u/ -- Sebastiaan Visser From emertens at gmail.com Thu Jun 4 16:17:42 2009 From: emertens at gmail.com (Eric Mertens) Date: Thu Jun 4 16:01:35 2009 Subject: [Haskell-cafe] Umlauts in command line arguments In-Reply-To: References: Message-ID: <449c8cfc0906041317y3932860chdc620366f8b1fcfd@mail.gmail.com> Hello, On Sun, May 31, 2009 at 5:24 PM, G??nther Schmidt wrote: > When a command line argument contains an umlaut that argument gets garbled. > > I'm using ghc 6.10.2 on Win XP. Are there any known solutions for this > problem? Your question has inspired me to add a System.Environment.UTF8 module to utf8-string 0.3.5 This module behaves like the System.IO.UTF8 wrapper. -- Eric Mertens From bartek at sudety.it Thu Jun 4 19:31:26 2009 From: bartek at sudety.it (Bartosz =?iso-8859-1?q?W=F3jcik?=) Date: Thu Jun 4 17:15:45 2009 Subject: [Haskell-cafe] Fast code question Message-ID: <200906050031.26336.bartek@sudety.it> Hi Folks, I had to transform Packed Decimal file into csv format (does anybody here know what this Mainframe format is?). Because of the file size I could not do this on mainframe directly. So I've created simply program using ByteString. Generally I'm happy with my solution: pgm processes arroud 2MB/s on my pc, so my 3GB file was transformed in reasonable 30 min time. My question is: how to do this faster? {code} module Main where import qualified Data.ByteString.Lazy as B main = B.getContents >>= myPrint . myConcat . B.unpack myConcat = myConcat' 0 myConcat' :: (Integral a) => Integer -> [a] -> [Integer] myConcat' _ [] = [] myConcat' acc (x:xs) = case x `mod` 16 of 12 -> (10*acc + (restOf . fromIntegral) x) : myConcat' 0 xs 13 -> ((-10)*acc + (restOf . fromIntegral) x) : myConcat' 0 xs 15 -> (10*acc + (restOf . fromIntegral) x) : myConcat' 0 xs 10 -> fail $ show acc 11 -> fail $ show acc 14 -> fail $ show acc v -> myConcat' (100*acc + (numberOf . fromIntegral) x) xs where restOf n = (n - 12) `div` 16 numberOf n = n - 6 * (n `div` 16) myPrint [] = return () myPrint xs = mapM_ myShow (take 14 xs) >> putStrLn "" >> myPrint (drop 14 xs) myShow x = (putStr . show) x >> putStr ";" {code} I knew that csv output had to be 14 fields per line. Best, Bartek From michael at snoyman.com Thu Jun 4 17:38:53 2009 From: michael at snoyman.com (Michael Snoyman) Date: Thu Jun 4 17:22:48 2009 Subject: [Haskell-cafe] Fast code question In-Reply-To: <200906050031.26336.bartek@sudety.it> References: <200906050031.26336.bartek@sudety.it> Message-ID: <29bf512f0906041438q49f89667v1bdcb3eba653cc04@mail.gmail.com> I *do* know what Packed Decimal is; at my previous job, I actually had a whole Haskell library for parsing them. The only immediate suggestion that pops to mind is to use Int instead of Integer (Int uses regular 32- or 64-bit integers, Integer uses arbitrary precision integers). If you send me a sample Packed Decimal file, I can test out your code and get a better feel for it that way. Good luck with those mainframes, they can be beasts sometimes. Have you had to parse EBCDIC yet? *That* was fun, manually copying all those character codes from some IBM web page... ;) Michael On Fri, Jun 5, 2009 at 2:31 AM, Bartosz W?jcik wrote: > Hi Folks, > > I had to transform Packed Decimal file into csv format (does anybody here > know > what this Mainframe format is?). Because of the file size I could not do > this on mainframe directly. So I've created simply program using > ByteString. > Generally I'm happy with my solution: pgm processes arroud 2MB/s on my pc, > so > my 3GB file was transformed in reasonable 30 min time. > > My question is: how to do this faster? > > {code} > module Main > where > > import qualified Data.ByteString.Lazy as B > > main = B.getContents >>= myPrint . myConcat . B.unpack > > myConcat = myConcat' 0 > > myConcat' :: (Integral a) => Integer -> [a] -> [Integer] > myConcat' _ [] = [] > myConcat' acc (x:xs) = case x `mod` 16 of > 12 -> (10*acc + (restOf . fromIntegral) x) : myConcat' 0 xs > 13 -> ((-10)*acc + (restOf . fromIntegral) x) : myConcat' 0 > xs > 15 -> (10*acc + (restOf . fromIntegral) x) : myConcat' 0 xs > 10 -> fail $ show acc > 11 -> fail $ show acc > 14 -> fail $ show acc > v -> myConcat' (100*acc + (numberOf . fromIntegral) x) xs > where restOf n = (n - 12) `div` 16 > numberOf n = n - 6 * (n `div` 16) > > myPrint [] = return () > myPrint xs = mapM_ myShow (take 14 xs) >> putStrLn "" >> myPrint (drop 14 > xs) > > myShow x = (putStr . show) x >> putStr ";" > {code} > > I knew that csv output had to be 14 fields per line. > > Best, > Bartek > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090604/71bcf87d/attachment.html From gue.schmidt at web.de Thu Jun 4 17:53:06 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Thu Jun 4 17:37:16 2009 Subject: [Haskell-cafe] Non Empty List? Message-ID: Hi, I need to design a container data structure that by design cannot be empty and can hold n elements. Something like a non-empty list. I started with: data Container a = Single a | Many a [a] but the problem above is that the data structure would allow to construct a Many 5 [] :: Container Int. I can't figure out how to get this right. :( Please help. G?nther From miguelimo38 at yandex.ru Thu Jun 4 17:55:52 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Thu Jun 4 17:39:54 2009 Subject: [Haskell-cafe] Non Empty List? In-Reply-To: References: Message-ID: <84340663-0AC6-470E-B48D-A535082627B3@yandex.ru> data Container a = Container a [a] ? Or, maybe, you need something like zipper. On 5 Jun 2009, at 01:53, G??nther Schmidt wrote: > Hi, > > I need to design a container data structure that by design cannot be > empty and can hold n elements. Something like a non-empty list. > > > I started with: > > data Container a = Single a | Many a [a] > > but the problem above is that the data structure would allow to > construct a Many 5 [] :: Container Int. > > I can't figure out how to get this right. :( > > Please help. > > G?nther > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From dons at galois.com Thu Jun 4 18:21:21 2009 From: dons at galois.com (Don Stewart) Date: Thu Jun 4 18:06:56 2009 Subject: [Haskell-cafe] Fast code question In-Reply-To: <200906050031.26336.bartek@sudety.it> References: <200906050031.26336.bartek@sudety.it> Message-ID: <20090604222121.GC15472@whirlpool.galois.com> Can you use the bytestring csv parser (or convert it into a pretty printer?) bartek: > Hi Folks, > > I had to transform Packed Decimal file into csv format (does anybody here know > what this Mainframe format is?). Because of the file size I could not do > this on mainframe directly. So I've created simply program using ByteString. > Generally I'm happy with my solution: pgm processes arroud 2MB/s on my pc, so > my 3GB file was transformed in reasonable 30 min time. > > My question is: how to do this faster? > > {code} > module Main > where > > import qualified Data.ByteString.Lazy as B > > main = B.getContents >>= myPrint . myConcat . B.unpack ^^^^^^^^^^^^^^^^^^^^^ That looks bad. > > myConcat = myConcat' 0 > > myConcat' :: (Integral a) => Integer -> [a] -> [Integer] > myConcat' _ [] = [] > myConcat' acc (x:xs) = case x `mod` 16 of > 12 -> (10*acc + (restOf . fromIntegral) x) : myConcat' 0 xs > 13 -> ((-10)*acc + (restOf . fromIntegral) x) : myConcat' 0 xs > 15 -> (10*acc + (restOf . fromIntegral) x) : myConcat' 0 xs > 10 -> fail $ show acc > 11 -> fail $ show acc > 14 -> fail $ show acc > v -> myConcat' (100*acc + (numberOf . fromIntegral) x) xs > where restOf n = (n - 12) `div` 16 > numberOf n = n - 6 * (n `div` 16) > > myPrint [] = return () > myPrint xs = mapM_ myShow (take 14 xs) >> putStrLn "" >> myPrint (drop 14 xs) > > myShow x = (putStr . show) x >> putStr ";" > {code} > > I knew that csv output had to be 14 fields per line. > > Best, > Bartek > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From jake.mcarthur at gmail.com Thu Jun 4 18:53:42 2009 From: jake.mcarthur at gmail.com (Jake McArthur) Date: Thu Jun 4 18:37:29 2009 Subject: [Haskell-cafe] Non Empty List? In-Reply-To: References: Message-ID: <4A285076.8000905@gmail.com> G??nther Schmidt wrote: > data Container a = Single a | Many a [a] > > but the problem above is that the data structure would allow to > construct a Many 5 [] :: Container Int. I think you meant to do either data Container a = Single a | Many a (Container a) or data Container a = Container a [a] - Jake From tom at lokhorst.eu Thu Jun 4 19:21:55 2009 From: tom at lokhorst.eu (Tom Lokhorst) Date: Thu Jun 4 19:06:11 2009 Subject: [Haskell-cafe] Non Empty List? In-Reply-To: References: Message-ID: <317ca7670906041621s5887adcdx9d390641dd7143c3@mail.gmail.com> Are you looking for something like Streams [1]? They're infinite sequences, defined like this: data Stream a = Cons a (Stream a) They can obviously never be empty (unless you see bottom (undefined) as empty). - Tom [1] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Stream On Thu, Jun 4, 2009 at 11:53 PM, G??nther Schmidt wrote: > Hi, > > I need to design a container data structure that by design cannot be empty > and can hold n elements. Something like a non-empty list. > > > I started with: > > data Container a = Single a | Many a [a] > > but the problem above is that the data structure would allow to construct a > Many 5 [] :: Container Int. > > I can't figure out how to get this right. :( > > Please help. > > G?nther > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From gue.schmidt at web.de Thu Jun 4 19:39:12 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Thu Jun 4 19:23:19 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: <4A285076.8000905@gmail.com> References: <4A285076.8000905@gmail.com> Message-ID: Hi Jake, Jake McArthur schrieb: > G??nther Schmidt wrote: >> data Container a = Single a | Many a [a] >> but the problem above is that the data structure would allow to >> construct a Many 5 [] :: Container Int. > > I think you meant to do either > > data Container a = Single a | Many a (Container a) nope, I pretty much meant what I wrote above, the solution here would mean deeply nested containers, since it's a recursive data structure. I need a data structure as in my example without the [] being possible to be empty. It's quite possible that in order to achieve this I would need to split this in 2 separate data declarations. The idea behind this is that an "a" can "pocket" siblings, but only one level deep and that an "a's" list of "pocketed/swallowed" siblings must not be empty, because otherwise it would automatically be an "Single a". Sorry, I really don't know how to put this better. G?nther > > or > > data Container a = Container a [a] > > - Jake From gue.schmidt at web.de Thu Jun 4 19:40:47 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Thu Jun 4 19:28:55 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: <317ca7670906041621s5887adcdx9d390641dd7143c3@mail.gmail.com> References: <317ca7670906041621s5887adcdx9d390641dd7143c3@mail.gmail.com> Message-ID: Hi Tom, thanks for replying, no, I'm not looking for streams. I hope I made myself a bit more clear in my response to Jake. G?nther Tom Lokhorst schrieb: > Are you looking for something like Streams [1]? > > They're infinite sequences, defined like this: > > data Stream a = Cons a (Stream a) > > They can obviously never be empty (unless you see bottom (undefined) as empty). > > - Tom > > [1] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Stream > > On Thu, Jun 4, 2009 at 11:53 PM, G??nther Schmidt wrote: >> Hi, >> >> I need to design a container data structure that by design cannot be empty >> and can hold n elements. Something like a non-empty list. >> >> >> I started with: >> >> data Container a = Single a | Many a [a] >> >> but the problem above is that the data structure would allow to construct a >> Many 5 [] :: Container Int. >> >> I can't figure out how to get this right. :( >> >> Please help. >> >> G?nther >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> From westondan at imageworks.com Thu Jun 4 19:45:50 2009 From: westondan at imageworks.com (Dan Weston) Date: Thu Jun 4 19:29:56 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: References: <4A285076.8000905@gmail.com> Message-ID: <4A285CAE.9040209@imageworks.com> Unless I'm missing something in your description, why not data Container a = Single a | Many a a [a] Dan G??nther Schmidt wrote: > Hi Jake, > > > Jake McArthur schrieb: >> G??nther Schmidt wrote: >>> data Container a = Single a | Many a [a] >>> but the problem above is that the data structure would allow to >>> construct a Many 5 [] :: Container Int. >> I think you meant to do either >> >> data Container a = Single a | Many a (Container a) > > > > nope, I pretty much meant what I wrote above, the solution here would > mean deeply nested containers, since it's a recursive data structure. > > I need a data structure as in my example without the [] being possible > to be empty. > > It's quite possible that in order to achieve this I would need to split > this in 2 separate data declarations. > > The idea behind this is that an "a" can "pocket" siblings, but only one > level deep and that an "a's" list of "pocketed/swallowed" siblings must > not be empty, because otherwise it would automatically be an "Single a". > > Sorry, I really don't know how to put this better. > > G?nther > >> or >> >> data Container a = Container a [a] >> >> - Jake > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From gue.schmidt at web.de Thu Jun 4 19:54:06 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Thu Jun 4 19:38:11 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: <4A285CAE.9040209@imageworks.com> References: <4A285076.8000905@gmail.com> <4A285CAE.9040209@imageworks.com> Message-ID: Dan Weston schrieb: > Unless I'm missing something in your description, why not > > data Container a = Single a | Many a a [a] > Hi Dan, the above solution would still allow to construct, for instance, Many 5 42 [] :: Container Int The reason why I'm trying to find the design for a data structure in which this would not even be possible is to be able to avoid writing additional "bookkeeping" code into the functions that operate on the structure, ie. the lookups, inserts, delete etc. G?nther From rendel at cs.au.dk Thu Jun 4 19:56:16 2009 From: rendel at cs.au.dk (Tillmann Rendel) Date: Thu Jun 4 19:40:10 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: References: <4A285076.8000905@gmail.com> Message-ID: <4A285F20.9070406@cs.au.dk> Hi G?nther, G??nther Schmidt wrote: >>> data Container a = Single a | Many a [a] but the problem above > > I need a data structure as in my example without the [] being possible > to be empty. So lets write a variant of list which cannot be empty. A usual list is empty, or a head and a tail: data List a = Empty | HeadAndTail a (List a) Now, our kind of list should be just one element, or a head and a tail: data NonEmptyList a = JustOne a | HeadAndNonEmptyTail a (NonEmptyList a) So we can replace [] by NonEmptyList in your definition to get what you want: data Container a = Single a | Many a (NonEmptyList a) However, since Container and NonEmptyList are isomorphic, we can use one instead of the other: data Container a = Single a | Many a (Container a) Whether this is a good idea depends on the purpose of the types, but I guess it is. Tillmann From tonymorris at gmail.com Thu Jun 4 19:57:26 2009 From: tonymorris at gmail.com (Tony Morris) Date: Thu Jun 4 19:41:17 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: References: <4A285076.8000905@gmail.com> <4A285CAE.9040209@imageworks.com> Message-ID: <4A285F66.6030401@gmail.com> I note that you didn't address the suggestion of a zipper. G??nther Schmidt wrote: > Dan Weston schrieb: >> Unless I'm missing something in your description, why not >> >> data Container a = Single a | Many a a [a] >> > > Hi Dan, > > the above solution would still allow to construct, for instance, > > Many 5 42 [] :: Container Int > > The reason why I'm trying to find the design for a data structure in > which this would not even be possible is to be able to avoid writing > additional "bookkeeping" code into the functions that operate on the > structure, ie. the lookups, inserts, delete etc. > > G?nther > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- Tony Morris http://tmorris.net/ From gue.schmidt at web.de Thu Jun 4 20:08:01 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Thu Jun 4 19:52:08 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: <4A285F66.6030401@gmail.com> References: <4A285076.8000905@gmail.com> <4A285CAE.9040209@imageworks.com> <4A285F66.6030401@gmail.com> Message-ID: Hi Tony, that's because I wasn't sure whether or not it would be applicable here. As with monads, continuations, delimited continuations and quite a number of other high level concepts I only understand them in part even though I realize at the same time that understanding them fully would yield enormous benefits. I am aware of the power of these concepts, but have not gained the intuition yet. As for the zipper: In some of the examples I've seen, the zipper is implemented "on top" of an underlying data structure, but not the data structure itself. In my app I was actually going to pull a zipper over it, once I had the underlying structure right. G?nther PS: please also see my reply to Tillman Tony Morris schrieb: > I note that you didn't address the suggestion of a zipper. > > > G??nther Schmidt wrote: >> Dan Weston schrieb: >>> Unless I'm missing something in your description, why not >>> >>> data Container a = Single a | Many a a [a] >>> >> Hi Dan, >> >> the above solution would still allow to construct, for instance, >> >> Many 5 42 [] :: Container Int >> >> The reason why I'm trying to find the design for a data structure in >> which this would not even be possible is to be able to avoid writing >> additional "bookkeeping" code into the functions that operate on the >> structure, ie. the lookups, inserts, delete etc. >> >> G?nther >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > From gue.schmidt at web.de Thu Jun 4 20:16:04 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Thu Jun 4 20:00:14 2009 Subject: [Haskell-cafe] Re: Non Empty List? - Apologies In-Reply-To: <4A285076.8000905@gmail.com> References: <4A285076.8000905@gmail.com> Message-ID: Hi Jake, apologies, Jake McArthur schrieb: > G??nther Schmidt wrote: >> data Container a = Single a | Many a [a] >> but the problem above is that the data structure would allow to >> construct a Many 5 [] :: Container Int. > > I think you meant to do either > > data Container a = Single a | Many a (Container a) you're right, the above solution is indeed exactly what I need. It took me until Tillmans later elaborate reply to realize. Sometimes I'm unable to see things even when they bite me in the face, ouch! G?nther > > or > > data Container a = Container a [a] > > - Jake From jeff at nokrev.com Thu Jun 4 20:17:05 2009 From: jeff at nokrev.com (Jeff Wheeler) Date: Thu Jun 4 20:01:12 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: References: <4A285076.8000905@gmail.com> <4A285CAE.9040209@imageworks.com> <4A285F66.6030401@gmail.com> Message-ID: <1244161025.4057.2.camel@ulysses> On Fri, 2009-06-05 at 02:08 +0200, G??nther Schmidt wrote: > As for the zipper: In some of the examples I've seen, the zipper is > implemented "on top" of an underlying data structure, but not the data > structure itself. > In my app I was actually going to pull a zipper over it, once I had the > underlying structure right. I have a package on Hackage that implements a zipper-ish non-empty list structure. PointedList [1] is a datatype composed of a list of items on the left, the current item, and a list of items on the right. Is that close to what you're looking for? [1] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/pointedlist From gue.schmidt at web.de Thu Jun 4 20:19:32 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Thu Jun 4 20:03:55 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: <4A285F20.9070406@cs.au.dk> References: <4A285076.8000905@gmail.com> <4A285F20.9070406@cs.au.dk> Message-ID: Hi Tillmann, thank you for the elaborate example. This is exactly what it took for me to realize that you and Jake have indeed given me the solution that I need. I had a very hard time getting my head around it, but to my defense I'm usually working on this stuff in the wee hours. :) G?nther Tillmann Rendel schrieb: > Hi G?nther, > > G??nther Schmidt wrote: >>>> data Container a = Single a | Many a [a] but the problem above >> >> I need a data structure as in my example without the [] being possible >> to be empty. > > So lets write a variant of list which cannot be empty. A usual list is > empty, or a head and a tail: > > data List a > = Empty > | HeadAndTail a (List a) > > Now, our kind of list should be just one element, or a head and a tail: > > data NonEmptyList a > = JustOne a > | HeadAndNonEmptyTail a (NonEmptyList a) > > So we can replace [] by NonEmptyList in your definition to get what you > want: > > data Container a > = Single a > | Many a (NonEmptyList a) > > However, since Container and NonEmptyList are isomorphic, we can use one > instead of the other: > > data Container a > = Single a > | Many a (Container a) > > Whether this is a good idea depends on the purpose of the types, but I > guess it is. > > Tillmann From gue.schmidt at web.de Thu Jun 4 20:25:08 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Thu Jun 4 20:09:17 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: <1244161025.4057.2.camel@ulysses> References: <4A285076.8000905@gmail.com> <4A285CAE.9040209@imageworks.com> <4A285F66.6030401@gmail.com> <1244161025.4057.2.camel@ulysses> Message-ID: Hi Jeff, it might actually be, I'll check it out after a good nights sleep. Apparently working on this in the wee hours only leads to self embarrassing requests for help. Actually when it comes to the "underlying" data structure, Jake and Tillmann have already found it for me, even though I failed to realize that in Jakes post and only "got it" after Tillmanns post. It's been a long night :) G?nther Jeff Wheeler schrieb: > On Fri, 2009-06-05 at 02:08 +0200, G??nther Schmidt wrote: > >> As for the zipper: In some of the examples I've seen, the zipper is >> implemented "on top" of an underlying data structure, but not the data >> structure itself. >> In my app I was actually going to pull a zipper over it, once I had the >> underlying structure right. > > I have a package on Hackage that implements a zipper-ish non-empty list > structure. PointedList [1] is a datatype composed of a list of items on > the left, the current item, and a list of items on the right. > > Is that close to what you're looking for? > > [1] > http://hackage.haskell.org/cgi-bin/hackage-scripts/package/pointedlist From ekmett at gmail.com Thu Jun 4 20:34:05 2009 From: ekmett at gmail.com (Edward Kmett) Date: Thu Jun 4 20:17:58 2009 Subject: [Haskell-cafe] Non Empty List? In-Reply-To: References: Message-ID: <7fb8f82f0906041734h53c71f5xb56285990ae21509@mail.gmail.com> G?nther, Miguel had the easiest suggestion to get right: Your goal is to avoid the redundant encoding of a list of one element, so why do you need to get rid of the Many a [] case when you can get rid of your Single a case! > module NE where > import Prelude hiding (foldr, foldl, foldl1, head, tail) > import Data.Foldable (Foldable, foldr, toList, foldl, foldl1) > import Data.Traversable (Traversable, traverse) > import Control.Applicative > data NE a = NE a [a] deriving (Eq,Ord,Show,Read) Now we can fmap over non-empty lists > instance Functor NE where > fmap f (NE a as) = NE (f a) (map f as) It is clear how to append to a non-empty list. > cons :: a -> NE a -> NE a > a `cons` NE b bs = NE a (b:bs) head is total. > head :: NE a -> a > head (NE a _) = a tail can return an empty list, so lets model that > tail :: NE a -> [a] > tail (NE _ as) = as We may not be able to construct a non-empty list from a list, if its empty so model that. > fromList :: [a] -> Maybe (NE a) > fromList (x:xs) = Just (NE x xs) > fromList [] = Nothing We can make our non-empty lists an instance of Foldable so you can use Data.Foldable's versions of foldl, foldr, etc. and nicely foldl1 has a very pretty total definition, so lets use it. > instance Foldable NE where > foldr f z (NE a as) = a `f` foldr f z as > foldl f z (NE a as) = foldl f (z `f` a) as > foldl1 f (NE a as) = foldl f a as We can traverse non-empty lists too. > instance Traversable NE where > traverse f (NE a as) = NE <$> f a <*> traverse f as And they clearly offer a monadic structure: > instance Monad NE where > return a = NE a [] > NE a as >>= f = NE b (bs ++ concatMap (toList . f) as) where > NE b bs = f a and you can proceed to add suitable instance declarations for it to be a Comonad if you are me, etc. Now a singleton list has one representation NE a [] A list with two elements can only be represented by NE a [b] And so on for NE a [b,c], NE 1 [2..], etc. You could also make the > data Container a = Single a | Many a (Container a) definition work that Jake McArthur provided. For the category theory inspired reader Jake's definition is equivalent to the Cofree comonad of the Maybe functor, which can encode a non-empty list. I leave that one as an exercise for the reader, but observe Single 1 Many 1 (Single 2) Many 1 (Many 2 (Single 3)) And the return for this particular monad is easy: instance Monad Container where return = Single In general Jake's non-empty list is a little nicer because it avoids a useless [] constructor at the end of the list. -Edward Kmett On Thu, Jun 4, 2009 at 5:53 PM, G??nther Schmidt wrote: > Hi, > > I need to design a container data structure that by design cannot be empty > and can hold n elements. Something like a non-empty list. > > > I started with: > > data Container a = Single a | Many a [a] > > but the problem above is that the data structure would allow to construct a > Many 5 [] :: Container Int. > > I can't figure out how to get this right. :( > > Please help. > > G?nther > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090604/54cd7ee4/attachment.html From duncan.coutts at worc.ox.ac.uk Thu Jun 4 20:16:46 2009 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Thu Jun 4 20:25:41 2009 Subject: [Haskell-cafe] GHCI & Curl under Windows In-Reply-To: References: <4A266C49.3080207@gmx.org> Message-ID: <1244161006.29805.498.camel@localhost> On Thu, 2009-06-04 at 12:57 +1000, John Lask wrote: > The issue you are experiencing is the result of ghci not using import > libraries to resolve external symbols. Just a bit of explanation for > reference, which will also help you understand the solution to your problem. [..] > The long and the short of it is --- much work still needs to be > done to ensure that building and maintaining packages on windows > platforms via cabal and ghc is painless - so far every > package I have used that relied on external libraries has required > some tweaking (and not just setting library paths). Thanks for the detailed writeup. We would of course like to have better support on Windows in cabal and ghc for packages that bind C libs. Perhaps you can file some tickets with concrete suggestions? http://hackage.haskell.org/trac/hackage/ http://hackage.haskell.org/trac/ghc/ Duncan From wren at freegeek.org Thu Jun 4 22:45:17 2009 From: wren at freegeek.org (wren ng thornton) Date: Thu Jun 4 22:29:19 2009 Subject: [Haskell-cafe] Functors and the Visitor Pattern In-Reply-To: <90889fe70906040055w2da66abdv58465566dfb8a611@mail.gmail.com> References: <23851113.post@talk.nabble.com> <4A277416.8040707@freegeek.org> <90889fe70906040055w2da66abdv58465566dfb8a611@mail.gmail.com> Message-ID: <4A2886BD.5070003@freegeek.org> Johan Tibell wrote: > wren ng thornton wrote: > > [2] For the recursive Visitor pattern I use most often, that is. For the > > non-recursive version it's usually fmap. This is the part where the pattern > > gets a bit shaky because there are actually many different patterns all > > called "Visitor". The main points of interest are whether it's recursive or > > not, and whether it applies the visitor to itself, to its children, or both. > > > > non-recursive + itself == ($) > > > > non-recursive + children == fmap (under open-recursion interpretation of > > the type, aka all nodes are elements) > > > > recursive + children == fmap (under closed-recursion interpretation, aka > > only fringe nodes are elements) > > > > recursive + both == cata (usually, though it depends how you aggregate) > > > > recursive + itself == This is actually a variant of the Iterator pattern > > > Could you be so kind to give an example for each? In OOP you mean? /* nonrecursive + self == application */ class A { T app(Visitor v) { return v.visit(this); } } class B { T app(Visitor v) { return v.visit(this); } } ... // An allomorphic function :: (A | B | ...) -> T class Visitor { T visit(A a) { ... } T visit(B b) { ... } ... } This particular version often isn't too helpful because it's just reflecting the method call, we could've just called visit directly instead of calling app. But there are times where it is useful, particularly when you want to have some visitors which are recursive and some which are not. In which case it doesn't matter which method you start with, but you do need both in order to reflect back on recursion. /* nonrecursive + children == fmap (with real parametricity) */ class F { Children as; F(Children as) { this.as = as; } F fmap(Visitor v) { Children bs = new Children(); for (A a : this.as) bs.add( v.visit(a) ); return new F(bs); } } ... interface Visitor { B visit(A a); } This is a rather Haskellish take on this version. In practice people often don't bother supporting parametricity (needed for making F a real functor). That is, usually they'll do destructive updates to F, only have endofunction visitors (so there's no change of types), or use side-effect only visitors (see below). /* recursive + children == fmap (side-effect only) */ abstract class Tree { abstract void rmap(Visitor v); } class Branch extends Tree { Children subtrees; void rmap(Visitor v) { for (Tree t : this.subtrees) v.visit(t); } } class Leaf extends Tree { void rmap(Visitor v) { // Just in case we're the root node. v.visit(this); // Or we could do nothing instead, // depending on desired semantics } } class Visitor { void visit(Branch t) { t.rmap(this); } // reflect to recurse void visit(Leaf t) { ... } // don't reflect or you'll hit _|_ } This highlights an additional axis of variation in the many different visitor patterns, whether the "result" is returned directly (as in the previous example), whether it is accumulated in the Visitor itself (requiring explicit lookup later), or whether it's done via side-effects on global state. The accumulator and side-effect versions are a bit more general since their "return type" isn't restricted by the classes being visited. /* recursive + self/both == a kind of Iterator/catamorphism */ abstract class Tree { abstract void observe(Visitor v); } class Branch extends Tree { Children subtrees; void observe(Visitor v) { v.visit(this); for (Tree t : this.subtrees) t.observe(v); } } class Leaf extends Tree { void observe(Visitor v) { v.visit(this); } } class Visitor { void visit(Branch t) { ... } void visit(Leaf t) { ... } } This is different from the recursive+children version because this version keeps all of the recursion code on the side of the visited classes, and it also meaningfully visits interior nodes. In the recursive+children version the visitor ignored branches (though it doesn't need to) and reflected back to initiate recursion, whereas this version will recurse no matter what the visitor does (barring exceptions, etc). This version is a push iterator which forces you to visit all nodes, rather than the more usual pull iterator where you need to call next() to get the next node. We can convert between the two varieties by using co-routines or threads or other control-flow tricks. If we reverse the order of the recursive observe and the visit(this) then we get something like a catamorphism. Whether it's actually a catamorphism depends on what the visitor does, or rather what knowledge about the shape of Branch and Leaf it makes use of. "Real" catamorphisms are fairly rare in OOP, though you often find things like using a visitor to add decoration to a tree (which is much like passing the initial algebra to cata) or maintaining some aggregation in the visitor. -- Live well, ~wren From johan.tibell at gmail.com Fri Jun 5 03:47:43 2009 From: johan.tibell at gmail.com (Johan Tibell) Date: Fri Jun 5 03:31:55 2009 Subject: [Haskell-cafe] Functors and the Visitor Pattern In-Reply-To: <4A2886BD.5070003@freegeek.org> References: <23851113.post@talk.nabble.com> <4A277416.8040707@freegeek.org> <90889fe70906040055w2da66abdv58465566dfb8a611@mail.gmail.com> <4A2886BD.5070003@freegeek.org> Message-ID: <90889fe70906050047x61640851p9c19f4031804862@mail.gmail.com> On Fri, Jun 5, 2009 at 4:45 AM, wren ng thornton wrote: > Johan Tibell wrote: >> >> Could you be so kind to give an example for each? >> > > In OOP you mean? > This cleared things up for me. Thanks! -- Johan -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090605/c6dcb01a/attachment.html From oleg at okmij.org Fri Jun 5 03:57:00 2009 From: oleg at okmij.org (oleg@okmij.org) Date: Fri Jun 5 03:42:04 2009 Subject: [Haskell-cafe] Generic polyvariadic printf in Haskell98 Message-ID: <20090605075700.56C32176F6@Adric.metnet.navy.mil> Evan Klitzke wrote: > I'm writing code with hslogger, and I'm finding myself frequently > writing things like this: > > infoM $ printf "%s saw %s with %s" (show x) (show y) (show z) Indeed writing these `show' is tedious. Fortunately, we can get rid of them, still remaining in Haskell98. The following file defines the polyvariadic generic printf: http://okmij.org/ftp/typed-formatting/GenPrintF.hs It is like polyvariadic show with the printf formatting string. It handles values of any type for which there is a Show instance. Two instances of the class SPrintF are all we ever need. Here are the tests: t1 = unR $ printf "Hi there" -- "Hi there" t2 = unR $ printf "Hi %s!" "there" -- "Hi there!" t3 = unR $ printf "The value of %s is %s" "x" 3 -- "The value of x is 3" t4 = unR $ printf "The value of %s is %s" "x" [5] -- "The value of x is [5]" The appearance of unR is only because of Haskell98 (with flexible instances, we can get rid of that). On the other hand, your code post-processes the result of formatting with infoM, so the newtype unwrapping should not matter at all. Still, the code is a bit unsatisfactory because of the appearances of "error" in pr_aux functions. The errors like passing too many or too few arguments to printf (as demanded by the format specification) are caught only at run-time. We can certainly do better. From bulat.ziganshin at gmail.com Fri Jun 5 04:03:57 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Fri Jun 5 03:52:31 2009 Subject: [Haskell-cafe] Umlauts in command line arguments In-Reply-To: <449c8cfc0906041317y3932860chdc620366f8b1fcfd@mail.gmail.com> References: <449c8cfc0906041317y3932860chdc620366f8b1fcfd@mail.gmail.com> Message-ID: <1051598548.20090605120357@gmail.com> Hello Eric, Friday, June 5, 2009, 12:17:42 AM, you wrote: >> I'm using ghc 6.10.2 on Win XP. Are there any known solutions for this >> problem? > Your question has inspired me to add a System.Environment.UTF8 module > to utf8-string 0.3.5 > This module behaves like the System.IO.UTF8 wrapper. it is useless on Windows, since it passes cmdline in ANSI code page rather than UTF-8. proper windows solution is using *W version of WIN API function to get UTF-16 string and then decode it -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From mle+hs at mega-nerd.com Fri Jun 5 04:29:11 2009 From: mle+hs at mega-nerd.com (Erik de Castro Lopo) Date: Fri Jun 5 04:13:19 2009 Subject: [Haskell-cafe] Generic polyvariadic printf in Haskell98 In-Reply-To: <20090605075700.56C32176F6@Adric.metnet.navy.mil> References: <20090605075700.56C32176F6@Adric.metnet.navy.mil> Message-ID: <20090605182911.24745e8d.mle+hs@mega-nerd.com> oleg@okmij.org wrote: > Still, the code is a bit unsatisfactory because of the appearances of > "error" in pr_aux functions. The errors like passing too many or too > few arguments to printf (as demanded by the format specification) are > caught only at run-time. We can certainly do better. I'd love to see it. Coming from Ocaml one of the things I miss is compile time checking of printf arguments. Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/ From ketil at malde.org Fri Jun 5 04:32:48 2009 From: ketil at malde.org (Ketil Malde) Date: Fri Jun 5 04:16:17 2009 Subject: [Haskell-cafe] Fast code question In-Reply-To: <200906050031.26336.bartek@sudety.it> ("Bartosz =?utf-8?Q?W?= =?utf-8?Q?=C3=B3jcik=22's?= message of "Fri\, 5 Jun 2009 00\:31\:26 +0100") References: <200906050031.26336.bartek@sudety.it> Message-ID: <87iqjbt70v.fsf@malde.org> Bartosz W?jcik writes: > myConcat' :: (Integral a) => Integer -> [a] -> [Integer] : > myConcat' acc (x:xs) = case x `mod` 16 of : > 10 -> fail $ show acc > 11 -> fail $ show acc > 14 -> fail $ show acc ^^^^^^^^^^^^^^^ Since you're in the list monad, this just returns []. Perhaps you mean error rather than fail? (And isn't it more useful to print x than acc?) > v -> myConcat' (100*acc + (numberOf . fromIntegral) x) xs > where restOf n = (n - 12) `div` 16 > numberOf n = n - 6 * (n `div` 16) -k -- If I haven't seen further, it is by standing in the footprints of giants From newhoggy at gmail.com Fri Jun 5 05:33:56 2009 From: newhoggy at gmail.com (John Ky) Date: Fri Jun 5 05:17:48 2009 Subject: [Haskell-cafe] Record initialise question Message-ID: Hi all, I have some sample code: > full = do > let myOrder = initOrder > { item = Just initItem > { itemId = "Something" > } > , operation = Just Buy > } > putStrLn $ show myOrder > return () This is just a test project, but in a real project, I would have a more elaborate structure. Notice initOrder and initItem. I actually need to know the type of field I am initialising or the name of the corresponding function that provides default values. Is there any kind of polymorphic magic that lets me do this instead? > full = do > let myOrder = init -- [1] > { item = Just init > { itemId = "Something" > } > , operation = Just Buy > } > putStrLn $ show myOrder > return () Where initOrder and initItem are both replaced with just 'init' and the compiler works out from the context (ie. the type of the field) what the types are supposed to be and therefore the actual init function to call? Thanks, -John [1] The second example is silly because there isn't actually any context at this point, but let's pretend there is. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090605/005c40c9/attachment.html From martijn at van.steenbergen.nl Fri Jun 5 05:54:00 2009 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Fri Jun 5 05:38:02 2009 Subject: [Haskell-cafe] Monad transformer responsibilities Message-ID: <4A28EB38.3050604@van.steenbergen.nl> Hello, Suppose I have two projects: 1) one that defines a monad transformer and an accompanying type class that captures my monad-specific operations and 2) one that uses the other project, combining the monad transformer with, say, Parsec. Now while writing my Parsec parser I want to use my monad transformer operations without using lift: I need an instance MyMonadT Parsec. Where should this instance go? I can think of three answers, all unsatisfactory: 1) For obvious reasons it shouldn't go in the Parsec package. 2) For pretty much the same reasons it shouldn't go in my monad transformer package, either. Also, it is undesirable to add a dependency on Parsec just for this instance, and the package should not have to know about the projects that are going to use it. 3) If I put it in the second project it is an orphan instance, which is undesirable for well-known reasons. What is the best solution? Thank you, Martijn. From ketil at malde.org Fri Jun 5 05:56:02 2009 From: ketil at malde.org (Ketil Malde) Date: Fri Jun 5 05:39:30 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: (=?utf-8?B?IkfDvMKfbnRoZXI=?= Schmidt"'s message of "Fri\, 05 Jun 2009 01\:39\:12 +0200") References: <4A285076.8000905@gmail.com> Message-ID: <87eitzt365.fsf@malde.org> G??nther Schmidt writes: > I need a data structure as in my example without the [] being possible > to be empty. Well, a list can by definition be empty, so this is clearly impossible. The best you can do is to hide the constructors and have "smart" constructor functions that guarantee not to construct your data structure with an empty list component. I'm puzzled why you need to use a list here though. > The idea behind this is that an "a" can "pocket" siblings, but only > one level deep and that an "a's" list of "pocketed/swallowed" siblings > must not be empty, because otherwise it would automatically be an > "Single a". >> data Container a = Container a [a] If you cannot use this directly, then perhaps you can use it as a replacement for normal lists that cannot be non-empty? chead (Container x _) = x ctail (Container _ []) = error "Can't take tail of singleton list" ctail (Container _ (x:xs) = x:xs -k -- If I haven't seen further, it is by standing in the footprints of giants From martijn at van.steenbergen.nl Fri Jun 5 06:05:38 2009 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Fri Jun 5 05:49:34 2009 Subject: [Haskell-cafe] Record initialise question In-Reply-To: References: Message-ID: <4A28EDF2.6000608@van.steenbergen.nl> Hi John, John Ky wrote: > > full = do > > let myOrder = init -- [1] > > { item = Just init > > { itemId = "Something" > > } > > , operation = Just Buy > > } > > putStrLn $ show myOrder > > return () > > Where initOrder and initItem are both replaced with just 'init' and the > compiler works out from the context (ie. the type of the field) what the > types are supposed to be and therefore the actual init function to call? Sure! This is one of the simplest forms of overloading. Here's a small example: > data Circle = Circle { center :: (Float, Float), radius :: Float } > data WrapCircle = WrapCircle { circle :: Circle } > > class Ini a where > ini :: a > > instance Ini Circle where > ini = Circle { center = (0, 0), radius = 1 } > > exampleCircle :: WrapCircle > exampleCircle = WrapCircle { circle = ini { radius = 2 } } Hope this helps! Martijn. From ryani.spam at gmail.com Fri Jun 5 06:29:50 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Fri Jun 5 06:13:43 2009 Subject: [Haskell-cafe] Monad transformer responsibilities In-Reply-To: <4A28EB38.3050604@van.steenbergen.nl> References: <4A28EB38.3050604@van.steenbergen.nl> Message-ID: <2f9b2d30906050329o41239b5ahd653964f7d4bd02d@mail.gmail.com> >From what I understand, the current best practices are to build your package dependencies like so: Parsec MyMonadT MyMonadT_Parsec -- orphan instances go here ProjectPackage This does mean splitting up your project into three packages, but decouples the orphan instance into its own package where it can do the least damage :) At the very least it should go into its own module which can be imported only in the places that need it, similar to Control.Monad.Instances defining the orphan instance for Monad ((->) r). -- ryan On Fri, Jun 5, 2009 at 2:54 AM, Martijn van Steenbergen wrote: > Hello, > > Suppose I have two projects: 1) one that defines a monad transformer and an > accompanying type class that captures my monad-specific operations and 2) > one that uses the other project, combining the monad transformer with, say, > Parsec. > > Now while writing my Parsec parser I want to use my monad transformer > operations without using lift: I need an instance MyMonadT Parsec. Where > should this instance go? I can think of three answers, all unsatisfactory: > > 1) For obvious reasons it shouldn't go in the Parsec package. > > 2) For pretty much the same reasons it shouldn't go in my monad transformer > package, either. Also, it is undesirable to add a dependency on Parsec just > for this instance, and the package should not have to know about the > projects that are going to use it. > > 3) If I put it in the second project it is an orphan instance, which is > undesirable for well-known reasons. > > What is the best solution? > > Thank you, > > Martijn. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From deduktionstheorem at web.de Fri Jun 5 06:40:02 2009 From: deduktionstheorem at web.de (Stephan Friedrichs) Date: Fri Jun 5 06:23:59 2009 Subject: [Haskell-cafe] Monad transformer responsibilities In-Reply-To: <4A28EB38.3050604@van.steenbergen.nl> References: <4A28EB38.3050604@van.steenbergen.nl> Message-ID: <4A28F602.70103@web.de> Hi, it's alomost the same problem when you're writing a library with optional quickcheck test cases: Where to put the Arbitrary instances? - You can't put them into quickcheck - You don't want to put them in the library (because of the quickcheck dependency) - So you have to declare them near the test cases and they're orphan instances The entire project doesn't issue a single warning when compiling with -Wall *except* two orphan instances when building the test cases... //Stephan -- Fr?her hie? es ja: Ich denke, also bin ich. Heute wei? man: Es geht auch so. - Dieter Nuhr From martijn at van.steenbergen.nl Fri Jun 5 07:20:03 2009 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Fri Jun 5 07:04:01 2009 Subject: [Haskell-cafe] A small puzzle: inTwain as function of foldr In-Reply-To: <16442B752A06A74AB4D9F9A5FF076E4B01ABABEC@ELON17P32001A.csfb.cs-group.com> References: <4A27D8A6.1090605@van.steenbergen.nl> <16442B752A06A74AB4D9F9A5FF076E4B01ABABEC@ELON17P32001A.csfb.cs-group.com> Message-ID: <4A28FF63.6060302@van.steenbergen.nl> Sittampalam, Ganesh wrote: > Does this help? http://www.brics.dk/RS/02/12/BRICS-RS-02-12.pdf I think so! Thanks, got something more to read now. :-) Martijn. From martijn at van.steenbergen.nl Fri Jun 5 07:21:22 2009 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Fri Jun 5 07:05:19 2009 Subject: [Haskell-cafe] A small puzzle: inTwain as function of foldr In-Reply-To: References: <4A27D8A6.1090605@van.steenbergen.nl> Message-ID: <4A28FFB2.2000503@van.steenbergen.nl> Thomas ten Cate wrote: > Possible, yes. > > Efficient, not really. > >> inTwain = foldr (\x (ls, rs) -> if length ls == length rs then (x:ls, rs) else (x:(init ls), (last ls):rs)) ([], []) But this uses length and init and last all of which are recursive functions. I consider that cheating: only foldr may do the recursion. Martijn. From claus.reinke at talk21.com Fri Jun 5 07:25:52 2009 From: claus.reinke at talk21.com (Claus Reinke) Date: Fri Jun 5 07:09:51 2009 Subject: [Haskell-cafe] Monad transformer responsibilities References: <4A28EB38.3050604@van.steenbergen.nl> <2f9b2d30906050329o41239b5ahd653964f7d4bd02d@mail.gmail.com> Message-ID: > >From what I understand, the current best practices are to build your > package dependencies like so: > > Parsec MyMonadT > MyMonadT_Parsec -- orphan instances go here > ProjectPackage > > This does mean splitting up your project into three packages, but > decouples the orphan instance into its own package where it can do the > least damage :) Lets assume the above are modules rather than packages (same difference, but fewer indirections in the explanation to follow): if ProjectPackage imports MyMonadT_Parsec and is itself meant to be imported by other modules, then that decoupling breaks down (unless MyMonadT is a private class, in which case there is only one provider of instances, who can try to manage the situation). > At the very least it should go into its own module which can be > imported only in the places that need it, similar to > Control.Monad.Instances defining the orphan instance for Monad ((->) > r). Orphan instances aren't themselves bad, I think. But since current technology doesn't allow for import/export control, they always indicate a problem, hence the warning. When possible, the problem should be avoided, by making either the class or the type private (if neccessary by wrapping a common type in a newtype). That doesn't mean that the problem can always be avoided, just that there is something that needs attention. Back to that import hierarchy: > Parsec MyMonadT > MyMonadT_Parsec -- orphan instances go here > ProjectPackage If ProjectPackage is meant to be imported, there are at least two ways to proceed. Version A is to split the dependent modules, so that each of them can be used with or without the import. Parsec MyMonadT MyMonadT_Parsec -- orphan instances go here ProjectPackageWith -- imports, and implicitly exports, MyMonadT_Parsec ProjectPackageWithout -- no import, no implicit export So clients can still use ProjectPackageWithout if they get the instances by another route. This only works for convenience instances where the instances are nice to provide for clients, but not needed in ProjectPackage itself - in essence: ProjectPackageWith(module ProjectPackageWithout) where import MyMonadT_Parsec import ProjectPackageWithout If ProjectPackage actually depends on the existence of those orphan instances, plan B is to delay instance resolution, from library to clients, so instead of importing the orphan instances module ProjectPackage where import MyMonadT_Parsec f .. = .. orphan instances are available, use them .. (which leads to the dreaded implicit export), you'd just assert their existence: module ProjectPackage where f :: .. Orphan x => .. ; f .. = .. use orphan instances .. so the client module would have to import both ProjectPackage and MyMonadT_Parsec if it wants to call 'f', or find another way to provide those instance. Of course, the same concerns apply to the client modules, so you end up delaying all instance resolution until the last possible moment (at which point all the orphans need to be imported). If there is a main module somewhere (something that isn't itself imported), that is the place where importing the orphan instances won't cause any trouble (other than that all the users of such instances better have compatible ideas about what kind of instance they want, because they all get the same ones). If there is no main module (you're writing a library meant to be imported), you better delay the import of any orphans or provide both libraryWith and libraryWithout. It isn't pretty. Claus From martijn at van.steenbergen.nl Fri Jun 5 07:37:04 2009 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Fri Jun 5 07:21:04 2009 Subject: [Haskell-cafe] A small puzzle: inTwain as function of foldr In-Reply-To: <79e6290e0906041121h5d4cf590k9107c9679b5be1ff@mail.gmail.com> References: <4A27D8A6.1090605@van.steenbergen.nl> <79e6290e0906041121h5d4cf590k9107c9679b5be1ff@mail.gmail.com> Message-ID: <4A290360.1080800@van.steenbergen.nl> Geoffrey Marchant wrote: > The linked paper appears to show the right style. > > This appears to satisfy the conditions, however: > > inTwain as = let (x,y,_) = foldr (\a (r,s,t) -> case (t) of {b:(b':bs) > -> (r,a:s,bs); _ -> (a:r,s,t)}) ([],[],as) as in (x,y) This one is very interesting. Thanks. :-) It took a while to see what is going on. I'm not too happy with the whole list as part of the initial state. That feels like cheating to me--although I obviously failed to specify this in my original question. Trying to understand morphisms: does that make this a paramorphism rather than a catamorphism? Martijn. From ketil at malde.org Fri Jun 5 07:38:24 2009 From: ketil at malde.org (Ketil Malde) Date: Fri Jun 5 07:21:54 2009 Subject: [Haskell-cafe] A small puzzle: inTwain as function of foldr In-Reply-To: <4A28FFB2.2000503@van.steenbergen.nl> (Martijn van Steenbergen's message of "Fri\, 05 Jun 2009 13\:21\:22 +0200") References: <4A27D8A6.1090605@van.steenbergen.nl> <4A28FFB2.2000503@van.steenbergen.nl> Message-ID: <87y6s6syfj.fsf@malde.org> Martijn van Steenbergen writes: >>> inTwain = foldr (\x (ls, rs) -> if length ls == length rs then (x:ls, rs) else (x:(init ls), (last ls):rs)) ([], []) > But this uses length and init and last all of which are recursive > functions. I consider that cheating: only foldr may do the recursion. inTwain = foldr (\x (ls, rs) -> if foldr (const (+1)) 0 ls = ... ? :-) -k -- If I haven't seen further, it is by standing in the footprints of giants From ketil at malde.org Fri Jun 5 07:58:43 2009 From: ketil at malde.org (Ketil Malde) Date: Fri Jun 5 07:42:11 2009 Subject: [Haskell-cafe] A small puzzle: inTwain as function of foldr In-Reply-To: <4A290360.1080800@van.steenbergen.nl> (Martijn van Steenbergen's message of "Fri\, 05 Jun 2009 13\:37\:04 +0200") References: <4A27D8A6.1090605@van.steenbergen.nl> <79e6290e0906041121h5d4cf590k9107c9679b5be1ff@mail.gmail.com> <4A290360.1080800@van.steenbergen.nl> Message-ID: <874ouusxho.fsf@malde.org> Martijn van Steenbergen writes: >> inTwain as = let (x,y,_) = foldr (\a (r,s,t) -> case (t) of >> {b:(b':bs) -> (r,a:s,bs); _ -> (a:r,s,t)}) ([],[],as) as in (x,y) > This one is very interesting. Yes, neat. > I'm not too happy with the whole list as part of the initial > state. That feels like cheating to me--although I obviously failed to > specify this in my original question. Can you avoid it? If you only allow one traversal of the input (and I think the above might qualify as two, albeit simultaneous), how do you know when you're halfway through? I seem to remember one example case that regular languages can't solve is a^nb^n -- is this for the same (or a related) reason? -k -- If I haven't seen further, it is by standing in the footprints of giants From cetin.sert at gmail.com Fri Jun 5 08:09:25 2009 From: cetin.sert at gmail.com (Cetin Sert) Date: Fri Jun 5 07:53:38 2009 Subject: [Haskell-cafe] specialization in type classes Message-ID: <1ff5dedc0906050509w5c6134e0vf5d382b0c3a049d3@mail.gmail.com> module IOStream where import System.IO import System.IO.Unsafe class Out a where out :: a ? String instance Show a ? Out a where out = show instance Out String where {-# SPECIALISE out :: String ? String #-} out = id instance Out Char where {-# SPECIALISE out :: Char ? String #-} out = \x ? [x] infixl 0 <<, ? (?), (<<) :: Out a ? IO Handle ? a ? IO Handle (<<)= (?) h ? a = do s ? h hPutStr s $ out a return s cout, cin, cerr :: IO Handle cout = return stdout cin = return stdin cerr = return stderr endl :: String endl = "\n" --- cetin@unique:~/lab/c/linking/demo$ ghci -fglasgow-exts iostream.hs GHCi, version 6.10.2: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Ok, modules loaded: IOStream. Prelude IOStream> cout << 22 << False 22False{handle: } Prelude IOStream> cout << 22 << False << endl :1:0: Overlapping instances for Out String arising from a use of `<<' at :1:0-26 Matching instances: instance (Show a) => Out a -- Defined in IOStream instance Out String -- Defined in IOStream In the expression: cout << 22 << False << endl In the definition of `it': it = cout << 22 << False << endl o________________O how can I specialise a type class function? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090605/70192386/attachment.html From dave at zednenem.com Fri Jun 5 08:21:52 2009 From: dave at zednenem.com (David Menendez) Date: Fri Jun 5 08:05:48 2009 Subject: [Haskell-cafe] Monad transformer responsibilities In-Reply-To: References: <4A28EB38.3050604@van.steenbergen.nl> <2f9b2d30906050329o41239b5ahd653964f7d4bd02d@mail.gmail.com> Message-ID: <49a77b7a0906050521j5125164x17d396dfc2383a5d@mail.gmail.com> On Fri, Jun 5, 2009 at 7:25 AM, Claus Reinke wrote: > > If ProjectPackage actually depends on the existence of those orphan > instances, plan B is to delay instance resolution, from library to clients, > so instead of importing the orphan instances > > module ProjectPackage where import MyMonadT_Parsec > f .. = ?.. orphan instances are available, use them .. > > (which leads to the dreaded implicit export), you'd just assert their > existence: > > module ProjectPackage where f :: .. Orphan x => .. ; f .. = .. use orphan > instances .. That gets awkward if you're dealing with a concrete type. Consider, class C a where foo :: a -> a data T = T bar :: C T => T bar = foo T I was able to get GHCi to accept this with FlexibleContexts, but it obviously doesn't like it. *Main> :bro Main class C a where foo :: a -> a data T = T bar :: (C T) => T *Main> :t bar :1:0: No instance for (C T) arising from a use of `bar' at :1:0-2 Possible fix: add an instance declaration for (C T) In the expression: bar But at least it's possible. And the problems go away once the instance is in scope. -- Dave Menendez From miguelimo38 at yandex.ru Fri Jun 5 08:53:14 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Fri Jun 5 08:37:52 2009 Subject: [Haskell-cafe] Monad transformer responsibilities In-Reply-To: <4A28EB38.3050604@van.steenbergen.nl> References: <4A28EB38.3050604@van.steenbergen.nl> Message-ID: <4A29153A.2000807@yandex.ru> Do you really need a class? Maybe, a simple data type would do? So, instead of class MyMonad m where myVal1 :: m a myVal2 :: m a -> m [a] instance Monad m => MyMonad (MyMonadT m) where myVal1 = foo myVal2 = bar you can write (in your first package) something like data MyMonad m = MyMonad {myVal1 :: forall a. m a, myVal2 :: forall a. m a -> m [a]} myMonadT :: Monad m => MyMonad m myMonadT = MyMonad {myVal1 = foo, myVal2 = bar} Then you can define something like myMonadParsec :: MyMonad Parser myMonadParsec = ... and use it wherever you want your instance. There are two disadvantages: 1) It's not Haskell98, since we use forall's. 2) You have to explicitly state what instance you define. Personally, I don't care about the first one, and the second one doesn't seem bad enough to outweight the benefit of not having orphan instances. Usually, you can restore most of Haskell's automatic choice of instance by using some upper-level classes. Note also that you can have both the class and the data type. Martijn van Steenbergen wrote on 05.06.2009 13:54: > Hello, > > Suppose I have two projects: 1) one that defines a monad transformer and > an accompanying type class that captures my monad-specific operations > and 2) one that uses the other project, combining the monad transformer > with, say, Parsec. > > Now while writing my Parsec parser I want to use my monad transformer > operations without using lift: I need an instance MyMonadT Parsec. Where > should this instance go? I can think of three answers, all unsatisfactory: > > 1) For obvious reasons it shouldn't go in the Parsec package. > > 2) For pretty much the same reasons it shouldn't go in my monad > transformer package, either. Also, it is undesirable to add a dependency > on Parsec just for this instance, and the package should not have to > know about the projects that are going to use it. > > 3) If I put it in the second project it is an orphan instance, which is > undesirable for well-known reasons. > > What is the best solution? > > Thank you, > > Martijn. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From miguelimo38 at yandex.ru Fri Jun 5 08:56:19 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Fri Jun 5 08:40:55 2009 Subject: [Haskell-cafe] Monad transformer responsibilities In-Reply-To: <4A29153A.2000807@yandex.ru> References: <4A28EB38.3050604@van.steenbergen.nl> <4A29153A.2000807@yandex.ru> Message-ID: <4A2915F3.5060307@yandex.ru> Miguel Mitrofanov wrote on 05.06.2009 16:53: > myMonadT :: Monad m => MyMonad m Sorry, I've meant myMonadT :: Monad m => MyMonad (MyMonadT m) From claus.reinke at talk21.com Fri Jun 5 09:02:15 2009 From: claus.reinke at talk21.com (Claus Reinke) Date: Fri Jun 5 08:46:10 2009 Subject: [Haskell-cafe] Monad transformer responsibilities References: <4A28EB38.3050604@van.steenbergen.nl><2f9b2d30906050329o41239b5ahd653964f7d4bd02d@mail.gmail.com> <49a77b7a0906050521j5125164x17d396dfc2383a5d@mail.gmail.com> Message-ID: <0CDE8EF31B614595AB979B17C23DD730@cr3lt> | bar :: (C T) => T | *Main> :t bar | | :1:0: | No instance for (C T) | arising from a use of `bar' at :1:0-2 | Possible fix: add an instance declaration for (C T) | In the expression: bar I'm not sure where that comes from, but it does seem to be an artifact of GHC's type inference, which seems unwilling to infer a flexible context even if flexible contexts are enabled: *Main> :show languages active language flags: -XImplicitPrelude -XFlexibleContexts *Main> let f _ = negate [] *Main> :t f f :: (Num [a]) => t -> [a] *Main> let f _ = negate [()] :1:10: No instance for (Num [()]) arising from a use of `negate' at :1:10-20 Possible fix: add an instance declaration for (Num [()]) In the expression: negate [()] In the definition of `f': f _ = negate [()] *Main> let f :: Num [()] => t -> [()]; f _ = negate [()] *Main> :t f :1:0: No instance for (Num [()]) arising from a use of `f' at :1:0 Possible fix: add an instance declaration for (Num [()]) In the expression: f This does look like a bug to me? Compare with Hugs (Hugs mode): Main> :t let f _ = negate [] in f let {...} in f :: Num [a] => b -> [a] Main> :t let f _ = negate [()] in f let {...} in f :: Num [()] => a -> [()] Claus From cetin.sert at gmail.com Fri Jun 5 09:02:37 2009 From: cetin.sert at gmail.com (Cetin Sert) Date: Fri Jun 5 08:46:51 2009 Subject: [Haskell-cafe] Re: specialization in type classes In-Reply-To: <1ff5dedc0906050509w5c6134e0vf5d382b0c3a049d3@mail.gmail.com> References: <1ff5dedc0906050509w5c6134e0vf5d382b0c3a049d3@mail.gmail.com> Message-ID: <1ff5dedc0906050602h15ebda2dtb9afd94bf105ea3a@mail.gmail.com> Now there's also a stackoverflow question for this: http://stackoverflow.com/questions/955711/specialization-in-type-classes-using-ghc Any help highly appreciated! 2009/6/5 Cetin Sert > module IOStream where > > import System.IO > import System.IO.Unsafe > > class Out a where > out :: a ? String > > instance Show a ? Out a where > out = show > > instance Out String where > {-# SPECIALISE out :: String ? String #-} > out = id > > instance Out Char where > {-# SPECIALISE out :: Char ? String #-} > out = \x ? [x] > > infixl 0 <<, ? > (?), (<<) :: Out a ? IO Handle ? a ? IO Handle > (<<)= (?) > h ? a = do > s ? h > hPutStr s $ out a > return s > > cout, cin, cerr :: IO Handle > cout = return stdout > cin = return stdin > cerr = return stderr > > endl :: String > endl = "\n" > > --- > > cetin@unique:~/lab/c/linking/demo$ ghci -fglasgow-exts iostream.hs > GHCi, version 6.10.2: http://www.haskell.org/ghc/ :? for help > Loading package ghc-prim ... linking ... done. > Loading package integer ... linking ... done. > Loading package base ... linking ... done. > Ok, modules loaded: IOStream. > Prelude IOStream> cout << 22 << False > 22False{handle: } > Prelude IOStream> cout << 22 << False << endl > > :1:0: > Overlapping instances for Out String > arising from a use of `<<' at :1:0-26 > Matching instances: > instance (Show a) => Out a -- Defined in IOStream > instance Out String -- Defined in IOStream > In the expression: cout << 22 << False << endl > In the definition of `it': it = cout << 22 << False << endl > > o________________O > > how can I specialise a type class function? > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090605/17cc0390/attachment.html From Malcolm.Wallace at cs.york.ac.uk Fri Jun 5 09:35:02 2009 From: Malcolm.Wallace at cs.york.ac.uk (Malcolm Wallace) Date: Fri Jun 5 09:22:37 2009 Subject: [Haskell-cafe] A small puzzle: inTwain as function of foldr In-Reply-To: <4A28FFB2.2000503@van.steenbergen.nl> References: <4A27D8A6.1090605@van.steenbergen.nl> <4A28FFB2.2000503@van.steenbergen.nl> Message-ID: <20090605143502.093ba46e.Malcolm.Wallace@cs.york.ac.uk> Martijn van Steenbergen wrote: > But this uses length and init and last all of which are recursive > functions. I consider that cheating: only foldr may do the recursion. I think the key is to pick your intermediate data-structure wisely. A pair of queues would be my choice. You don't need to calculate any lengths, just keep a parity bit for how far you have already come. Code is below, including a very simple implementation of queues - I'm sure there are better ones out there. > import Data.List (foldl') > > -- inTwain divides a list of even length into two sections of equal length, > -- using a single recursive traversal (fold) of the input. > -- Intermediate values are a pair of FIFO queues, keeping a parity state > -- to ensure the queues are of nearly equal length. > inTwain :: [a] -> ([a],[a]) > inTwain = unTwo . foldl' redistrib emptyTwo > where > redistrib (Two Even begin end) v = Two Odd begin (enQ v end) > redistrib (Two Odd begin end) v = Two Even (enQ e begin) (enQ v es) > where (e,es) = deQ end > > -- The intermediate data structures needed. > data Parity = Odd | Even > data Two a = Two Parity (Queue a) (Queue a) > data Queue a = Q [a] [a] > > emptyTwo = Two Even emptyQ emptyQ > emptyQ = Q [] [] > > unTwo :: Two a -> ([a],[a]) > unTwo (Two _ begin end) = (unQ begin, unQ end) > > -- A very simple implementation of FIFO queues. > enQ :: a -> Queue a -> Queue a > deQ :: Queue a -> (a, Queue a) > unQ :: Queue a -> [a] > enQ v (Q begin end) = Q begin (v:end) > deQ (Q (v:vs) end) = (v, Q vs end) > deQ (Q [] []) = error ("deQ []") > deQ (Q [] end) = deQ (Q (reverse end) []) > unQ (Q begin end) = begin ++ reverse end Regards, Malcolm From conor at strictlypositive.org Fri Jun 5 10:22:18 2009 From: conor at strictlypositive.org (Conor McBride) Date: Fri Jun 5 10:06:24 2009 Subject: [Haskell-cafe] Non Empty List? In-Reply-To: <7fb8f82f0906041734h53c71f5xb56285990ae21509@mail.gmail.com> References: <7fb8f82f0906041734h53c71f5xb56285990ae21509@mail.gmail.com> Message-ID: <1C0C698E-A2A1-4769-AF9F-DF2CBEEAE52C@strictlypositive.org> Hi folks data NE x = x :> Maybe (NE x) ? It's Applicative in at least four different ways. Can anyone find more? Conor On 5 Jun 2009, at 01:34, Edward Kmett wrote: > G?nther, > > Miguel had the easiest suggestion to get right: > > Your goal is to avoid the redundant encoding of a list of one > element, so why do you need to get rid of the Many a [] case when > you can get rid of your Single a case! > > > module NE where > > > import Prelude hiding (foldr, foldl, foldl1, head, tail) > > import Data.Foldable (Foldable, foldr, toList, foldl, foldl1) > > import Data.Traversable (Traversable, traverse) > > import Control.Applicative > > > data NE a = NE a [a] deriving (Eq,Ord,Show,Read) > > Now we can fmap over non-empty lists > > > instance Functor NE where > > fmap f (NE a as) = NE (f a) (map f as) > > It is clear how to append to a non-empty list. > > > cons :: a -> NE a -> NE a > > a `cons` NE b bs = NE a (b:bs) > > head is total. > > > head :: NE a -> a > > head (NE a _) = a > > tail can return an empty list, so lets model that > > > tail :: NE a -> [a] > > tail (NE _ as) = as > > We may not be able to construct a non-empty list from a list, if its > empty so model that. > > > fromList :: [a] -> Maybe (NE a) > > fromList (x:xs) = Just (NE x xs) > > fromList [] = Nothing > > We can make our non-empty lists an instance of Foldable so you can > use Data.Foldable's versions of foldl, foldr, etc. and nicely foldl1 > has a very pretty total definition, so lets use it. > > > instance Foldable NE where > > foldr f z (NE a as) = a `f` foldr f z as > > foldl f z (NE a as) = foldl f (z `f` a) as > > foldl1 f (NE a as) = foldl f a as > > We can traverse non-empty lists too. > > > instance Traversable NE where > > traverse f (NE a as) = NE <$> f a <*> traverse f as > > And they clearly offer a monadic structure: > > > instance Monad NE where > > return a = NE a [] > > NE a as >>= f = NE b (bs ++ concatMap (toList . f) as) where > > NE b bs = f a > > and you can proceed to add suitable instance declarations for it to > be a Comonad if you are me, etc. > > Now a singleton list has one representation > > NE a [] > > A list with two elements can only be represented by NE a [b] > > And so on for NE a [b,c], NE 1 [2..], etc. > > You could also make the > > > data Container a = Single a | Many a (Container a) > > definition work that Jake McArthur provided. For the category theory > inspired reader Jake's definition is equivalent to the Cofree > comonad of the Maybe functor, which can encode a non-empty list. > > I leave that one as an exercise for the reader, but observe > > Single 1 > Many 1 (Single 2) > Many 1 (Many 2 (Single 3)) > > And the return for this particular monad is easy: > > instance Monad Container where > return = Single > > In general Jake's non-empty list is a little nicer because it avoids > a useless [] constructor at the end of the list. > > -Edward Kmett > > On Thu, Jun 4, 2009 at 5:53 PM, G??nther Schmidt > wrote: > Hi, > > I need to design a container data structure that by design cannot be > empty and can hold n elements. Something like a non-empty list. > > > I started with: > > data Container a = Single a | Many a [a] > > but the problem above is that the data structure would allow to > construct a Many 5 [] :: Container Int. > > I can't figure out how to get this right. :( > > Please help. > > G?nther > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From conor at strictlypositive.org Fri Jun 5 11:18:51 2009 From: conor at strictlypositive.org (Conor McBride) Date: Fri Jun 5 11:02:44 2009 Subject: [Haskell-cafe] web musing Message-ID: Comrades I'm in a perplexing situation and I'd like to appeal to the sages. I've never written anything other than static HTML in my life, and I'd like to make a wee web service: I've heard some abbreviations, but I don't really know what they mean. I've got a function (possibly the identity, possibly const "", who knows?) assistant :: String -> String and I want to make a webpage with an edit box and a submit button. If I press the submit button with the edit box containing string s, I'd like the page to reload with the edit box reset to (assistant s). Will I need to ask systems support to let me install some haskelly sort of web server? Looks likely, I suppose. In general, what's an easy way to put a web front end on functionality implemented in Haskell? Hoping this isn't a hard question Conor From max.rabkin at gmail.com Fri Jun 5 11:35:11 2009 From: max.rabkin at gmail.com (Max Rabkin) Date: Fri Jun 5 11:19:22 2009 Subject: [Haskell-cafe] web musing In-Reply-To: References: Message-ID: On Fri, Jun 5, 2009 at 5:18 PM, Conor McBride wrote: > > Will I need to ask systems support to let me install some > haskelly sort of web server? Looks likely, I suppose. > > In general, what's an easy way to put a web front end on > functionality implemented in Haskell? > For something this simple, I'd use CGI. I've never used the Haskell cgi package, but the basic idea is that the webserver runs an arbitrary script which reads the HTTP request information from environment variables, and outputs the response (in the simple case, just "Content-Type: text/html\r\n\r\n"++html). The cgi package probably provides easy access to those environment variables; this is what Python's cgi module does, for instance. --Max From dagit at codersbase.com Fri Jun 5 12:12:26 2009 From: dagit at codersbase.com (Jason Dagit) Date: Fri Jun 5 11:56:17 2009 Subject: [Haskell-cafe] web musing In-Reply-To: References: Message-ID: On Fri, Jun 5, 2009 at 8:18 AM, Conor McBride wrote: > Comrades > > I'm in a perplexing situation and I'd like to appeal to the > sages. > > I've never written anything other than static HTML in my life, > and I'd like to make a wee web service: I've heard some > abbreviations, but I don't really know what they mean. > > I've got a function (possibly the identity, possibly const "", > who knows?) > > assistant :: String -> String > > and I want to make a webpage with an edit box and a submit > button. If I press the submit button with the edit box > containing string s, I'd like the page to reload with the > edit box reset to (assistant s). > > Will I need to ask systems support to let me install some > haskelly sort of web server? Looks likely, I suppose. > > In general, what's an easy way to put a web front end on > functionality implemented in Haskell? Several of us cobbled together a web service version of lambdabot at one point. We used fast cgi plus apache on the unix side. In the program we used the fastcgi haskell bindings (I forget which package), and excuted lambdabot as a subprocess and communicated over pipes, I think. Then on the web page side there was a bit of ajax that executed the cgi request and spliced the value into the webpage. It no longer works due to changes in lambdabot, but all lambdabot knew was that it was running as a normal unix process. In a simpler world the code that used the cgi bindings could directly import your assistant function. I can try to dig up the sources if you want to see the code. It was pretty slick. And I'd say the bottom line is, you just need (fast) cgi bindings and you're good on any host where cgi is supported. Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090605/1cf63caa/attachment.html From jgbailey at gmail.com Fri Jun 5 12:30:49 2009 From: jgbailey at gmail.com (Justin Bailey) Date: Fri Jun 5 12:14:59 2009 Subject: [Haskell-cafe] web musing In-Reply-To: References: Message-ID: I bet they have PHP on the server already. Write your program so it takes input from standard in and writes to standard out. Then just run your executable from PHP and write to its pipe. Instant web service! On Fri, Jun 5, 2009 at 8:18 AM, Conor McBride wrote: > Comrades > > I'm in a perplexing situation and I'd like to appeal to the > sages. > > I've never written anything other than static HTML in my life, > and I'd like to make a wee web service: I've heard some > abbreviations, but I don't really know what they mean. > > I've got a function (possibly the identity, possibly const "", > who knows?) > > ?assistant :: String -> String > > and I want to make a webpage with an edit box and a submit > button. If I press the submit button with the edit box > containing string s, I'd like the page to reload with the > edit box reset to (assistant s). > > Will I need to ask systems support to let me install some > haskelly sort of web server? Looks likely, I suppose. > > In general, what's an easy way to put a web front end on > functionality implemented in Haskell? > > Hoping this isn't a hard question > > Conor > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From ryani.spam at gmail.com Fri Jun 5 13:35:28 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Fri Jun 5 13:19:19 2009 Subject: [Haskell-cafe] Re: specialization in type classes In-Reply-To: <1ff5dedc0906050602h15ebda2dtb9afd94bf105ea3a@mail.gmail.com> References: <1ff5dedc0906050509w5c6134e0vf5d382b0c3a049d3@mail.gmail.com> <1ff5dedc0906050602h15ebda2dtb9afd94bf105ea3a@mail.gmail.com> Message-ID: <2f9b2d30906051035n7c532fcej91f9100d8435534d@mail.gmail.com> The SPECIALIZE pragma doesn't do what you think; those implementations are already as specialized as they get. You can enable OverlappingInstances, but the big problem is that it doesn't really work; consider this function: > foo :: Show a => a -> String > foo x = out x > question = foo "hello" What should "question" return? "hello", or "\"hello\""? With the "dictionary-passing-style" that GHC uses for typeclasses, "foo" will always call the Show a => Out a instance of out. But that's incorrect; question passes a String which has a specific implementation of "out", and that implementation doesn't get called. The right answer is to do this: > newtype UseShow a = UseShow a > instance Show a => Out (UseShow a) where > out (UseShow a) = show a Now you can write > test1 = out (UseShow 1) -- "1" > test2 = out (UseShow "hello") -- "\"hello\"" > test3 = out "hello" -- "hello" Feel free to use a shorter name for UseShow, of course :) I believe there is a proposal to allow you to declare ad-hoc superclasses of typeclasses; this would let you write -- notice reversed => to <= class Show a <= Out a where out :: a -> String out = show This means that every instance of Show is required to be an instance of Out; the default implementation of "out" for types that don't have an explicit instance is given. (In the dictionary-passing world, this means that every "Show" dictionary will contain an "Out" dictionary, instead of having to construct the "out" implementation as in your instance, it could contain a different "out" function that the default) But this isn't in the language currently. -- ryan 2009/6/5 Cetin Sert : > Now there's also a stackoverflow question for this: > http://stackoverflow.com/questions/955711/specialization-in-type-classes-using-ghc > Any help highly appreciated! > > 2009/6/5 Cetin Sert >> >> module IOStream where >> >> import System.IO >> import System.IO.Unsafe >> >> class Out a where >> out :: a ? String >> >> instance Show a => Out a where >> out = show >> >> instance Out String where >> {-# SPECIALISE out :: String ? String #-} >> out = id >> >> instance Out Char where >> {-# SPECIALISE out :: Char ? String #-} >> out = \x ? [x] >> >> infixl 0 <<, ? >> (?), (<<) :: Out a => IO Handle ? a ? IO Handle >> (<<)= (?) >> h ? a = do >> s ? h >> hPutStr s $ out a >> return s >> >> cout, cin, cerr :: IO Handle >> cout = return stdout >> cin = return stdin >> cerr = return stderr >> >> endl :: String >> endl = "\n" >> >> --- >> >> cetin@unique:~/lab/c/linking/demo$ ghci -fglasgow-exts iostream.hs >> GHCi, version 6.10.2: http://www.haskell.org/ghc/ :? for help >> Loading package ghc-prim ... linking ... done. >> Loading package integer ... linking ... done. >> Loading package base ... linking ... done. >> Ok, modules loaded: IOStream. >> Prelude IOStream> cout << 22 << False >> 22False{handle: } >> Prelude IOStream> cout << 22 << False << endl >> >> :1:0: >> Overlapping instances for Out String >> arising from a use of `<<' at :1:0-26 >> Matching instances: >> instance (Show a) => Out a -- Defined in IOStream >> instance Out String -- Defined in IOStream >> In the expression: cout << 22 << False << endl >> In the definition of `it': it = cout << 22 << False << endl >> >> o________________O >> >> how can I specialise a type class function? > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From vigalchin at gmail.com Fri Jun 5 15:33:06 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Fri Jun 5 15:16:57 2009 Subject: [Haskell-cafe] Cabal "addressibility" problem Message-ID: <5ae4f2ba0906051233u351e1ef5q31dde69482a4628f@mail.gmail.com> Hello, The following is a fragment in my cabal file: Executable GraphPartitionTest Main-Is: Swish.HaskellRDF.GraphPartitionTest.hs Other-modules: Swish.HaskellRDF.GraphPartition Swish.HaskellRDF.GraphClass Swish.HaskellUtils.ListHelpers Swish.HaskellUtils.TestHelpers When I try to do a build I get: Setup: can't find source for Swish in . Cabal/Setup seem to be looking in the current directory for source but as you can see I gave "full" paths, i.e. Swish.HaskellRDF* or Swish.HaskellUtils*. What I doing wrong? Regards, Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090605/9b31e3cb/attachment.html From flippa at flippac.org Fri Jun 5 15:40:58 2009 From: flippa at flippac.org (Philippa Cowderoy) Date: Fri Jun 5 15:25:01 2009 Subject: [Haskell-cafe] web musing In-Reply-To: References: Message-ID: <1244230858.7090.450.camel@flippa-eee> On Fri, 2009-06-05 at 16:18 +0100, Conor McBride wrote: > I've got a function (possibly the identity, possibly const "", > who knows?) > > assistant :: String -> String > > and I want to make a webpage with an edit box and a submit > button. If I press the submit button with the edit box > containing string s, I'd like the page to reload with the > edit box reset to (assistant s). > > Will I need to ask systems support to let me install some > haskelly sort of web server? Looks likely, I suppose. > > In general, what's an easy way to put a web front end on > functionality implemented in Haskell? You don't need a web server so long as you've got a compiler - Network.CGI ought to work nicely for your purposes, you just have a binary that's called by the web server, processes the request and yields input. If you're not doing disk I/O, pretty much the entire program's plain functional stuff. -- Philippa Cowderoy From gwern0 at gmail.com Fri Jun 5 15:43:06 2009 From: gwern0 at gmail.com (Gwern Branwen) Date: Fri Jun 5 15:26:59 2009 Subject: [Haskell-cafe] Cabal "addressibility" problem In-Reply-To: <5ae4f2ba0906051233u351e1ef5q31dde69482a4628f@mail.gmail.com> References: <5ae4f2ba0906051233u351e1ef5q31dde69482a4628f@mail.gmail.com> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On Fri, Jun 5, 2009 at 3:33 PM, Vasili I. Galchin wrote: > Hello, > > The following is a fragment in my cabal file: > > > Executable GraphPartitionTest > Main-Is: Swish.HaskellRDF.GraphPartitionTest.hs > Other-modules: Swish.HaskellRDF.GraphPartition > Swish.HaskellRDF.GraphClass > Swish.HaskellUtils.ListHelpers > Swish.HaskellUtils.TestHelpers > > > > When I try to do a build I get: > > > Setup: can't find source for Swish in . > > Cabal/Setup seem to be looking in the current directory for source but as > you can see I gave "full" paths, i.e. Swish.HaskellRDF* or > Swish.HaskellUtils*. > > What I doing wrong? > > > Regards, > > Vasili You need to give more detail. For example, is your directory layout like './src/Swish/HaskellRDF.../foo.hs'? In that case, Cabal is looking for './Swish/HaskellRDF.../foo.hs'. You need to tell it to look in src/ and not ./ with a line like 'hs-source-dirs: src/' etc. - -- gwern -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEAREKAAYFAkopdUsACgkQvpDo5Pfl1oLbCgCfWI1MZOyWnsyAkra88S/LC506 7oMAoJhv5hDcc1Ypqq0hLncB2t/1Yuby =ADOt -----END PGP SIGNATURE----- From bartek at sudety.it Fri Jun 5 17:45:09 2009 From: bartek at sudety.it (Bartosz =?iso-8859-1?q?W=F3jcik?=) Date: Fri Jun 5 15:29:08 2009 Subject: [Haskell-cafe] Fast code question Message-ID: <200906052245.09233.bartek@sudety.it> Packed Decimal downloaded on pc is just a stream of bytes without any comma. I was supposed to reformat data. If I undersdand bytestring-csv library, it parses csv format data. Thanks for the hint. I'll investigate next time when I have to deal with huge files. Bartek On Thursday 04 June 2009 23:21:21 you wrote: > Can you use the bytestring csv parser (or convert it into a pretty > printer?) > > bartek: > > Hi Folks, > > > > I had to transform Packed Decimal file into csv format (does anybody here > > know what this Mainframe format is?). ?Because of the file size I could > > not do this on mainframe directly. So I've created simply program using > > ByteString. Generally I'm happy with my solution: pgm processes arroud > > 2MB/s on my pc, so my 3GB file was transformed in reasonable 30 min time. > > > > My question is: how to do this faster? > > > > {code} > > module Main > > where > > ? > > import qualified Data.ByteString.Lazy as B > > ? > > main = ?B.getContents >>= myPrint . myConcat . B.unpack > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ^^^^^^^^^^^^^^^^^^^^^ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? That looks bad. ------------------------------------------------------- From bartek at sudety.it Fri Jun 5 17:49:25 2009 From: bartek at sudety.it (Bartosz =?utf-8?q?W=C3=B3jcik?=) Date: Fri Jun 5 15:33:22 2009 Subject: [Haskell-cafe] Fast code question In-Reply-To: <29bf512f0906041438q49f89667v1bdcb3eba653cc04@mail.gmail.com> References: <200906050031.26336.bartek@sudety.it> <29bf512f0906041438q49f89667v1bdcb3eba653cc04@mail.gmail.com> Message-ID: <200906052249.25439.bartek@sudety.it> Integer was on purpose. One of the fields was 14 digits number. Usually I parse EBCDIC directly on mainframe. This time it was exception. Bartek On Thursday 04 June 2009 22:38:53 Michael Snoyman wrote: > I *do* know what Packed Decimal is; at my previous job, I actually had a > whole Haskell library for parsing them. The only immediate suggestion that > pops to mind is to use Int instead of Integer (Int uses regular 32- or > 64-bit integers, Integer uses arbitrary precision integers). If you send me > a sample Packed Decimal file, I can test out your code and get a better > feel for it that way. > > Good luck with those mainframes, they can be beasts sometimes. Have you had > to parse EBCDIC yet? *That* was fun, manually copying all those character > codes from some IBM web page... ;) From rendel at cs.au.dk Fri Jun 5 16:01:04 2009 From: rendel at cs.au.dk (Tillmann Rendel) Date: Fri Jun 5 15:44:57 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: References: Message-ID: <4A297980.60509@cs.au.dk> Hi, please write to the whole list, not just me. There are a lot of people around who can help you. MH wrote: > Rendel do you mind to explain to me how Container a = Many a > (Container [a]) prevents user from creating an empty list? > I did try the following: > let a = Many "string" > a :: Container [Char] -> Container [Char] > let b = Many [] > b :: forall a. Container [a] -> Container [a] > > but I can not understand what is the difference. You cannot prevent users from creating an empty list, because lists are already defined in the Haskell prelude, and you cannot change that definition. But you can define your own datatype Container which prevents users from creating empty containers. Your datatype data Container a = Many a (Container [a]) is quite complicated, because you have (Container a) on the left hand side of the equation, but (Container [a]) on the right hand side. Is that on purpose? Anyway, your Container has the property that a (Container a) is never empty, because it always contains at least one value of type a, namely the first parameter of Many. To see that, we can write a function which extracts that element: getContainerElement :: Container a -> a getContainerElement (Many element something) = element It is not possible to write such a function for ordinary lists without calling error or entering a nonterminating loop: getListElement :: [a] -> a getListElement (element : something) = element getListElement [] = error "no element around :(" So ordinary lists can be empty, but your Containers can't. Tillmann From vigalchin at gmail.com Fri Jun 5 16:10:04 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Fri Jun 5 15:53:55 2009 Subject: [Haskell-cafe] Cabal "addressibility" problem In-Reply-To: References: <5ae4f2ba0906051233u351e1ef5q31dde69482a4628f@mail.gmail.com> Message-ID: <5ae4f2ba0906051310j72eb35eftd28f17f62d590ed8@mail.gmail.com> for directory structure I Swish-0.2.1/Swish/HaskellRDF and Swish-0.2.1/Swish/HaskellUtils ... there are deeper directories but that distract from the discussion ... to make things concete: 1) swish.cabal is directly under Swish-0.2.1 2) GraphPartitionTest.hs is under Swish-0.2.1/Swish/HaskellRDF 3) GraphPartitionTest's dependencies are either under HaskellRDF or HaskellUtils Hope this helps to make things clearer. I added a "Hs-source-dirs" but that help. I did a "ruinhaskell Setup -?" to check on options. I don't see any verbose mode so that when I do "runhaskell Setup build" I can moniitor the progress of my build for diagnostic purposes! Is there a verbose mode? Thanks, Vasili On Fri, Jun 5, 2009 at 2:43 PM, Gwern Branwen wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA512 > > On Fri, Jun 5, 2009 at 3:33 PM, Vasili I. Galchin wrote: > > Hello, > > > > The following is a fragment in my cabal file: > > > > > > Executable GraphPartitionTest > > Main-Is: Swish.HaskellRDF.GraphPartitionTest.hs > > Other-modules: Swish.HaskellRDF.GraphPartition > > Swish.HaskellRDF.GraphClass > > Swish.HaskellUtils.ListHelpers > > Swish.HaskellUtils.TestHelpers > > > > > > > > When I try to do a build I get: > > > > > > Setup: can't find source for Swish in . > > > > Cabal/Setup seem to be looking in the current directory for source but as > > you can see I gave "full" paths, i.e. Swish.HaskellRDF* or > > Swish.HaskellUtils*. > > > > What I doing wrong? > > > > > > Regards, > > > > Vasili > > You need to give more detail. > > For example, is your directory layout like > './src/Swish/HaskellRDF.../foo.hs'? In that case, Cabal is looking for > './Swish/HaskellRDF.../foo.hs'. You need to tell it to look in src/ > and not ./ with a line like 'hs-source-dirs: src/' etc. > > - -- > gwern > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v1.4.9 (GNU/Linux) > > iEYEAREKAAYFAkopdUsACgkQvpDo5Pfl1oLbCgCfWI1MZOyWnsyAkra88S/LC506 > 7oMAoJhv5hDcc1Ypqq0hLncB2t/1Yuby > =ADOt > -----END PGP SIGNATURE----- > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090605/5a035200/attachment.html From gwern0 at gmail.com Fri Jun 5 16:28:43 2009 From: gwern0 at gmail.com (Gwern Branwen) Date: Fri Jun 5 16:12:34 2009 Subject: [Haskell-cafe] Cabal "addressibility" problem In-Reply-To: <5ae4f2ba0906051310j72eb35eftd28f17f62d590ed8@mail.gmail.com> References: <5ae4f2ba0906051233u351e1ef5q31dde69482a4628f@mail.gmail.com> <5ae4f2ba0906051310j72eb35eftd28f17f62d590ed8@mail.gmail.com> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On Fri, Jun 5, 2009 at 4:10 PM, Vasili I. Galchin wrote: > for directory structure I Swish-0.2.1/Swish/HaskellRDF and > Swish-0.2.1/Swish/HaskellUtils ... there are deeper directories but that > distract from the discussion ... to make things concete: > > 1) swish.cabal is directly under Swish-0.2.1 > > 2) GraphPartitionTest.hs is under Swish-0.2.1/Swish/HaskellRDF > > 3) GraphPartitionTest's dependencies are either under HaskellRDF or > HaskellUtils > > Hope this helps to make things clearer. I added a "Hs-source-dirs" but that > help. > > I did a "ruinhaskell Setup -?" to check on options. I don't see any verbose > mode so that when I do "runhaskell Setup build" I can moniitor the progress > of my build for diagnostic purposes! Is there a verbose mode? > > Thanks, > > Vasili [04:27 PM] 0Mb$ build --help Usage: Setup build [FLAGS] Flags for build: -h --help Show this help text -v --verbose[=n] Control verbosity (n is 0--3, default verbosity level is 1) --builddir=DIR The directory where Cabal puts generated build files (default dist) --with-PROG=PATH give the path to PROG --PROG-options=OPTS give extra options to PROG --PROG-option=OPT give an extra option to PROG (no need to quote options containing spaces) - -- gwern -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEAREKAAYFAkopf/sACgkQvpDo5Pfl1oIZfgCeInjWOqdxejdpsBaI62YHkSHu BvIAn1ZsC9rCYmluCW2UCmFGVFcAw3bh =S6In -----END PGP SIGNATURE----- From vigalchin at gmail.com Fri Jun 5 16:37:16 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Fri Jun 5 16:21:06 2009 Subject: [Haskell-cafe] Cabal "addressibility" problem In-Reply-To: References: <5ae4f2ba0906051233u351e1ef5q31dde69482a4628f@mail.gmail.com> <5ae4f2ba0906051310j72eb35eftd28f17f62d590ed8@mail.gmail.com> Message-ID: <5ae4f2ba0906051337j6f5c36d7s311ef76edf9e90a8@mail.gmail.com> At work I am using Windose ... so I use "runhaskell .. I don't have "build" .... Vasili On Fri, Jun 5, 2009 at 3:28 PM, Gwern Branwen wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA512 > > On Fri, Jun 5, 2009 at 4:10 PM, Vasili I. Galchin wrote: > > for directory structure I Swish-0.2.1/Swish/HaskellRDF and > > Swish-0.2.1/Swish/HaskellUtils ... there are deeper directories but that > > distract from the discussion ... to make things concete: > > > > 1) swish.cabal is directly under Swish-0.2.1 > > > > 2) GraphPartitionTest.hs is under Swish-0.2.1/Swish/HaskellRDF > > > > 3) GraphPartitionTest's dependencies are either under HaskellRDF or > > HaskellUtils > > > > Hope this helps to make things clearer. I added a "Hs-source-dirs" but > that > > help. > > > > I did a "ruinhaskell Setup -?" to check on options. I don't see any > verbose > > mode so that when I do "runhaskell Setup build" I can moniitor the > progress > > of my build for diagnostic purposes! Is there a verbose mode? > > > > Thanks, > > > > Vasili > [04:27 PM] 0Mb$ build --help > Usage: Setup build [FLAGS] > > Flags for build: > -h --help Show this help text > -v --verbose[=n] Control verbosity (n is 0--3, default verbosity > level > is 1) > --builddir=DIR The directory where Cabal puts generated build files > (default dist) > --with-PROG=PATH give the path to PROG > --PROG-options=OPTS give extra options to PROG > --PROG-option=OPT give an extra option to PROG (no need to quote > options > containing spaces) > > - -- > gwern > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v1.4.9 (GNU/Linux) > > iEYEAREKAAYFAkopf/sACgkQvpDo5Pfl1oIZfgCeInjWOqdxejdpsBaI62YHkSHu > BvIAn1ZsC9rCYmluCW2UCmFGVFcAw3bh > =S6In > -----END PGP SIGNATURE----- > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090605/996eb2dd/attachment.html From vigalchin at gmail.com Fri Jun 5 16:49:54 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Fri Jun 5 16:33:44 2009 Subject: [Haskell-cafe] Cabal "addressibility" problem In-Reply-To: References: <5ae4f2ba0906051233u351e1ef5q31dde69482a4628f@mail.gmail.com> <5ae4f2ba0906051310j72eb35eftd28f17f62d590ed8@mail.gmail.com> Message-ID: <5ae4f2ba0906051349n3bede6afs889f01a337401fc@mail.gmail.com> getting farther ..... Executable GraphPartitionTest Hs-source-dirs: Swish/ << added this Main-Is: HaskellRDF/GraphPartitionTest.hs <<< changed to a real filesystem path Other-modules: HaskellRDF.GraphPartition HaskellRDF.GraphClass HaskellUtils.ListHelpers HaskellUtils.TestHelpers <<< now says "can't find module 'Swish.HaskellUtils.TestHelpers'"??? Vasili On Fri, Jun 5, 2009 at 3:28 PM, Gwern Branwen wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA512 > > On Fri, Jun 5, 2009 at 4:10 PM, Vasili I. Galchin wrote: > > for directory structure I Swish-0.2.1/Swish/HaskellRDF and > > Swish-0.2.1/Swish/HaskellUtils ... there are deeper directories but that > > distract from the discussion ... to make things concete: > > > > 1) swish.cabal is directly under Swish-0.2.1 > > > > 2) GraphPartitionTest.hs is under Swish-0.2.1/Swish/HaskellRDF > > > > 3) GraphPartitionTest's dependencies are either under HaskellRDF or > > HaskellUtils > > > > Hope this helps to make things clearer. I added a "Hs-source-dirs" but > that > > help. > > > > I did a "ruinhaskell Setup -?" to check on options. I don't see any > verbose > > mode so that when I do "runhaskell Setup build" I can moniitor the > progress > > of my build for diagnostic purposes! Is there a verbose mode? > > > > Thanks, > > > > Vasili > [04:27 PM] 0Mb$ build --help > Usage: Setup build [FLAGS] > > Flags for build: > -h --help Show this help text > -v --verbose[=n] Control verbosity (n is 0--3, default verbosity > level > is 1) > --builddir=DIR The directory where Cabal puts generated build files > (default dist) > --with-PROG=PATH give the path to PROG > --PROG-options=OPTS give extra options to PROG > --PROG-option=OPT give an extra option to PROG (no need to quote > options > containing spaces) > > - -- > gwern > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v1.4.9 (GNU/Linux) > > iEYEAREKAAYFAkopf/sACgkQvpDo5Pfl1oIZfgCeInjWOqdxejdpsBaI62YHkSHu > BvIAn1ZsC9rCYmluCW2UCmFGVFcAw3bh > =S6In > -----END PGP SIGNATURE----- > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090605/299a2c91/attachment.html From gwern0 at gmail.com Fri Jun 5 16:55:55 2009 From: gwern0 at gmail.com (Gwern Branwen) Date: Fri Jun 5 16:39:45 2009 Subject: [Haskell-cafe] Cabal "addressibility" problem In-Reply-To: <5ae4f2ba0906051349n3bede6afs889f01a337401fc@mail.gmail.com> References: <5ae4f2ba0906051233u351e1ef5q31dde69482a4628f@mail.gmail.com> <5ae4f2ba0906051310j72eb35eftd28f17f62d590ed8@mail.gmail.com> <5ae4f2ba0906051349n3bede6afs889f01a337401fc@mail.gmail.com> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On Fri, Jun 5, 2009 at 4:49 PM, Vasili I. Galchin wrote: > getting farther ..... > > Executable GraphPartitionTest > Hs-source-dirs: Swish/ Main-Is: HaskellRDF/GraphPartitionTest.hs filesystem path Right. You understand why it has to be a filepath and not a module name? Because the module name of an executable would be 'Main', not HaskellRDF.GraphPartitionTest. You can try compiling something like module Foo (main) where main = print "hello world" and see for yourself how it fails. > Other-modules: HaskellRDF.GraphPartition > HaskellRDF.GraphClass > HaskellUtils.ListHelpers > HaskellUtils.TestHelpers module 'Swish.HaskellUtils.TestHelpers'"??? > > Vasili Right. hs-source-dirs defined all the module paths as relative to Swish/; I think the solution here would be to have something like 'hs-source-dirs: ., Swish/' (or whatever the directory was that the HaskellUtils stuff can be found in if not ./). - -- gwern -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEAREKAAYFAkophlwACgkQvpDo5Pfl1oJkBgCeLBI6CsOOdt4EzJa1CaYzoMd4 aDAAn3HICqcDAR74J7z4v8xkakVJ6bDl =hgRy -----END PGP SIGNATURE----- From rmm-haskell at z.odi.ac Fri Jun 5 16:55:56 2009 From: rmm-haskell at z.odi.ac (Ross Mellgren) Date: Fri Jun 5 16:39:52 2009 Subject: [Haskell-cafe] Cabal "addressibility" problem In-Reply-To: <5ae4f2ba0906051349n3bede6afs889f01a337401fc@mail.gmail.com> References: <5ae4f2ba0906051233u351e1ef5q31dde69482a4628f@mail.gmail.com> <5ae4f2ba0906051310j72eb35eftd28f17f62d590ed8@mail.gmail.com> <5ae4f2ba0906051349n3bede6afs889f01a337401fc@mail.gmail.com> Message-ID: If your module statements say Swish in them, e.g. module Swish.HaskellUtils.TestHelpers where .... then you should probably have no hs-source-dirs (or hs-source-dirs: .) and then use Swish.HaskellUtils.TestHelpers. But leave Main-Is: as you have it. -Ross On Jun 5, 2009, at 4:49 PM, Vasili I. Galchin wrote: > getting farther ..... > > Executable GraphPartitionTest > Hs-source-dirs: Swish/ << added this > Main-Is: HaskellRDF/GraphPartitionTest.hs <<< changed to > a real filesystem path > Other-modules: HaskellRDF.GraphPartition > HaskellRDF.GraphClass > HaskellUtils.ListHelpers > HaskellUtils.TestHelpers <<< now says "can't > find module 'Swish.HaskellUtils.TestHelpers'"??? > > Vasili > > > On Fri, Jun 5, 2009 at 3:28 PM, Gwern Branwen > wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA512 > > On Fri, Jun 5, 2009 at 4:10 PM, Vasili I. Galchin wrote: > > for directory structure I Swish-0.2.1/Swish/HaskellRDF and > > Swish-0.2.1/Swish/HaskellUtils ... there are deeper directories > but that > > distract from the discussion ... to make things concete: > > > > 1) swish.cabal is directly under Swish-0.2.1 > > > > 2) GraphPartitionTest.hs is under Swish-0.2.1/Swish/HaskellRDF > > > > 3) GraphPartitionTest's dependencies are either under HaskellRDF or > > HaskellUtils > > > > Hope this helps to make things clearer. I added a "Hs-source-dirs" > but that > > help. > > > > I did a "ruinhaskell Setup -?" to check on options. I don't see > any verbose > > mode so that when I do "runhaskell Setup build" I can moniitor the > progress > > of my build for diagnostic purposes! Is there a verbose mode? > > > > Thanks, > > > > Vasili > [04:27 PM] 0Mb$ build --help > Usage: Setup build [FLAGS] > > Flags for build: > -h --help Show this help text > -v --verbose[=n] Control verbosity (n is 0--3, default > verbosity level > is 1) > --builddir=DIR The directory where Cabal puts generated > build files > (default dist) > --with-PROG=PATH give the path to PROG > --PROG-options=OPTS give extra options to PROG > --PROG-option=OPT give an extra option to PROG (no need to > quote options > containing spaces) > > - -- > gwern > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v1.4.9 (GNU/Linux) > > iEYEAREKAAYFAkopf/sACgkQvpDo5Pfl1oIZfgCeInjWOqdxejdpsBaI62YHkSHu > BvIAn1ZsC9rCYmluCW2UCmFGVFcAw3bh > =S6In > -----END PGP SIGNATURE----- > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090605/4f3bd33b/attachment.html From ryani.spam at gmail.com Fri Jun 5 16:58:33 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Fri Jun 5 16:42:23 2009 Subject: [Haskell-cafe] Is it possible to do type-level arithmetic without UndeciableInstances? Message-ID: <2f9b2d30906051358l1a34eeecx4eca0c1aeab4d26e@mail.gmail.com> > {-# LANGUAGE TypeFamilies #-} > module PeanoArith > data Z = Z > data S n = S n So, this type family works just fine: > type family Plus a b > type instance Plus Z b = b > type instance Plus (S a) b = S (Plus a b) As does this one: > type family Minus a b > type instance Minus a Z = Z > type instance Minus Z (S b) = Z > type instance Minus (S a) (S b) = Minus a b But this one doesn't work without UndecidableInstances: > type family Times a b > type instance Times Z b = Z > type instance Times (S a) b = Plus b (Times a b) I tried several different implementations for Times but I was unable to come up with one that passed the type family termination checker. Is there a way to do so? Some examples of attempts: > -- (a+1)*(b+1) = ab + a + b + 1 > type family Times1 a b > type instance Times1 Z Z = Z > type instance Times1 (S n) Z = Z > type instance Times1 Z (S n) = Z > type instance Times1 (S a) (S b) = S (Plus (Times1 a b) (Plus a b)) > -- inline Plus > type family Times2_H a b acc > type Times2 a b = Times2_H a b Z > type instance Times2_H a b (S acc) = S (Times2_H a b acc) > type instance Times2_H Z b Z = Z > type instance Times2_H (S a) b Z = Times2_H a b b Do you have any other ideas? Is (a*b) too big for the termination checker to ever accept? -- ryan From rwbarton at math.harvard.edu Fri Jun 5 17:39:49 2009 From: rwbarton at math.harvard.edu (Reid Barton) Date: Fri Jun 5 17:23:51 2009 Subject: [Haskell-cafe] Is it possible to do type-level arithmetic without UndeciableInstances? In-Reply-To: <2f9b2d30906051358l1a34eeecx4eca0c1aeab4d26e@mail.gmail.com> References: <2f9b2d30906051358l1a34eeecx4eca0c1aeab4d26e@mail.gmail.com> Message-ID: <20090605213949.GA22976@rwbarton.mit.edu> On Fri, Jun 05, 2009 at 01:58:33PM -0700, Ryan Ingram wrote: > I tried several different implementations for Times but I was unable > to come up with one that passed the type family termination checker. > Is there a way to do so? Here is a solution. I don't understand exactly why this works while various simpler things don't. {-# LANGUAGE TypeFamilies, TypeOperators, KindSignatures #-} data Z = Z data S n = S n newtype Id a = Id a newtype (a :. b) c = O (a (b c)) type family Expand x type instance Expand Z = Z type instance Expand (S a) = S (Expand a) type instance Expand (Id a) = Expand a type instance Expand ((a :. b) c) = Expand (a (b c)) type family (f :: * -> *) :^ n :: * -> * type instance f :^ Z = Id type instance f :^ (S a) = f :. (f :^ a) type Plus a = S :^ a type Times a b = Expand ((Plus a :^ b) Z) {- *Main> undefined :: Times (S (S Z)) (S (S (S Z))) :1:0: No instance for (Show (S (S (S (S (S (S Z))))))) arising from a use of `print' at :1:0-41 Possible fix: add an instance declaration for (Show (S (S (S (S (S (S Z))))))) In a stmt of a 'do' expression: print it -} Regards, Reid From iavor.diatchki at gmail.com Fri Jun 5 17:42:47 2009 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Fri Jun 5 17:26:37 2009 Subject: [Haskell-cafe] web musing In-Reply-To: References: Message-ID: <5ab17e790906051442w7ce6ce5q103a74b0b6f2d45a@mail.gmail.com> Hi Conor, As someone pointed out, CGI is one way to go. Another option is to write a small Haskell web server. This path is better if you have an app that needs to keep state, ans uses the browser mostly as a GUI. I have just made a package that should make doing this fairly easy. I have not uploaded it to hackage yet because I want to make some small changes still. You can try out the "pre-release" from here (the usual cabal steps should work for making a package/installing) git clone git://code.galois.com/http-server.git For an example, take a look in the "example" directory, there is a small web-server there, which shows how to all kinds of things, including ajax interactions with javascript using jQuery. For processing form data there is the module: Network.HTTP.Server.HtmlForm. Let me know if you have questions, comments, or other feed-back! -Iavor On Fri, Jun 5, 2009 at 8:18 AM, Conor McBride wrote: > Comrades > > I'm in a perplexing situation and I'd like to appeal to the > sages. > > I've never written anything other than static HTML in my life, > and I'd like to make a wee web service: I've heard some > abbreviations, but I don't really know what they mean. > > I've got a function (possibly the identity, possibly const "", > who knows?) > > ?assistant :: String -> String > > and I want to make a webpage with an edit box and a submit > button. If I press the submit button with the edit box > containing string s, I'd like the page to reload with the > edit box reset to (assistant s). > > Will I need to ask systems support to let me install some > haskelly sort of web server? Looks likely, I suppose. > > In general, what's an easy way to put a web front end on > functionality implemented in Haskell? > > Hoping this isn't a hard question > > Conor > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From paul at cogito.org.uk Fri Jun 5 17:58:27 2009 From: paul at cogito.org.uk (Paul Johnson) Date: Fri Jun 5 17:42:32 2009 Subject: [Haskell-cafe] Is it possible to do type-level arithmetic without UndeciableInstances? In-Reply-To: <20090605213949.GA22976@rwbarton.mit.edu> References: <2f9b2d30906051358l1a34eeecx4eca0c1aeab4d26e@mail.gmail.com> <20090605213949.GA22976@rwbarton.mit.edu> Message-ID: <4A299503.3040605@cogito.org.uk> This is a bit beyond my normal level of expertise, but if I understand it correctly the type checker is normally limited to type functions that are "primitive recursive" (http://en.wikipedia.org/wiki/Primitive_recursive_function). This means that they are guaranteed to terminate, but on the other hand the resulting language is not Turing complete. Setting UndecidableInstances lifts the Primitive Recursive restriction, making the type checker Turing Complete, but also creating the potential for endless loops. So yes, you can do type arithmetic without UndecidableInstances, provided you limit yourself to the Primitive Recursive axioms. The Wikipedia page lists them, and turning them into Haskell type classes shouldn't be more than a few milli-Olegs. Paul. From mhamro at gmail.com Fri Jun 5 17:58:45 2009 From: mhamro at gmail.com (MH) Date: Fri Jun 5 17:42:40 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: <4A297980.60509@cs.au.dk> References: <4A297980.60509@cs.au.dk> Message-ID: <648da0750906051458j5c37622cu2083fdeb66113288@mail.gmail.com> I actually meant data Container a = Many a(Container a) but here is what I don't understand (fyi, I am a beginner) how can you construct this container? I can do let a = Many "somestring" - and I will get back a function but I can not do let a = Many 'a' "somestring" - because the second param is not (Container a) type. let a = Many 'a' (Container ['a','a']) - doesn't work either because Container is a type not a constructor (right or I am missing something?). So I have two questions: 1. When I do let b = Many "somestring" , I get :t b b :: Container[Char] -> Container[Char] what is it and why I am allowed to pass just one parameter to Many (and how can I use it)? 2. How can you construct that container? data Container a = Many a(Container a) let a = ???? On Fri, Jun 5, 2009 at 4:01 PM, Tillmann Rendel wrote: > Hi, > > please write to the whole list, not just me. There are a lot of people > around who can help you. > > MH wrote: >> >> Rendel do you mind to explain to me how Container a = Many a >> (Container [a]) prevents user from creating an empty list? >> I did try the following: >> let a = Many "string" >> a :: Container [Char] -> Container [Char] >> let b = Many [] >> b :: forall a. Container [a] -> Container [a] >> >> but I can not understand what is the difference. > > You cannot prevent users from creating an empty list, because lists are > already defined in the Haskell prelude, and you cannot change that > definition. But you can define your own datatype Container which prevents > users from creating empty containers. > > Your datatype > > ?data Container a = Many a (Container [a]) > > is quite complicated, because you have (Container a) on the left hand side > of the equation, but (Container [a]) on the right hand side. Is that on > purpose? > > Anyway, your Container has the property that a (Container a) is never empty, > because it always contains at least one value of type a, namely the first > parameter of Many. To see that, we can write a function which extracts that > element: > > ?getContainerElement :: Container a -> a > ?getContainerElement (Many element something) = element > > It is not possible to write such a function for ordinary lists without > calling error or entering a nonterminating loop: > > ?getListElement :: [a] -> a > ?getListElement (element : something) = element > ?getListElement [] = error "no element around :(" > > So ordinary lists can be empty, but your Containers can't. > > ?Tillmann > From ketil at malde.org Fri Jun 5 18:10:50 2009 From: ketil at malde.org (Ketil Malde) Date: Fri Jun 5 17:54:18 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: <648da0750906051458j5c37622cu2083fdeb66113288@mail.gmail.com> (MH's message of "Fri\, 5 Jun 2009 17\:58\:45 -0400") References: <4A297980.60509@cs.au.dk> <648da0750906051458j5c37622cu2083fdeb66113288@mail.gmail.com> Message-ID: <87d49imivp.fsf@malde.org> MH writes: > data Container a = Many a(Container a) > but here is what I don't understand (fyi, I am a beginner) how can you > construct this container? I can do > let a = Many "somestring" - and I will get back a function but I can not do > let a = Many 'a' "somestring" - because the second param is not > (Container a) type. Right, so you need to pass a 'Container a' for that parameter. > let a = Many 'a' (Container ['a','a']) - doesn't work either because > Container is a type not a constructor (right or I am missing > something?). It doesn't work because the Container parameter must be of the same type. The parameters here are Char (due to the 'a' as the first parameter to Many), and [Char] (due to the ['a','a'] given as parameter to the Container parameter. These are not the same, so it fails. > So I have two questions: > 1. When I do > let b = Many "somestring" , I get > :t b > b :: Container[Char] -> Container[Char] > what is it and why I am allowed to pass just one parameter to Many > (and how can I use it)? This is just partial application. Pass one more parameter to build the whole thing. > 2. How can you construct that container? > data Container a = Many a(Container a) > let a = ???? Well you need a 'Container a' to do it. So you can do for instance: let a = Container 'x' a or let b = Conainer 'y' undefined -k -- If I haven't seen further, it is by standing in the footprints of giants From dagit at codersbase.com Fri Jun 5 18:13:08 2009 From: dagit at codersbase.com (Jason Dagit) Date: Fri Jun 5 17:56:59 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: <648da0750906051458j5c37622cu2083fdeb66113288@mail.gmail.com> References: <4A297980.60509@cs.au.dk> <648da0750906051458j5c37622cu2083fdeb66113288@mail.gmail.com> Message-ID: On Fri, Jun 5, 2009 at 2:58 PM, MH wrote: > I actually meant > > data Container a = Many a(Container a) > > but here is what I don't understand (fyi, I am a beginner) how can you > construct this container? I can do I think I saw the above definition described as a coalgebra or codata: http://blog.sigfpe.com/2007/07/data-and-codata.html Basically, that list has to always be infinite. > > > let a = Many "somestring" - and I will get back a function but I can not do > let a = Many 'a' "somestring" - because the second param is not > (Container a) type. > let a = Many 'a' (Container ['a','a']) - doesn't work either because > Container is a type not a constructor (right or I am missing > something?). > > So I have two questions: > 1. When I do > let b = Many "somestring" , I get > :t b > b :: Container[Char] -> Container[Char] > what is it and why I am allowed to pass just one parameter to Many > (and how can I use it)? > > 2. How can you construct that container? > data Container a = Many a(Container a) > let a = ???? > Check that link above for answers to some of your questions. I think that basically you want a different type: data NonEmptyList a = JustOne a | MoreThanOne a (NonEmptyList a) This is just the normal list definition with a small change, if you think of the normal list as being defined in this (pseudo) code: data [a] = [] | a : [a] I've just made it so that the "empty" list has at least one. I hope that helps, Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090605/7483a157/attachment.html From lrpalmer at gmail.com Fri Jun 5 18:36:12 2009 From: lrpalmer at gmail.com (Luke Palmer) Date: Fri Jun 5 18:20:01 2009 Subject: [Haskell-cafe] Re: Non Empty List? In-Reply-To: References: <4A297980.60509@cs.au.dk> <648da0750906051458j5c37622cu2083fdeb66113288@mail.gmail.com> Message-ID: <7ca3f0160906051536l65ea3efemf8e5e317a557a248@mail.gmail.com> On Fri, Jun 5, 2009 at 4:13 PM, Jason Dagit wrote: > > > On Fri, Jun 5, 2009 at 2:58 PM, MH wrote: > >> I actually meant >> >> data Container a = Many a(Container a) >> >> but here is what I don't understand (fyi, I am a beginner) how can you >> construct this container? I can do > > > I think I saw the above definition described as a coalgebra or codata: > http://blog.sigfpe.com/2007/07/data-and-codata.html > > Basically, that list has to always be infinite. > > >> >> >> let a = Many "somestring" - and I will get back a function but I can not >> do >> let a = Many 'a' "somestring" - because the second param is not >> (Container a) type. >> let a = Many 'a' (Container ['a','a']) - doesn't work either because >> Container is a type not a constructor (right or I am missing >> something?). >> >> So I have two questions: >> 1. When I do >> let b = Many "somestring" , I get >> :t b >> b :: Container[Char] -> Container[Char] >> what is it and why I am allowed to pass just one parameter to Many >> (and how can I use it)? >> >> 2. How can you construct that container? >> data Container a = Many a(Container a) >> let a = ???? >> > > Check that link above for answers to some of your questions. > > I think that basically you want a different type: > data NonEmptyList a = JustOne a | MoreThanOne a (NonEmptyList a) > I am still not sure why so much attention is being given to the recursive version. I find the most elegant and useful to be this simple one: data NonEmpty a = NonEmpty a [a] With the obligatory conversions: toList (NonEmpty x xs) = x:xs fromList [] = Nothing fromList (x:xs) = Just (NonEmpty x xs) Luke -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090605/8b363951/attachment.html From wren at freegeek.org Fri Jun 5 19:38:17 2009 From: wren at freegeek.org (wren ng thornton) Date: Fri Jun 5 19:22:07 2009 Subject: [Haskell-cafe] Monad transformer responsibilities In-Reply-To: <4A28EB38.3050604@van.steenbergen.nl> References: <4A28EB38.3050604@van.steenbergen.nl> Message-ID: <4A29AC69.90103@freegeek.org> Martijn van Steenbergen wrote: > Hello, > > Suppose I have two projects: 1) one that defines a monad transformer and > an accompanying type class that captures my monad-specific operations > and 2) one that uses the other project, combining the monad transformer > with, say, Parsec. > > Now while writing my Parsec parser I want to use my monad transformer > operations without using lift: I need an instance MyMonadT Parsec. Where > should this instance go? I can think of three answers, all unsatisfactory: > > 1) For obvious reasons it shouldn't go in the Parsec package. > > 2) For pretty much the same reasons it shouldn't go in my monad > transformer package, either. Also, it is undesirable to add a dependency > on Parsec just for this instance, and the package should not have to > know about the projects that are going to use it. > > 3) If I put it in the second project it is an orphan instance, which is > undesirable for well-known reasons. > > What is the best solution? 4) Define a newtype of MyMonadT Parsec and declare instances of MyMonad and Parsec for it. Yes, I know Parsec is (an alias for) a data type, not a type class. But for the general problem, using newtype wrappers is often the best solution when it's possible. This is one of the reasons why it's good to define type classes for specialty monads rather than hard-wiring the types of functions to use the one concrete instance. (For instance, this is one of the things that rocks about the LogicT library; you can add a StateT on top of a MonadLogic and it all works great.) For the actual case of Parsec, you could try defining a GenParser class and giving it all the combinators as methods, but that's a good deal of work and may not scale to your task. -- Live well, ~wren From newsham at lava.net Fri Jun 5 21:14:47 2009 From: newsham at lava.net (Tim Newsham) Date: Fri Jun 5 20:58:38 2009 Subject: [Haskell-cafe] Pike's Newsqueak talk Message-ID: I just watched http://video.google.com/videoplay?docid=810232012617965344 It's a great talk that is suprisingly relevant to Haskell programming (although at first blush it looks a bit unrelated). (It refs a lot of older work that actually led me to Haskell in the first place by way of McIlroy's haskell power-series paper). Anyway, I thought it would be of general interest. A lot of the progrms he discusses are a lot more elegant in pure Haskell code (ie. prime number sieve, power series), but his language also supports an interesting imperative primitive that lets you pick the first available value from a set of channels which isn't available in pure Haskell expressions. Has anyone implemented a primitive like this for Haskell? Tim Newsham http://www.thenewsh.com/~newsham/ From aslatter at gmail.com Fri Jun 5 21:45:04 2009 From: aslatter at gmail.com (Antoine Latter) Date: Fri Jun 5 21:28:53 2009 Subject: [Haskell-cafe] Monad transformer responsibilities In-Reply-To: <4A29AC69.90103@freegeek.org> References: <4A28EB38.3050604@van.steenbergen.nl> <4A29AC69.90103@freegeek.org> Message-ID: <694519c50906051845p229e03car595e847613d8f0c4@mail.gmail.com> On Fri, Jun 5, 2009 at 6:38 PM, wren ng thornton wrote: > > 4) Define a newtype of MyMonadT Parsec and declare instances of MyMonad and > Parsec for it. > > Yes, I know Parsec is (an alias for) a data type, not a type class. But for > the general problem, using newtype wrappers is often the best solution when > it's possible. This is one of the reasons why it's good to define type > classes for specialty monads rather than hard-wiring the types of functions > to use the one concrete instance. (For instance, this is one of the things > that rocks about the LogicT library; you can add a StateT on top of a > MonadLogic and it all works great.) > > > For the actual case of Parsec, you could try defining a GenParser class and > giving it all the combinators as methods, but that's a good deal of work and > may not scale to your task. > If you need a head start: http://community.haskell.org/~aslatter/code/parsec/with_class/ I'm not too happy with what turned out to be the class methods. But I'd need to retire certain parts of the Parsec API to clean it up. Antoine From ccshan at post.harvard.edu Fri Jun 5 22:04:38 2009 From: ccshan at post.harvard.edu (Chung-chieh Shan) Date: Fri Jun 5 21:48:49 2009 Subject: [Haskell-cafe] Re: Pike's Newsqueak talk References: Message-ID: Tim Newsham wrote in article in gmane.comp.lang.haskell.cafe: > his language also > supports an interesting imperative primitive that lets you pick the first > available value from a set of channels which isn't available in pure > Haskell expressions. Has anyone implemented a primitive like this for > Haskell? Could it be the "amb" described at http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice/ http://conal.net/blog/posts/smarter-termination-for-thread-racing/ ? -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig We want our revolution, and we want it now! -- Marat/Sade We want our revolution, and we'll take it at such time as you've gotten around to delivering it -- Haskell programmer From phunge0 at hotmail.com Fri Jun 5 22:08:13 2009 From: phunge0 at hotmail.com (Brian Bloniarz) Date: Fri Jun 5 21:52:04 2009 Subject: [Haskell-cafe] A small puzzle: inTwain as function of foldr In-Reply-To: <20090605143502.093ba46e.Malcolm.Wallace@cs.york.ac.uk> References: <4A27D8A6.1090605@van.steenbergen.nl> <4A28FFB2.2000503@van.steenbergen.nl> <20090605143502.093ba46e.Malcolm.Wallace@cs.york.ac.uk> Message-ID: Hi all, Malcom Wallace wrote: > Martijn van Steenbergen wrote: > > > But this uses length and init and last all of which are recursive > > functions. I consider that cheating: only foldr may do the recursion. > > I think the key is to pick your intermediate data-structure wisely. A > pair of queues would be my choice. I think this is the essentially the same solution as the difference-list solution I posted before -- same approach, different datastructures. > > unQ (Q begin end) = begin ++ reverse end This might be cheating too? This solution recurses over the input only once, but then you need to recurse over the queue to convert it to a list. The difference list solution manages to only recurse once, I think. Here's the same solution I posted, with all the difference-list operations inlined: > import Control.Arrow > > start = (Nothing, (id, id)) > > iter (Nothing, (r1, r2)) x = (Just x, (r1, r2)) > iter (Just y, (r1, r2)) x = > case r2 [] of > [] -> (Nothing, (\t -> y:t, \t -> x:t)) > r:_ -> let r1' = \t -> r1 (r : t) > r2' = \t -> tail (r2 (y:x:t)) > in (Nothing, (r1', r2')) > > inTwain :: [a] -> ([a], [a]) > inTwain = (($[]) *** ($[])) . snd . foldl iter start As you can see, it's building up nested lambdas, adding a new lambda to r1 and r2 on each iteration of the fold. And, on each iteration, it's also applying the function it's built. Basically, it's using the program stack as it's intermediate datastructure. Ugly and inefficient yes, but recursion-free as far as I can see. Thanks, -Brian P.S. The "walk the list at 2 speeds" trick is very slick. _________________________________________________________________ Windows Live?: Keep your life in sync. http://windowslive.com/explore?ocid=TXT_TAGLM_WL_BR_life_in_synch_062009 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090605/5ad3ab9b/attachment.html From newsham at lava.net Fri Jun 5 22:10:08 2009 From: newsham at lava.net (Tim Newsham) Date: Fri Jun 5 21:53:59 2009 Subject: [Haskell-cafe] Re: Pike's Newsqueak talk In-Reply-To: References: Message-ID: > Tim Newsham wrote in article in gmane.comp.lang.haskell.cafe: >> his language also >> supports an interesting imperative primitive that lets you pick the first >> available value from a set of channels which isn't available in pure >> Haskell expressions. Has anyone implemented a primitive like this for >> Haskell? > > Could it be the "amb" described at > http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice/ > http://conal.net/blog/posts/smarter-termination-for-thread-racing/ > ? It reminds me a little of unamb but is different. Unamb is pure and picks the first computed value of several consistent computations. The select operator picks the first available value from a set of diff channels, some of which may have diff types and so is definitely not pure. Tim Newsham http://www.thenewsh.com/~newsham/ From mle+hs at mega-nerd.com Fri Jun 5 22:56:14 2009 From: mle+hs at mega-nerd.com (Erik de Castro Lopo) Date: Fri Jun 5 22:40:20 2009 Subject: [Haskell-cafe] Haddock : parse error on input `{-# UNPACK' Message-ID: <20090606125614.93aca46d.mle+hs@mega-nerd.com> Hi all, I'm trying to compile the binary-strict module from hackage and I'm getting the exact same error as in the hackage build log: http://hackage.haskell.org/packages/archive/binary-strict/0.4.2/logs/failure/ghc-6.10 src/Data/Binary/Strict/IncrementalGet.hs:106:11: parse error on input `{-# UNPACK' Is this a bug? Is there any way to work around it? TIA, Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/ From derek.a.elkins at gmail.com Fri Jun 5 23:32:55 2009 From: derek.a.elkins at gmail.com (Derek Elkins) Date: Fri Jun 5 23:16:44 2009 Subject: [Haskell-cafe] Pike's Newsqueak talk In-Reply-To: References: Message-ID: <61f84eff0906052032m70a9b2d4sa36b15d22ba950a4@mail.gmail.com> On Fri, Jun 5, 2009 at 8:14 PM, Tim Newsham wrote: > I just watched http://video.google.com/videoplay?docid=810232012617965344 > > It's a great talk that is suprisingly relevant to Haskell programming > (although at first blush it looks a bit unrelated). (It refs a lot of older > work that actually led me to Haskell in the first place by way of McIlroy's > haskell power-series paper). ?Anyway, I thought it would be of general > interest. > > A lot of the progrms he discusses are a lot more elegant in pure Haskell > code (ie. prime number sieve, power series), but his language also supports > an interesting imperative primitive that lets you pick the first available > value from a set of channels which isn't available in pure Haskell > expressions. ?Has anyone implemented a primitive like this for Haskell? Traditionally and as demonstrated in McIlroy's power series paper, channels are modelled as streams. I'm pretty sure the primitive you are looking for is (equivalent to) the non-deterministic merge, which is, again, the traditional way of adding such features (see, e.g. SICP). It is of course an impure operation and thus not implementable in pure Haskell and not a pure expression in Haskell. It is implemented in Control.Concurrent as mergeIO and nmergeIO. http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent.html#7 And yes, Rob Pike's work is great. I particularly like the concurrent windowing system stuff and would like to implement something like it in (Concurrent) Haskell. From cgibbard at gmail.com Sat Jun 6 01:21:45 2009 From: cgibbard at gmail.com (Cale Gibbard) Date: Sat Jun 6 01:05:35 2009 Subject: [Haskell-cafe] nubBy seems broken in recent GHCs Message-ID: <89ca3d1f0906052221k62c12d44ha92bcab4ede4d2f2@mail.gmail.com> According to the Report: nubBy :: (a -> a -> Bool) -> [a] -> [a] nubBy eq [] = [] nubBy eq (x:xs) = x : nubBy eq (filter (\y -> not (eq x y)) xs) Hence, we should have that nubBy (<) (1:2:[]) = 1 : nubBy (<) (filter (\y -> not (1 < y)) (2:[])) = 1 : nubBy (<) [] = 1 : [] However in ghc-6.10.3: Prelude Data.List> nubBy (<) [1,2] [1,2] The order of the parameters to the function which is passed to nubBy is *important* since the function might not be an equivalence relation. nubBy is more generally useful for sieving even when the relation is not symmetric. groupBy, for a similar reason, has applications for grouping beyond those provided by equivalence relations, and I think we should be able to rely on its behaviour. Moreover, I contend that the Report's order is more sensible, since the parameters to the relation stay in the left-to-right order in which they occurred in the list. It would be good if this could get fixed for 6.10.4. - Cale PS: There is actually another implementation of groupBy which would *also* be useful to have, but which is exactly the same for equivalence relations as groupBy, and it compares adjacent elements rather than the first element of a group with successive ones. (groupByAdjacent or something would be a reasonable name.) An implementation of it can be found here: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5595 From newhoggy at gmail.com Sat Jun 6 02:07:20 2009 From: newhoggy at gmail.com (John Ky) Date: Sat Jun 6 01:51:10 2009 Subject: [Haskell-cafe] Record initialise question (RESOLVED) Message-ID: On Fri, Jun 5, 2009 at 8:05 PM, Martijn van Steenbergen < martijn@van.steenbergen.nl> wrote: > Hi John, > > John Ky wrote: > >> > full = do >> > let myOrder = init -- [1] >> > { item = Just init >> > { itemId = "Something" >> > } >> > , operation = Just Buy >> > } >> > putStrLn $ show myOrder >> > return () >> >> Where initOrder and initItem are both replaced with just 'init' and the >> compiler works out from the context (ie. the type of the field) what the >> types are supposed to be and therefore the actual init function to call? >> > > Sure! This is one of the simplest forms of overloading. Here's a small > example: > > data Circle = Circle { center :: (Float, Float), radius :: Float } >> data WrapCircle = WrapCircle { circle :: Circle } >> >> class Ini a where >> ini :: a >> >> instance Ini Circle where >> ini = Circle { center = (0, 0), radius = 1 } >> >> exampleCircle :: WrapCircle >> exampleCircle = WrapCircle { circle = ini { radius = 2 } } >> > > Hope this helps! > > Martijn. > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090606/b6d94d3c/attachment.html From newhoggy at gmail.com Sat Jun 6 02:13:41 2009 From: newhoggy at gmail.com (John Ky) Date: Sat Jun 6 01:57:29 2009 Subject: [Haskell-cafe] Conversion from string to array Message-ID: Hi Haskell Cafe, I'm trying to send stuff over UDP. To do that, I've written a test program that sends strings across. That was fine, but I wanted to send binary data too. So I tried that only to find I am having difficulty putting together some binary data. For examples take the fromHex function in the following code. It is supposed to convert from a Hexadecimal string to a list of bytes, but I am having trouble coercing the integer types to the size I want. Is this the right way to do it? Cheers, -John > import Data.Bits > import Data.Char > import Data.Word > import System.Environment > import XStream.Tsmr.Client > data CmdLineOptions = CmdLineOptions > { optionHelp :: Bool > , optionVersion :: Bool > , optionPort :: String > , optionMessage :: String > , optionInvalids :: [String] > } > deriving (Eq, Show) > initCmdLineOptions = CmdLineOptions > { optionHelp = False > , optionVersion = False > , optionPort = "1234" > , optionMessage = "" > } > parseArgs :: [String] -> CmdLineOptions > parseArgs [] = initCmdLineOptions > parseArgs ("--port":port:xs) = (parseArgs xs) { optionPort = port } > parseArgs ("--help":xs) = (parseArgs xs) { optionHelp = True } > parseArgs ("--version":xs) = (parseArgs xs) { optionVersion = True } > parseArgs (('-':opt):xs) = let option = (parseArgs xs) in > option { optionInvalids = ('-':opt):optionInvalids option } > parseArgs (message:xs) = (parseArgs xs) { optionMessage = message } > printUsage = do > putStrLn "Usage: udp-server.lhs [options] " > putStrLn "" > putStrLn "Options:" > putStrLn " --help Get help information." > putStrLn " --vesion Get version information." > putStrLn " --port n The port number to listen on." > putStrLn "" > putStrLn "Message:" > putStrLn " The message to send." > putStrLn "" > printVersion = do > putStrLn "Version." > fromHex :: String -> [Word8] > fromHex [] = [] > fromHex (u:l:xs) = (hexU .|. hexL):fromHex xs > where > hexU = (fromInteger $ hexValue u) :: Word8 > hexL = (fromInteger $ hexValue l) :: Int > hexValue c > | '0' <= c && c <= '9' = ord c - ord '0' > | 'a' <= c && c <= 'z' = ord c - ord 'a' + 10 > run port message = do > h <- openlog "localhost" port "udp-client.lhs" > syslog h (fromHex message) > main = do > args <- getArgs > let options = parseArgs args > let port = optionPort options > let message = optionMessage options > if optionHelp options > then printUsage > else if optionVersion options > then printVersion > else do > putStrLn ("Starting UDP listener on port: " ++ port) > run port message -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090606/1b2f3cb6/attachment.html From semanticphilosopher at googlemail.com Sat Jun 6 02:38:34 2009 From: semanticphilosopher at googlemail.com (Neil Davies) Date: Sat Jun 6 02:22:27 2009 Subject: [Haskell-cafe] Conversion from string to array In-Reply-To: References: Message-ID: <5FC7F857-A11D-4E08-B5FA-9211247BCEE5@gmail.com> Look at Data.Binary (binary package) It will marshall and unmarshall data types for you. If you don't like its binary encoding you can dive in there and use the same principles Cheers Neil On 6 Jun 2009, at 07:13, John Ky wrote: > Hi Haskell Cafe, > > I'm trying to send stuff over UDP. To do that, I've written a test > program that sends strings across. That was fine, but I wanted to > send binary data too. So I tried that only to find I am having > difficulty putting together some binary data. For examples take the > fromHex function in the following code. > It is supposed to convert from a Hexadecimal string to a list of > bytes, but I am having trouble coercing the integer types to the > size I want. > > Is this the right way to do it? > > Cheers, > > -John > > > import Data.Bits > > import Data.Char > > import Data.Word > > import System.Environment > > import XStream.Tsmr.Client > > > data CmdLineOptions = CmdLineOptions > > { optionHelp :: Bool > > , optionVersion :: Bool > > , optionPort :: String > > , optionMessage :: String > > , optionInvalids :: [String] > > } > > deriving (Eq, Show) > > > initCmdLineOptions = CmdLineOptions > > { optionHelp = False > > , optionVersion = False > > , optionPort = "1234" > > , optionMessage = "" > > } > > > parseArgs :: [String] -> CmdLineOptions > > parseArgs [] = initCmdLineOptions > > parseArgs ("--port":port:xs) = (parseArgs xs) { optionPort = port } > > parseArgs ("--help":xs) = (parseArgs xs) { optionHelp = True } > > parseArgs ("--version":xs) = (parseArgs xs) { optionVersion = > True } > > parseArgs (('-':opt):xs) = let option = (parseArgs xs) in > > option { optionInvalids = ('-':opt):optionInvalids option } > > parseArgs (message:xs) = (parseArgs xs) { optionMessage = message } > > > printUsage = do > > putStrLn "Usage: udp-server.lhs [options] " > > putStrLn "" > > putStrLn "Options:" > > putStrLn " --help Get help information." > > putStrLn " --vesion Get version information." > > putStrLn " --port n The port number to listen on." > > putStrLn "" > > putStrLn "Message:" > > putStrLn " The message to send." > > putStrLn "" > > > printVersion = do > > putStrLn "Version." > > > fromHex :: String -> [Word8] > > fromHex [] = [] > > fromHex (u:l:xs) = (hexU .|. hexL):fromHex xs > > where > > hexU = (fromInteger $ hexValue u) :: Word8 > > hexL = (fromInteger $ hexValue l) :: Int > > hexValue c > > | '0' <= c && c <= '9' = ord c - ord '0' > > | 'a' <= c && c <= 'z' = ord c - ord 'a' + 10 > > > > run port message = do > > h <- openlog "localhost" port "udp-client.lhs" > > syslog h (fromHex message) > > > main = do > > args <- getArgs > > let options = parseArgs args > > let port = optionPort options > > let message = optionMessage options > > if optionHelp options > > then printUsage > > else if optionVersion options > > then printVersion > > else do > > putStrLn ("Starting UDP listener on port: " ++ port) > > run port message > > > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From newhoggy at gmail.com Sat Jun 6 03:48:19 2009 From: newhoggy at gmail.com (John Ky) Date: Sat Jun 6 03:32:08 2009 Subject: [Haskell-cafe] Why are these record accesses ambiguous Message-ID: Hi Haskell Cafe, In the following code, I get an error saying Ambiguous occurrence `x'. Why can't Haskell work out which x to call based on the type of getA? Thanks -John #!/usr/bin/env runhaskell > {-# LANGUAGE DisambiguateRecordFields #-} > import A > import B > > main = do > let xx = getA > putStrLn $ show x xx ---------------------- module A where data TypeA = TypeA { a :: Int , x :: Int } getA = TypeA { a = 1, x = 2 } ------------------------- module B where data TypeB = TypeB { b :: Int , x :: Int } getB = TypeB { b = 1, x = 3 } -------------------------- ./test.lhs:8:21: Ambiguous occurrence `x' It could refer to either `A.x', imported from A at ./test.lhs:3:2-9 (defined at A.hs:5:5) or `B.x', imported from B at ./test.lhs:4:2-9 (defined at B.hs:5:5) -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090606/a16d8d47/attachment.html From miguelimo38 at yandex.ru Sat Jun 6 04:02:00 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Sat Jun 6 03:45:53 2009 Subject: [Haskell-cafe] Why are these record accesses ambiguous In-Reply-To: References: Message-ID: <41F01383-2F0A-4247-A3DE-81ED0FF749BC@yandex.ru> Probably because you don't apply "x" to "xx" anywhere? On 6 Jun 2009, at 11:48, John Ky wrote: > Hi Haskell Cafe, > > In the following code, I get an error saying Ambiguous occurrence > `x'. Why can't Haskell work out which x to call based on the type > of getA? > > Thanks > > -John > > #!/usr/bin/env runhaskell > > > {-# LANGUAGE DisambiguateRecordFields #-} > > import A > > import B > > > > main = do > > let xx = getA > > putStrLn $ show x xx > > ---------------------- > > module A where > > data TypeA = TypeA > { a :: Int > , x :: Int > } > > getA = TypeA { a = 1, x = 2 } > > ------------------------- > > module B where > > data TypeB = TypeB > { b :: Int > , x :: Int > } > > getB = TypeB { b = 1, x = 3 } > > -------------------------- > > ./test.lhs:8:21: > Ambiguous occurrence `x' > It could refer to either `A.x', imported from A at ./test.lhs: > 3:2-9 > (defined at A.hs:5:5) > or `B.x', imported from B at ./test.lhs: > 4:2-9 > (defined at B.hs:5:5) > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From lrpalmer at gmail.com Sat Jun 6 04:41:23 2009 From: lrpalmer at gmail.com (Luke Palmer) Date: Sat Jun 6 04:25:22 2009 Subject: [Haskell-cafe] Why are these record accesses ambiguous In-Reply-To: References: Message-ID: <7ca3f0160906060141g69f0ce6eu1e19d0485fcfa7aa@mail.gmail.com> On Sat, Jun 6, 2009 at 1:48 AM, John Ky wrote: > Hi Haskell Cafe, > > In the following code, I get an error saying Ambiguous occurrence `x'. Why > can't Haskell work out which x to call based on the type of getA? > > Thanks > > -John > > #!/usr/bin/env runhaskell > > > {-# LANGUAGE DisambiguateRecordFields #-} > > import A > > import B > > > > main = do > > let xx = getA > > putStrLn $ show x xx This is parsed as two arguments passed to the show function (which only takes one argument). putStrLn $ show (x xx) Or because putStrLn . show = print; print $ x xx > > > ---------------------- > > module A where > > data TypeA = TypeA > { a :: Int > , x :: Int > } > > getA = TypeA { a = 1, x = 2 } > > ------------------------- > > module B where > > data TypeB = TypeB > { b :: Int > , x :: Int > } > > getB = TypeB { b = 1, x = 3 } > > -------------------------- > > ./test.lhs:8:21: > Ambiguous occurrence `x' > It could refer to either `A.x', imported from A at ./test.lhs:3:2-9 > (defined at A.hs:5:5) > or `B.x', imported from B at ./test.lhs:4:2-9 > (defined at B.hs:5:5) > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090606/e57ac1ed/attachment.html From ats at offog.org Sat Jun 6 05:13:55 2009 From: ats at offog.org (Adam Sampson) Date: Sat Jun 6 04:57:45 2009 Subject: [Haskell-cafe] Pike's Newsqueak talk In-Reply-To: (Tim Newsham's message of "Fri\, 5 Jun 2009 15\:14\:47 -1000 \(HST\)") References: Message-ID: Tim Newsham writes: > Has anyone implemented a primitive like this for Haskell? This is the CSP external choice operator; it's often called "select" or "alt" in CSP-inspired languages. Neil Brown's CHP library provides CSP programming facilities in Haskell, including a <-> choice operator: http://www.cs.kent.ac.uk/projects/ofa/chp/ -- Adam Sampson From newhoggy at gmail.com Sat Jun 6 06:06:30 2009 From: newhoggy at gmail.com (John Ky) Date: Sat Jun 6 05:50:19 2009 Subject: [Haskell-cafe] Why are these record accesses ambiguous In-Reply-To: <7ca3f0160906060141g69f0ce6eu1e19d0485fcfa7aa@mail.gmail.com> References: <7ca3f0160906060141g69f0ce6eu1e19d0485fcfa7aa@mail.gmail.com> Message-ID: Hi Luke, You're right. My code had a typo. Unfortunately, I still get the same error whichever way I do it. For example: > {-# LANGUAGE DisambiguateRecordFields #-} > import A > import B > > main = do > let xx = getA > print (x xx) and: #!/usr/bin/env runhaskell > {-# LANGUAGE DisambiguateRecordFields #-} > import A > import B > > main = do > let xx = getA > putStrLn $ show (x xx) both give me: test.lhs:8:22: Ambiguous occurrence `x' It could refer to either `A.x', imported from A at test.lhs:3:2-9 (defined at A.hs:5:5) or `B.x', imported from B at test.lhs:4:2-9 (defined at B.hs:5:5) Any ideas? $ ghc --version The Glorious Glasgow Haskell Compilation System, version 6.10.3 Thanks, -John On Sat, Jun 6, 2009 at 6:41 PM, Luke Palmer wrote: > On Sat, Jun 6, 2009 at 1:48 AM, John Ky wrote: > >> Hi Haskell Cafe, >> >> In the following code, I get an error saying Ambiguous occurrence `x'. >> Why can't Haskell work out which x to call based on the type of getA? >> >> Thanks >> >> -John >> >> #!/usr/bin/env runhaskell >> >> > {-# LANGUAGE DisambiguateRecordFields #-} >> > import A >> > import B >> > >> > main = do >> > let xx = getA >> > putStrLn $ show x xx > > > This is parsed as two arguments passed to the show function (which only > takes one argument). > > putStrLn $ show (x xx) > > Or because putStrLn . show = print; > > print $ x xx > > >> >> >> ---------------------- >> >> module A where >> >> data TypeA = TypeA >> { a :: Int >> , x :: Int >> } >> >> getA = TypeA { a = 1, x = 2 } >> >> ------------------------- >> >> module B where >> >> data TypeB = TypeB >> { b :: Int >> , x :: Int >> } >> >> getB = TypeB { b = 1, x = 3 } >> >> -------------------------- >> >> ./test.lhs:8:21: >> Ambiguous occurrence `x' >> It could refer to either `A.x', imported from A at ./test.lhs:3:2-9 >> (defined at A.hs:5:5) >> or `B.x', imported from B at ./test.lhs:4:2-9 >> (defined at B.hs:5:5) >> >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090606/6af6ae27/attachment-0001.html From jfredett at gmail.com Sat Jun 6 07:24:18 2009 From: jfredett at gmail.com (Joe Fredette) Date: Sat Jun 6 07:08:03 2009 Subject: [Haskell-cafe] Why are these record accesses ambiguous In-Reply-To: References: <7ca3f0160906060141g69f0ce6eu1e19d0485fcfa7aa@mail.gmail.com> Message-ID: <4A2A51E2.6070808@gmail.com> The error is because of the way records work in Haskell. Recall that a record is just sugar for the normal datatype syntax. Namely: data FooA a b c = FooA {getA :: a, getB:: b, getC :: c} can be accessed as either f (FooA a b c) = ... or f fooA = ... (getA fooA) ... etc That is, Record syntax just creates functions for each label that take a record and return the content of that label. eg getA :: FooA a b c -> a getA (FooA a _ _ ) = a ... So when you have two records with the same label in it: data Bar = Bar { badlabel :: Int } data Baz = Baz { badlabel :: String } even though they are not the same type, you end up with the following definitions: badlabel :: Bar -> Int badlabel :: Baz -> String this is a type error, one that is not trivially resolved. Thats where your problem is coming from, two fields both named `x` which result in this error. HTH, /Joe John Ky wrote: > Hi Luke, > > You're right. My code had a typo. Unfortunately, I still get the > same error whichever way I do it. > > For example: > > > {-# LANGUAGE DisambiguateRecordFields #-} > > import A > > import B > > > > main = do > > let xx = getA > > print (x xx) > > and: > > #!/usr/bin/env runhaskell > > > {-# LANGUAGE DisambiguateRecordFields #-} > > import A > > import B > > > > main = do > > let xx = getA > > putStrLn $ show (x xx) > > both give me: > > test.lhs:8:22: > Ambiguous occurrence `x' > It could refer to either `A.x', imported from A at test.lhs:3:2-9 > (defined at A.hs:5:5) > or `B.x', imported from B at test.lhs:4:2-9 > (defined at B.hs:5:5) > > Any ideas? > > $ ghc --version > The Glorious Glasgow Haskell Compilation System, version 6.10.3 > > Thanks, > > -John > > On Sat, Jun 6, 2009 at 6:41 PM, Luke Palmer > wrote: > > On Sat, Jun 6, 2009 at 1:48 AM, John Ky > wrote: > > Hi Haskell Cafe, > > In the following code, I get an error saying Ambiguous > occurrence `x'. Why can't Haskell work out which x to call > based on the type of getA? > > Thanks > > -John > > #!/usr/bin/env runhaskell > > > {-# LANGUAGE DisambiguateRecordFields #-} > > import A > > import B > > > > main = do > > let xx = getA > > putStrLn $ show x xx > > > This is parsed as two arguments passed to the show function (which > only takes one argument). > > putStrLn $ show (x xx) > > Or because putStrLn . show = print; > > print $ x xx > > > > > ---------------------- > > module A where > > data TypeA = TypeA > { a :: Int > , x :: Int > } > > getA = TypeA { a = 1, x = 2 } > > ------------------------- > > module B where > > data TypeB = TypeB > { b :: Int > , x :: Int > } > > getB = TypeB { b = 1, x = 3 } > > -------------------------- > > ./test.lhs:8:21: > Ambiguous occurrence `x' > It could refer to either `A.x', imported from A at > ./test.lhs:3:2-9 > (defined at A.hs:5:5) > or `B.x', imported from B at > ./test.lhs:4:2-9 > (defined at B.hs:5:5) > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > > > ------------------------------------------------------------------------ > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- A non-text attachment was scrubbed... Name: jfredett.vcf Type: text/x-vcard Size: 296 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090606/b648c8ed/jfredett.vcf From benjovi at gmx.net Sat Jun 6 07:32:36 2009 From: benjovi at gmx.net (Benedikt Huber) Date: Sat Jun 6 07:16:33 2009 Subject: [Haskell-cafe] Re: Why are these record accesses ambiguous In-Reply-To: References: <7ca3f0160906060141g69f0ce6eu1e19d0485fcfa7aa@mail.gmail.com> Message-ID: <4A2A53D4.8060008@gmx.net> Hi John, The record field disambiguation only works if you use the form > C{ field-name = variable } where C is a datatype constructor. In your example you have to write > let TypeA{ x = v } = getA > print v You're right, after type inference it is clear (for us) that x should mean A.x, but this kind of reasoning (disambiguate names based on the results of type inference) is not supported by ghc - and that's a good thing, in my opinion, as otherwise it would be incredibly hard to find the definition in scope. There was a long thread on cafe on this subject. cheers, benedikt John Ky schrieb: > Hi Luke, > > You're right. My code had a typo. Unfortunately, I still get the same > error whichever way I do it. > > For example: > > > {-# LANGUAGE DisambiguateRecordFields #-} > > import A > > import B > > > > main = do > > let xx = getA > > print (x xx) > > and: > > #!/usr/bin/env runhaskell > > > {-# LANGUAGE DisambiguateRecordFields #-} > > import A > > import B > > > > main = do > > let xx = getA > > putStrLn $ show (x xx) > > both give me: > > test.lhs:8:22: > Ambiguous occurrence `x' > It could refer to either `A.x', imported from A at test.lhs:3:2-9 > (defined at A.hs:5:5) > or `B.x', imported from B at test.lhs:4:2-9 > (defined at B.hs:5:5) > > Any ideas? > > $ ghc --version > The Glorious Glasgow Haskell Compilation System, version 6.10.3 > > Thanks, > > -John > > On Sat, Jun 6, 2009 at 6:41 PM, Luke Palmer > wrote: > > On Sat, Jun 6, 2009 at 1:48 AM, John Ky > wrote: > > Hi Haskell Cafe, > > In the following code, I get an error saying Ambiguous > occurrence `x'. Why can't Haskell work out which x to call > based on the type of getA? > > Thanks > > -John > > #!/usr/bin/env runhaskell > > > {-# LANGUAGE DisambiguateRecordFields #-} > > import A > > import B > > > > main = do > > let xx = getA > > putStrLn $ show x xx > > > This is parsed as two arguments passed to the show function (which > only takes one argument). > > putStrLn $ show (x xx) > > Or because putStrLn . show = print; > > print $ x xx > > > > > ---------------------- > > module A where > > data TypeA = TypeA > { a :: Int > , x :: Int > } > > getA = TypeA { a = 1, x = 2 } > > ------------------------- > > module B where > > data TypeB = TypeB > { b :: Int > , x :: Int > } > > getB = TypeB { b = 1, x = 3 } > > -------------------------- > > ./test.lhs:8:21: > Ambiguous occurrence `x' > It could refer to either `A.x', imported from A at > ./test.lhs:3:2-9 > (defined at A.hs:5:5) > or `B.x', imported from B at > ./test.lhs:4:2-9 > (defined at B.hs:5:5) > > > _______________________________________________ > 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 ccshan at post.harvard.edu Sat Jun 6 07:26:16 2009 From: ccshan at post.harvard.edu (Chung-chieh Shan) Date: Sat Jun 6 07:44:14 2009 Subject: [Haskell-cafe] Re: Pike's Newsqueak talk References: Message-ID: Tim Newsham wrote in article in gmane.comp.lang.haskell.cafe: > > Could it be the "amb" described at > > http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice/ > > http://conal.net/blog/posts/smarter-termination-for-thread-racing/ > > ? > It reminds me a little of unamb but is different. I agree, but could it be the "amb" described there? -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig We want our revolution, and we want it now! -- Marat/Sade We want our revolution, and we'll take it at such time as you've gotten around to delivering it -- Haskell programmer From dominic at steinitz.org Sat Jun 6 08:01:06 2009 From: dominic at steinitz.org (Dominic Steinitz) Date: Sat Jun 6 07:45:05 2009 Subject: [Haskell-cafe] Re: Haddock : parse error on input `{-# UNPACK' References: <20090606125614.93aca46d.mle+hs@mega-nerd.com> Message-ID: Erik de Castro Lopo mega-nerd.com> writes: > > src/Data/Binary/Strict/IncrementalGet.hs:106:11: > parse error on input `{-# UNPACK' > > Is this a bug? Is there any way to work around it? > This is a haddock error and I presume a bug in haddock. I don't know whether cabal installs things if haddock fails. You could do ghc-pkg list and see what's there. If it didn't install then you can install "by hand": 1. Extract the sources and in that directory: 2. runghc Setup.lhs configure 3. runghc Setup.lhs build 4. runghc Setup.lhs install You might want to do configure with --user - that's what cabal defaults to. Dominic From colin at colina.demon.co.uk Sat Jun 6 10:00:56 2009 From: colin at colina.demon.co.uk (Colin Paul Adams) Date: Sat Jun 6 09:44:47 2009 Subject: [Haskell-cafe] Can't install chp (confused by cabal yet again) Message-ID: I tried a cabal install chp: It complained that base was hidden. So I unpacked the archive, and tried installing using runhaskell Setup configure/build/install. Now I get (from install): Setup: You need to re-run the 'configure' command. The version of Cabal being used has changed (was Cabal-1.6.0.3, now Cabal-1.6.0.2). So I repeated the process and get the same message again. ghc version is 6.10.3 Also: cabal --version cabal-install version 0.6.2 using version 1.6.0.2 of the Cabal library Where does this 1-6.0.3 come from (Ghc HEAD perhaps?)? What can I do about it? -- Colin Adams Preston Lancashire From bertram.felgenhauer at googlemail.com Sat Jun 6 12:39:50 2009 From: bertram.felgenhauer at googlemail.com (Bertram Felgenhauer) Date: Sat Jun 6 12:23:43 2009 Subject: [Haskell-cafe] nubBy seems broken in recent GHCs In-Reply-To: <89ca3d1f0906052221k62c12d44ha92bcab4ede4d2f2@mail.gmail.com> References: <89ca3d1f0906052221k62c12d44ha92bcab4ede4d2f2@mail.gmail.com> Message-ID: <4a2a9bd9.12115e0a.77d5.5b0d@mx.google.com> Cale Gibbard wrote: > According to the Report: > > nubBy :: (a -> a -> Bool) -> [a] -> [a] > nubBy eq [] = [] > nubBy eq (x:xs) = x : nubBy eq (filter (\y -> not (eq x y)) xs) > > Hence, we should have that > > nubBy (<) (1:2:[]) > = 1 : nubBy (<) (filter (\y -> not (1 < y)) (2:[])) > = 1 : nubBy (<) [] > = 1 : [] > > However in ghc-6.10.3: > > Prelude Data.List> nubBy (<) [1,2] > [1,2] Interesting. This was changed in response to http://hackage.haskell.org/trac/ghc/ticket/2528 | Tue Sep 2 11:29:50 CEST 2008 Simon Marlow | * #2528: reverse the order of args to (==) in nubBy to match nub | This only makes a difference when the (==) definition is not | reflexive, but strictly speaking it does violate the report definition | of nubBy, so we should fix it. It turns out that 'elem' differs from the report version and should have its comparison reversed. Of course that would only ever matter for broken Eq instances. However, the report also states that the nubBy function may assume that the given predicate defines an equivalence relation. http://haskell.org/onlinereport/list.html#sect17.6 So I'm not sure there's anything to be fixed here - although backing out the above patch probably won't hurt anybody. Bertram From bluescreen303 at gmail.com Sat Jun 6 14:41:57 2009 From: bluescreen303 at gmail.com (Mathijs Kwik) Date: Sat Jun 6 14:25:53 2009 Subject: [Haskell-cafe] using phantom types to validate html Message-ID: <775c14610906061141j5bc89aa2h8908bfde25163178@mail.gmail.com> Hi all, Please have a look at http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2575#a2575 I wanted to use the typesystem to mandate businesslogic (in this case w3c validation rules). Thanks to some helpful people in #haskell I learned a bit about phantom types. Please let me know if I implemented them correctly. Also this little experiment raises some questions: The code becomes very verbose if there are more elements added or more rules to check. Since repetitive code can be a source of error, and hellish to maintain, I would like to know if there's some way to get this generated, or maybe there's some meta-programming stuff I don't know about. Another thing I can't figure out yet is how to do more advanced validation rules like "an html element cannot have 2 head sections", or (made up) "a span element isn't allowed to be a child(any level deep) of a p element". I think this would ask for an exponentially growing number of strange types and classes. Am I right? Just to be clear: this is just some practice to use the typesystem. I'm well aware that just using runtime validation checks will be a lot easier and clearer in most cases. Thanks, Mathijs From byorgey at seas.upenn.edu Sat Jun 6 14:51:35 2009 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Sat Jun 6 14:35:22 2009 Subject: [Haskell-cafe] Haskell Weekly News: Issue 120 - June 6, 2009 Message-ID: <20090606185134.GA3394@seas.upenn.edu> --------------------------------------------------------------------------- Haskell Weekly News http://sequence.complete.org/hwn/20090606 Issue 120 - June 06, 2009 --------------------------------------------------------------------------- Welcome to issue 120 of HWN, a newsletter covering developments in the [1]Haskell community. Sorry for the massive HWN, I missed last week so you're getting two for the price of one! Registration for [2]Hac phi is now open, be sure to register soon (register by June 15 to get a special hotel rate). Announcements Reminder: Haskell Implementers' Workshop CFT deadline in 2 weeks. Simon Marlow [3]reminded everyone to consider submitting a talk proposal for the Haskell Implementers' Workshop, to be held in conjunction with ICFP in Edinburgh, Scotland on 5 September. The deadline for submissions is a couple of weeks away (15 June); all that is needed is an abstract. storable-record. Henning Thielemann [4]announced [5]storable-record, a small package for simplified declaration of Storable instances for records. It may be used as an alternative to the [6]c2hs preprocessor. It was made possible by advanced applicative technology, a cutting edge LCM monoid and an incredible constructor power tower. Haskell Communities and Activities Report (16th ed., May 2009). Janis Voigtlaender [7]announced the availability of the [8]16th Haskell Communities and Activities Report. hledger 0.5 released. Simon Michael [9]announced the release of version 0.5 of [10]hledger, a (mostly) text-mode double-entry accounting tool that generates precise activity and balance reports from a plain text journal file. New repository and trac for haskell-src-exts. Niklas Broberg [11]announced some new infrastructure for the haskell-src-exts package, set up in preparation for his GSoC project. with the HSP packages, it's now old enough to be allowed to [12]live on its own. There is also a [13]bug tracker. Please help by reporting any bugs you come across, or by requesting new and cool features. bsd-sysctl 1.0.3. Maxime Henrion [14]announced the release of [15]bsd-sysctl 1.0.3, a package that provides a System.BSD.Sysctl module allowing access to the C sysctl(3) API. It should fully work on FreeBSD, NetBSD and Mac OS X platforms. multirec-binary. Sebastiaan Visser [16]announced the release of [17]multirec-binary, which allows generic derivation of Data.Binary instances using the [18]MultiRec library. notice for package authors. Duncan Coutts [19]announced that Hackage uploads will soon require an upper bound on the version of the base package and reject packages that omit it. This will hopefully result in less breakage the next time a new version of the base package is released. (Pre-) Announce: Data.GDS 0.1.0. Uwe Hollerbach [20](pre-) announced Data.GDS, a small module to write and (eventually) read GDS files, a classic format of the semiconductor industry. The module can currently generate GDS files with a fairly low-level interface; planned future versions (which will be uploaded to Hackage) will have a higher-level interface and be able to parse GDS files as well. new version of uu-parsinglib. S. Doaitse Swierstra [21]announced that a new version of the [22]uu-parsinglib library has been uploaded to hackage. It is now based on Control.Applicative where possible. Be warned that functions like some and many will be redefined in the future. Hac phi: Haskell hackathon in Philadelphia, July 24-26. Brent Yorgey [23]announced Hac phi, a Haskell hackathon/get-together to be held July 24-26 at the University of Pennsylvania in Philadelphia. The hackathon will officially kick off at 2:30 Friday afternoon, and go until 5pm on Sunday (with breaks for sleep, of course). Everyone is welcome---you do not have to be a Haskell guru to attend! Helping hack on someone else's project could be a great way to increase your Haskell-fu. If you plan on coming, please [24]register. There is a block of hotel rooms available at a special rate only until June 15, so register early! More details can be found on the [25]Hac phi wiki. Job for someone: make a VM image for GHC development. Simon Marlow [26]suggested a useful project for someone looking for something to do: create a VM image of a Linux system with a complete GHC development environment set up and ready to go. My attempt at Haskell USB. Mauricio [27]announced some [28]Haskell bindings to libusb, and gave another plug for his [29]bindings-common package, which makes it easier to generate Haskell bindings to low-level libraries. second alpha release of OSX haskell platform installer. Gregory Collins [30]announced a [31]second candidate release for the OSX Haskell Platform installer. Please try it out! Release Schedule for 2009.2.0.2. Don Stewart [32]announced the [33]release schedule for the next minor release of the 2009.2.0 branch of the Haskell Platform. The freeze for package changes will be Wednesday 1 July, and the release is scheduled for Monday 13th July. hscamwire, for IIDC1394 cameras. Frederick Ross [34]announced the release of [35]hscamwire 0.1, which provides a nice Haskellized layer over Camwire, a library to connect to IIDC1394 cameras (most scientific and industrial Firewire cameras) on Linux. Safe and generic printf with C-like format string. oleg [36]announced some code to implement a type-safe polyvariadic version of printf, which is also integrated with Show so that any showable type can be printed. A library for serial ports. Frederick Ross [37]announced the release of [38]serial-0.1, a library for line-oriented interaction with serial ports on POSIX compatible systems. HaL4: Haskell-Meeting in Germany, 12th June 2009. Janis Voigtlaender [39]reminded everyone of [40]Hal4, a German-language Haskell gathering to be held in Halle/Saale on June 12. There are already close to 50 registered participants, so expect a very lively meeting! Late registration still possible. wp-archivebot 0.1 - archive Wikipedia's external links in WebCite. Gwern Branwen [41]announced [42]wp-archivebot, a relatively simple little script which follows all the links in a RSS feed, combs the destination for http:// links, and submits them to [43]WebCite. memscript-0.0.0.2. Ki Yung Ahn [44]announced [45]memscript, a command line utility for memorizing scriptures or any other text. HSH 2.0.0. John Goerzen [46]announced the release of [47]version 2.0.0 of HSH, the Haskell shell scripting library. This version features a complete rewrite of the core using System.Process, a drastic reduction in code size and complexity, cross-platform support, and a simpler and more flexible API. atom-0.0.5. Tom Hawkins [48]announced version 0.5 of the [49]atom library, a DSL for embedded hard realtime applications. This version includes a few bug fixes and doc improvements. heap-1.0.0. Stephan Friedrichs [50]announced a rewrite of the heap package, [51]heap-1.0.0. It is not 100% compatible with version 0.6.0, but provides major improvements, including a better mechanism for instantiating min-, max-, min-prio- and max-prio-heaps, and faster {from,to}{Asc,Desc}List conversions. The Haskell Platform 2009.2.0.1. Don Stewart [52]announced the second release (2009.2.0.1) of the [53]Haskell Platform, a single, standard Haskell distribution for everyone. The specification, along with installers (including Windows and Unix installers for a full Haskell environment) are available. Anglohaskell 2009. Philippa Cowderoy [54]announced [55]Anglohaskell 2009, to be held at MSR Cambridge on the 7th and 8th of August. code reviewers wanted for hashed-storage (darcs). Eric Kow [56]solicited anyone with a few spare hours this summer willing to help the Darcs project as a code reviewer for the standalone hashed-storage module, which will be used by Darcs in the future. No Darcs experience is needed! Google Summer of Code Progress updates from participants in the 2008 [57]Google Summer of Code. Haddock improvements. Isaac Dupree has begun looking at the Haddock code, and has a [58]question about which of two options he should pursue. EclipseFP. Thomas Ten Cate has posted an [59]explanation of how the Scion client/server model works. Space profiling. Gergely Patai has [60]uploaded a preliminary version of the [61]hp2any core library which handles heap profiles both during and after execution. He has also [62]posted some pretty graphs generated by a simple utility built on top of the core library. haskell-src-exts. Niklas Broberg has begun work by making a [63]list of all language extensions and the ways in which they affect lexing and parsing, since haskell-src-exts will need to be parameterized over these extensions. Fast Darcs. Petr Rockai has posted two detailed [64]progress [65]reports already, with many changes to both the standalone [66]hashed-storage library and a [67]fork of darcs which uses it. Discussion Error message reform (was: Strange type error with associated type synonyms). Max Rabkin began an interesting [68]discussion about error messages. Do you have an intuitive sense of which is the 'expected' and which the 'inferred' type? time library dependencies. Ashley Yakeley [69]asked what dependencies are acceptable for the time library, leading to a discussion of what dependencies are acceptable for base packages. Bool as type class to serve EDSLs. Sebastiaan Visser started a [70]discussion on the possibility of a type class for representing Boolean values, much like the current Num class for numeric values. Jobs 10 jobs in declarative programming. Oege de Moor [71]announced the availability of positions with Semmle and LogicBlox for ten declarative programming consultants, who will work with clients to write custom queries in Datalog, and to create user interfaces in a declarative framework. Semmle and LogicBlox are creating a platform for declarative programming in Datalog, a pure logic programming language. Semmle is based in Oxford, headed by Oege de Moor; LogicBlox is based in Atlanta, headed by Molham Aref. See the announcement for more information and how to apply. Blog noise [72]Haskell news from the [73]blogosphere. Blog posts from people new to the Haskell community are marked with >>>, be sure to welcome them! * David Amos: [74]Welcome to Haskell for Maths. David's Haskell library for mathematics exploration is under development again! * Joachim Breitner: [75]Third place in AI programming contest. * Bryan O'Sullivan: [76]Dealing with encoding errors in Data.Text. * Remco Niemeijer: [77]Programming Praxis - Ternary Search Tries. * beelsebob: [78]Collecting Non-Memory Resources. * Luke Palmer: [79]It is never safe to cheat. Ceiling cat is watching you. * Alex McLean: [80]More hackery. More cool livecoding with Haskell. * Thomas ten Cate: [81]Client/server communication. * Gergely Patai: [82]The first graphs. * Alson Kemp: [83]Turbinado V0.6.5. * Don Stewart (dons): [84]The Haskell Platform 2009.2.0.1. The first minor update release of the Haskell Platform is here. * Alson Kemp: [85]Turbinado V0.6.5. * Michael Snoyman: [86]Functors and Monads (containers). * Well-Typed.Com: [87]Come talk at the Haskell Implementers' Workshop!. * GSoC Fast Darcs: [88]soc progress 2. * Shin-Cheng Mu: [89]On a Basic Property for the Longest Prefix Problem. * >>> Ben Hutchison: [90]OO/Imperative programmers: 'Study Functional Programming or Be Ignorant'. * Michael Snoyman: [91]Run a MonadCGI as a CGI application!. * Michael Snoyman: [92]Wordify: RESTful Haskell web apps. * Marco Tulio Gontijo e Silva: [93]xmlGetWidget without castTo*. * >>> slawekk: [94]Probability monad. * Brandon Simmons: [95]Huffman Coding. * Niklas Broberg: [96]Parametrising haskell-src-exts on extensions. A list of language extensions and how they affect parsing. * Manuel M T Chakravarty: [97]Instant Generics now has a website!. * GHC / OpenSPARC Project: [98]The CAS experiment. * Brent Yorgey: [99]Hac phi!. Registration is now open. * Jeff Heard: [100]Buster 2.2 - Application Orchestration redux. Example code showing off Buster. * Bryan O'Sullivan: [101]I put a pidgit in your widget so you can fidget while you calculate pi. GHC and the language shootout. * Niklas Broberg: [102]Haskell Platform, I'm in love. * Bjorn Buckwalter: [103]Benchmarking Amazon EC2 with GHC. * Bjorn Buckwalter: [104]Blogging with Pandoc, literate Haskell, and a bug. * >>> Chris Moos: [105]Haskell AIM Client - a cool proof of concept. * Marco Tulio Gontijo e Silva: [106]Generating code with Haskell-src and TH. Quotes of the Week * pumpkin: we should throw it [CReal] in with Foreign.C.Types to confuse people * MyCatVerbs: The *real* best way to optimize a program is to tell dons that it's been added to the Shootout. * SimonFrankau: The points-free approach, while elegant, can make code unreadable, especially if it is written by quantitative analysts moonlighting as functional programmers. * ValarQ: l33t_h4x0r: could you help me port GHC to the AVR architecture? <-- l33t_h4x0r has left #haskell * gwern: drat. what *do* all you people talk about? only one bacon and one zombie quote * quicksilver: well if you can get proggit to help with your interview, then perhaps you can get proggit to help with the job when you get it. So it's not cheating, it's just an indication of one of your skill sets. * shapr: I haven't tried F#, everytime I get the urge to do something fun with .NET I have SharePoint flashbacks and buy more hardware instead. * gwern: bleh. haskell is messing me up. I wondered what operator =) is, before I realized it was a syntax error, before I realized it was an emoticon About the Haskell Weekly News New editions are posted to [107]the Haskell mailing list as well as to [108]the Haskell Sequence and [109]Planet Haskell. [110]RSS is also available, and headlines appear on [111]haskell.org. To help create new editions of this newsletter, please see the information on [112]how to contribute. Send stories to byorgey at cis dot upenn dot edu. The darcs repository is available at darcs get [113]http://code.haskell.org/~byorgey/code/hwn/ . References 1. http://haskell.org/ 2. http://haskell.org/haskellwiki/Hac_%CF%86 3. http://article.gmane.org/gmane.comp.lang.haskell.general/17225 4. http://article.gmane.org/gmane.comp.lang.haskell.general/17214 5. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/storable-record 6. http://www.cse.unsw.edu.au/~chak/haskell/c2hs/ 7. http://article.gmane.org/gmane.comp.lang.haskell.general/17208 8. http://www.haskell.org/communities/ 9. http://www.haskell.org//pipermail/haskell-cafe/2009-May/061841.html 10. http://hledger.org/ 11. http://article.gmane.org/gmane.comp.lang.haskell.cafe/58955 12. http://code.haskell.org/haskell-src-exts 13. http://trac.haskell.org/haskell-src-exts 14. http://article.gmane.org/gmane.comp.lang.haskell.cafe/58928 15. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/bsd-sysctl 16. http://www.haskell.org//pipermail/haskell-cafe/2009-May/061887.html 17. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/multirec-binary 18. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/multirec 19. http://www.haskell.org//pipermail/haskell-cafe/2009-June/062297.html 20. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59268 21. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59256 22. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/uu%2Dparsinglib 23. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59156 24. http://haskell.org/haskellwiki/Hac_%CF%86/Register 25. http://haskell.org/haskellwiki/Hac_%CF%86 26. http://article.gmane.org/gmane.comp.lang.haskell.glasgow.user/17046 27. http://article.gmane.org/gmane.comp.lang.haskell.libraries/11243 28. http://hackage.haskell.org/packages/archive/bindings-libusb/0.0.3/doc/html/Bindings-Libusb.html 29. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/bindings-common-0.1.3 30. http://article.gmane.org/gmane.comp.lang.haskell.libraries/11224 31. http://gregorycollins.net/static/haskell/haskell-platform-2009.2.0.1-alpha2.pkg 32. http://article.gmane.org/gmane.comp.lang.haskell.libraries/11217 33. http://trac.haskell.org/haskell-platform/wiki/ReleaseTimetable 34. http://article.gmane.org/gmane.comp.lang.haskell.general/17253 35. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hscamwire 36. http://article.gmane.org/gmane.comp.lang.haskell.general/17251 37. http://article.gmane.org/gmane.comp.lang.haskell.general/17247 38. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/serial 39. http://article.gmane.org/gmane.comp.lang.haskell.general/17238 40. http://iba-cg.de/hal4.html 41. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59435 42. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/wp%2Darchivebot 43. https://secure.wikimedia.org/wikipedia/en/wiki/WebCite 44. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59415 45. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/memscript 46. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59405 47. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HSH 48. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59400 49. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/atom 50. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59363 51. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/heap 52. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59338 53. http://hackage.haskell.org/platform/ 54. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59337 55. http://www.haskell.org/haskellwiki/AngloHaskell/2009 56. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59327 57. http://hackage.haskell.org/trac/summer-of-code/wiki/SoC2008 58. http://haddock2009.wordpress.com/2009/05/26/another-boring-update-question/ 59. http://eclipsefp.wordpress.com/2009/06/03/clientserver-communication/ 60. http://just-bottom.blogspot.com/2009/05/read-your-profiles.html 61. http://code.google.com/p/hp2any/ 62. http://just-bottom.blogspot.com/2009/06/first-graphs.html 63. http://nibrofun.blogspot.com/2009/05/parametrising-haskell-src-exts-on.html 64. http://web.mornfall.net/blog/soc_progress_1.html 65. http://web.mornfall.net/blog/soc_progress_2.html 66. http://repos.mornfall.net/hashed-storage 67. http://repos.mornfall.net/darcs/darcs-hs 68. http://thread.gmane.org/gmane.comp.lang.haskell.cafe/59073 69. http://thread.gmane.org/gmane.comp.lang.haskell.libraries/11163 70. http://thread.gmane.org/gmane.comp.lang.haskell.cafe/59021 71. http://article.gmane.org/gmane.comp.lang.haskell.general/17207 72. http://planet.haskell.org/ 73. http://haskell.org/haskellwiki/Blog_articles 74. http://haskellformaths.blogspot.com/2009/06/welcome-to-haskell-for-maths.html 75. https://www.joachim-breitner.de/blog/archives/328-Third-place-in-AI-programming-contest.html 76. http://www.serpentine.com/blog/2009/06/05/dealing-with-encoding-errors-in-datatext/ 77. http://bonsaicode.wordpress.com/2009/06/05/programming-praxis-ternary-search-tries/ 78. http://noordering.wordpress.com/2009/06/05/collecting-non-memory-resources/ 79. http://lukepalmer.wordpress.com/2009/06/04/it-is-never-safe-to-cheat/ 80. http://yaxu.org/more-hackery/ 81. http://eclipsefp.wordpress.com/2009/06/03/clientserver-communication/ 82. http://just-bottom.blogspot.com/2009/06/first-graphs.html 83. http://www.alsonkemp.com/haskell/turbinado-v065/ 84. http://donsbot.wordpress.com/2009/06/02/the-haskell-platform-2009-2-0-1/ 85. http://www.alsonkemp.com/haskell/turbinado-v065/ 86. http://blog.snoyman.com/2009/06/02/functors-and-monads-containers/ 87. http://blog.well-typed.com/2009/06/come-talk-at-the-haskell-implementers-workshop/ 88. http://web.mornfall.net/blog/soc_progress_2.html 89. http://www.iis.sinica.edu.tw/~scm/2009/on-a-basic-property-for-the-longest-prefix-problem/ 90. http://benhutchison.wordpress.com/2009/06/02/study-functional-programming-or-be-ignorant/ 91. http://blog.snoyman.com/2009/05/20/run-a-monadcgi-as-a-cgi-application/ 92. http://blog.snoyman.com/2009/05/20/wordify-restful-haskell-web-apps/ 93. http://marcot.iaaeee.org/diario/?p=137 94. http://slawekk.wordpress.com/2009/05/31/probability-monad/ 95. http://coder.bsimmons.name/blog/2009/05/huffman-coding/ 96. http://nibrofun.blogspot.com/2009/05/parametrising-haskell-src-exts-on.html 97. http://justtesting.org/post/115191589 98. http://ghcsparc.blogspot.com/2009/05/cas-experiment.html 99. http://byorgey.wordpress.com/2009/05/28/hac-%cf%86/ 100. http://vis.renci.org/jeff/2009/05/28/buster-22-application-orchestration-redux/ 101. http://www.serpentine.com/blog/2009/05/27/i-put-a-pidgit-in-your-widget-so-you-can-fidget-while-you-calculate-pi/ 102. http://nibrofun.blogspot.com/2009/05/haskell-platform-im-in-love.html 103. http://flygdynamikern.blogspot.com/2009/05/benchmarking-amazon-ec2-with-ghc.html 104. http://flygdynamikern.blogspot.com/2009/03/blogging-with-pandoc-literate-haskell.html 105. http://chrismoos.com/2009/05/26/haskell-aim-client-a-cool-proof-of-concept/ 106. http://marcot.iaaeee.org/diario/?p=130 107. http://www.haskell.org/mailman/listinfo/haskell 108. http://sequence.complete.org/ 109. http://planet.haskell.org/ 110. http://sequence.complete.org/node/feed 111. http://haskell.org/ 112. http://haskell.org/haskellwiki/HWN 113. http://code.haskell.org/~byorgey/code/hwn/ From bjorn.buckwalter at gmail.com Sat Jun 6 17:51:10 2009 From: bjorn.buckwalter at gmail.com (Bjorn Buckwalter) Date: Sat Jun 6 17:35:18 2009 Subject: [Haskell-cafe] ANNOUNCE: numtype 1.0 -- Type-level (low cardinality) integers Message-ID: <8b2a1a960906061451s2a5adf61k64579161c7041d@mail.gmail.com> Dear all, Since its inception my dimensional library has been built around a unary type-level representation of integers (NumTypes) defined in the Numeric.NumType module. This module has proven itself useful outside the context of dimensional and after dragging my feet for a long time I've finally gotten around packaging it up in its own library: numtype[1]. The Numeric.NumType module is completely self-contained (only imports Prelude) and is heavily commented in a narrative manner inspired by Oleg Kiselyov's expositions. I believe it provides a good case study for type-level programming with multi-parameter type classes and functional dependencies. Addition, subtraction, division, and multiplication of NumTypes is supported. NumTypes have no value-level representation but can be converted to any Num instance with the 'toNum' function. The numtype library has two significant short-comings: * Minimal haddocks -- as with my dimensional library the literate Haskell source code is the documentation. The flip-side is that the code is very well-commented. * Due to the unary implementation the practical size of the NumTypes is severely limited, making them unsuitable for large-cardinality applications. If you will be working with integers beyond (-20, 20) this package probably isn't for you. (If the second bullet is a show-stopper Edward Kmett's type-int[2] library may be a better choice. Peter Gavin's tfp[3] library also provides type-level integers but uses type families instead of MPTCs and fundeps. I cannot vouch for either of these libraries as I haven't used them.) Numtype version 1.0 can be downloaded from Hackage or the dimensional project page[4]. I've also updated dimensional to version 0.8 with the Numeric.NumType module removed and Julian 'year' and 'century' units added. Enjoy! Thanks, Bjorn Buckwalter [1]: http://code.google.com/p/dimensional/wiki/numtype [2]: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/type-int [3]: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/tfp [4]: http://dimensional.googlecode.com From v.reshetnikov at gmail.com Sat Jun 6 18:06:11 2009 From: v.reshetnikov at gmail.com (Vladimir Reshetnikov) Date: Sat Jun 6 17:49:58 2009 Subject: [Haskell-cafe] Question on rank-N polymorphism Message-ID: <4770d2590906061506w16d44af1i9a23bd0c6c1c5387@mail.gmail.com> Hi, I have the following code: -------------------------------------------------------------------------------- fs g = (g fst, g snd) examples = (fs fmap, fs liftA, fs liftM, fs id, fs ($(1,"2")), fs ((,)id), fs (:[]), fs repeat) -------------------------------------------------------------------------------- The idea is that fs accepts a polymorphic function as its argument. What type signature can I specify for f in order to compile this code? If it is not possible in Haskell, is there another language with static typing which allows this? Thanks, Vladimir From vigalchin at gmail.com Sat Jun 6 19:45:18 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Sat Jun 6 19:29:04 2009 Subject: [Haskell-cafe] Still having problems building a very simple "Executable" .... Message-ID: <5ae4f2ba0906061645j69e0b547t379c6d8c04208027@mail.gmail.com> Hello, I picked an exceedingly case to build an "Executable": Executable QNameTest Hs-source-dirs: Swish/ Main-Is: HaskellUtils/QNameTest.hs Other-Modules: HaskellUtils.QName Here are the results of a "cabal build -v": Creating dist/build/QNameTest (and its parents) Creating dist/build/QNameTest/QNameTest-tmp (and its parents) /usr/local/bin/ghc -o dist/build/QNameTest/QNameTest --make -hide-all-packages -i -idist/build/QNameTest/QNameTest-tmp -iSwish/ -idist/build/autogen -Idist/build/QNameTest/QNameTest-tmp -odir dist/build/QNameTest/QNameTest-tmp -hidir dist/build/QNameTest/QNameTest-tmp -stubdir dist/build/QNameTest/QNameTest-tmp -package HUnit-1.2.0.0 -package array-0.1.0.0 -package base-3.0.1.0 -package binary-0.4.2 -package bytestring-0.9.1.0 -package containers-0.1.0.1 -package mtl-1.1.0.1 -package old-time-1.0.0.0 -package parallel-1.0.0.0 -package parsec-2.1.0.0 -package random-1.0.0.0 -O Swish/HaskellUtils/QNameTest.hs Swish/HaskellUtils/QNameTest.hs:36:7: Could not find module `Swish.HaskellUtils.QName': Use -v to see a list of the files searched for. ??? Thanks, Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090606/6042f1c8/attachment.html From vigalchin at gmail.com Sat Jun 6 19:58:32 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Sat Jun 6 19:42:20 2009 Subject: [Haskell-cafe] Re: Still having problems building a very simple "Executable" .... In-Reply-To: <5ae4f2ba0906061645j69e0b547t379c6d8c04208027@mail.gmail.com> References: <5ae4f2ba0906061645j69e0b547t379c6d8c04208027@mail.gmail.com> Message-ID: <5ae4f2ba0906061658w58109ab3q6c33df3e34ed94f7@mail.gmail.com> in the following harder case, I see no mention of path Swish/HaskellUtils ..... seems not good: /usr/local/bin/ghc -o dist/build/GraphPartitionTest/GraphPartitionTest --make -hide-all-packages -i -idist/build/GraphPartitionTest/GraphPartitionTest-tmp -iSwish/ -idist/build/autogen -Idist/build/GraphPartitionTest/GraphPartitionTest-tmp -odir dist/build/GraphPartitionTest/GraphPartitionTest-tmp -hidir dist/build/GraphPartitionTest/GraphPartitionTest-tmp -stubdir dist/build/GraphPartitionTest/GraphPartitionTest-tmp -package HUnit-1.2.0.0 -package array-0.1.0.0 -package base-3.0.1.0 -package binary-0.4.2 -package bytestring-0.9.1.0 -package containers-0.1.0.1 -package mtl-1.1.0.1 -package old-time-1.0.0.0 -package parallel-1.0.0.0 -package parsec-2.1.0.0 -package random-1.0.0.0 -O Swish/HaskellRDF/GraphPartitionTest.hs Swish/HaskellRDF/GraphPartitionTest.hs:51:7: Could not find module `Swish.HaskellUtils.ListHelpers': Use -v to see a list of the files searched for. vigalchin@ubuntu:~/FTP/Haskell/Swish-0.2.1$ On Sat, Jun 6, 2009 at 6:45 PM, Vasili I. Galchin wrote: > Hello, > > I picked an exceedingly case to build an "Executable": > > Executable QNameTest > Hs-source-dirs: Swish/ > Main-Is: HaskellUtils/QNameTest.hs > Other-Modules: HaskellUtils.QName > > Here are the results of a "cabal build -v": > > Creating dist/build/QNameTest (and its parents) > Creating dist/build/QNameTest/QNameTest-tmp (and its parents) > /usr/local/bin/ghc -o dist/build/QNameTest/QNameTest --make > -hide-all-packages -i -idist/build/QNameTest/QNameTest-tmp -iSwish/ > -idist/build/autogen -Idist/build/QNameTest/QNameTest-tmp -odir > dist/build/QNameTest/QNameTest-tmp -hidir dist/build/QNameTest/QNameTest-tmp > -stubdir dist/build/QNameTest/QNameTest-tmp -package HUnit-1.2.0.0 -package > array-0.1.0.0 -package base-3.0.1.0 -package binary-0.4.2 -package > bytestring-0.9.1.0 -package containers-0.1.0.1 -package mtl-1.1.0.1 -package > old-time-1.0.0.0 -package parallel-1.0.0.0 -package parsec-2.1.0.0 -package > random-1.0.0.0 -O Swish/HaskellUtils/QNameTest.hs > > Swish/HaskellUtils/QNameTest.hs:36:7: > Could not find module `Swish.HaskellUtils.QName': > Use -v to see a list of the files searched for. > > ??? > > Thanks, > > Vasili > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090606/dbefe18d/attachment.html From mle+hs at mega-nerd.com Sat Jun 6 20:12:05 2009 From: mle+hs at mega-nerd.com (Erik de Castro Lopo) Date: Sat Jun 6 19:55:55 2009 Subject: [Haskell-cafe] Re: Haddock : parse error on input `{-# UNPACK' In-Reply-To: References: <20090606125614.93aca46d.mle+hs@mega-nerd.com> Message-ID: <20090607101205.d0e6f1f0.mle+hs@mega-nerd.com> Dominic Steinitz wrote: > Erik de Castro Lopo mega-nerd.com> writes: > > > > > src/Data/Binary/Strict/IncrementalGet.hs:106:11: > > parse error on input `{-# UNPACK' > > > > Is this a bug? Is there any way to work around it? > > > > This is a haddock error and I presume a bug in haddock. Well I raised a bug here: http://trac.haskell.org/haddock/ticket/109 > I don't know whether cabal installs things if haddock fails. Thats actually not the problem. I'm trying to build a debian package for this thing and this haddock problem is preventing that. Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/ From dave at zednenem.com Sat Jun 6 20:22:38 2009 From: dave at zednenem.com (David Menendez) Date: Sat Jun 6 20:06:24 2009 Subject: [Haskell-cafe] Still having problems building a very simple "Executable" .... In-Reply-To: <5ae4f2ba0906061645j69e0b547t379c6d8c04208027@mail.gmail.com> References: <5ae4f2ba0906061645j69e0b547t379c6d8c04208027@mail.gmail.com> Message-ID: <49a77b7a0906061722x5d1f8112pe82b746a6c3a2206@mail.gmail.com> On Sat, Jun 6, 2009 at 7:45 PM, Vasili I. Galchin wrote: > Hello, > > ???? I picked an exceedingly case to build an "Executable": > > Executable???????? QNameTest > ?? Hs-source-dirs: Swish/ > ?? Main-Is:??????? HaskellUtils/QNameTest.hs > ?? Other-Modules:? HaskellUtils.QName > > Here are the results of a "cabal build -v": > > Creating dist/build/QNameTest (and its parents) > Creating dist/build/QNameTest/QNameTest-tmp (and its parents) > /usr/local/bin/ghc -o dist/build/QNameTest/QNameTest --make > -hide-all-packages -i -idist/build/QNameTest/QNameTest-tmp -iSwish/ > -idist/build/autogen -Idist/build/QNameTest/QNameTest-tmp -odir > dist/build/QNameTest/QNameTest-tmp -hidir dist/build/QNameTest/QNameTest-tmp > -stubdir dist/build/QNameTest/QNameTest-tmp -package HUnit-1.2.0.0 -package > array-0.1.0.0 -package base-3.0.1.0 -package binary-0.4.2 -package > bytestring-0.9.1.0 -package containers-0.1.0.1 -package mtl-1.1.0.1 -package > old-time-1.0.0.0 -package parallel-1.0.0.0 -package parsec-2.1.0.0 -package > random-1.0.0.0 -O Swish/HaskellUtils/QNameTest.hs > > Swish/HaskellUtils/QNameTest.hs:36:7: > ??? Could not find module `Swish.HaskellUtils.QName': > ????? Use -v to see a list of the files searched for. > > ??? I'm guessing QNameTest.hs imports Swish.HaskellUtils.QName, which means that GHC is looking for a file Swish/HaskellUtils/QName.hs. But you've indicated that the root of the source tree is a directory called Swish/, so GHC is looking for Swish/Swish/HaskellUtils/QName.hs. I'd try eliminating the hs-source-dirs field. -- Dave Menendez From bertram.felgenhauer at googlemail.com Sat Jun 6 21:43:10 2009 From: bertram.felgenhauer at googlemail.com (Bertram Felgenhauer) Date: Sat Jun 6 21:27:05 2009 Subject: [Haskell-cafe] Still having problems building a very simple "Executable" .... In-Reply-To: <5ae4f2ba0906061645j69e0b547t379c6d8c04208027@mail.gmail.com> References: <5ae4f2ba0906061645j69e0b547t379c6d8c04208027@mail.gmail.com> Message-ID: <4a2b1b31.02135e0a.2f45.ffffd255@mx.google.com> Hi Vasili, Vasili I. Galchin wrote: > I picked an exceedingly case to build an "Executable": > > Executable QNameTest > Hs-source-dirs: Swish/ > Main-Is: HaskellUtils/QNameTest.hs > Other-Modules: HaskellUtils.QName I'm not sure what you did; the original Swish code doesn't have any hierarchical modules. Starting with that, I could build QNameTest like this: executable QNameTest hs-source-dirs: HaskellUtils HaskellRDF HaskellRDF/HUnit main-is: QNameTest.hs other-modules: HUnitLang HUnitBase HUnitText QName QNameTest build-depends: base, haskell98 ghc-options: -main-is QNameTest The trick here is to list all used subdirectories in hs-source-dirs; the module HUnit for example will be found in HaskellRDF/HUnit/ under the name HUnit.lhs. If you have a module A.B.C then the source file should be in foo/A/B/C.hs (or lhs or some other recognized extension) and foo should be listed in hs-source-dirs. Also note the ghc-options line: it tells ghc to use QNameTest instead of Main for the main module. I also managed to produce a Swish executable after a bit of tweaking; you can find my changes in http://int-e.home.tlink.de/haskell/Swish.diff The cabal file is at the end of the diff. HTH, Bertram P.S. I took Swish code from here: http://www.ninebynine.org/RDFNotes/Swish/Intro.html#SwishLinks From ccshan at post.harvard.edu Sat Jun 6 21:48:53 2009 From: ccshan at post.harvard.edu (Chung-chieh Shan) Date: Sat Jun 6 21:32:54 2009 Subject: [Haskell-cafe] Re: I love purity, but it's killing me. In-Reply-To: <856033f20905270058q493a254ah4623fbc354096574@mail.gmail.com> References: <594c1e830802072233n2b36ca82wd3c778f22edd4564@mail.gmail.com> <4cka85-223.ln1@mantle.rutgers.edu> <856033f20905270058q493a254ah4623fbc354096574@mail.gmail.com> Message-ID: <20090607014853.GA30135@mantle.rutgers.edu> On 2009-05-27T03:58:58-0400, Paul L wrote: > One possible solution is to further introduce a fixed point data > constructor, a Rec or even LetRec to explicitly capture cycles. But > then you still incur much overheads interpreting them, I don't understand this criticism -- what interpretive overhead do you mean? Certainly the Rec/LetRec encoding is pretty efficient for one object language with cycles, namely the lambda calculus with Rec or LetRec. :) One concrete way for you to explain what interpretive overhead you mean, if it's not too much trouble, might be to compare a Rec/LetRec encoding of a particular object language to another encoding that does not have the interpretive overhead you mean and is therefore more efficient. -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig We want our revolution, and we want it now! -- Marat/Sade We want our revolution, and we'll take it at such time as you've gotten around to delivering it -- Haskell programmer -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090606/7bcd5db3/attachment.bin From uhollerbach at gmail.com Sat Jun 6 22:07:12 2009 From: uhollerbach at gmail.com (Uwe Hollerbach) Date: Sat Jun 6 21:50:58 2009 Subject: [Haskell-cafe] Announce: haskeem 0.7.0 uploaded to hackage Message-ID: <65d7a7e0906061907w6b0208e1t2acdd01c278c5e81@mail.gmail.com> Hi, all, a little while ago I uploaded haskeem 0.7.0 to hackage: this is my small scheme interpreter. I had been busy with other important stuff for a while, and hadn't worked on it for a while; but I've now updated it to build ok with ghc 6.10.3 + haskeline, plus I added a simple macro system; that had been one of the two big items left on my list for it. It's not yet full R6RS Scheme hygienic macros, but I'll get there, too... I had kind of a "functional programming moment" while doing this macro system... I had been thinking and reading about it for, oh, a couple of weeks now, and today I sat down to start that, with the hope of maybe finishing it in a week or two. Nope! All in all, it took about 45 minutes, with the really important changes to the code spanning, oh, call it a generous three lines of code. There were changes in 50ish other lines, but those were all pretty trivial, just adding another data type. Such a let-down! :-) :-) :-) There is one small regression in all of this, namely that with haskeline I have lost the ability to interrupt the interpreter and land back at the "lisp>" prompt. I can interrupt it all right, but I end up at the shell prompt... not so good! I know all that stuff can be set up to interrupt a little less thoroughly than that, I just haven't got around to it yet... soon, I hope. Uwe From vigalchin at gmail.com Sat Jun 6 23:54:40 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Sat Jun 6 23:38:28 2009 Subject: [Haskell-cafe] Still having problems building a very simple "Executable" .... In-Reply-To: <49a77b7a0906061722x5d1f8112pe82b746a6c3a2206@mail.gmail.com> References: <5ae4f2ba0906061645j69e0b547t379c6d8c04208027@mail.gmail.com> <49a77b7a0906061722x5d1f8112pe82b746a6c3a2206@mail.gmail.com> Message-ID: <5ae4f2ba0906062054t4b8144fcreaacbf2dc3605b43@mail.gmail.com> Hi David, I commented out "Hs-source-dirs" Executable QNameTest -- Hs-source-dirs: Swish/ Main-Is: HaskellUtils/QNameTest.hs Other-Modules: HaskellUtils.QName Here is what I got: vigalchin@ubuntu:~/FTP/Haskell/Swish-0.2.1$ cabal build -v Warning: swish.cabal: A package using section syntax should require "Cabal-Version: >= 1.2" or equivalent. Creating dist/build (and its parents) Creating dist/build/autogen (and its parents) Preprocessing library swish-0.2.1... Preprocessing executables for swish-0.2.1... cabal: can't find source for HaskellUtils.QName in ., dist/build/autogen vigalchin@ubuntu:~/FTP/Haskell/Swish-0.2.1$ I seem to remember that on the Haskell Wiki there is an example of building/linking an "Executable" but I cannot find. ?? Regards, Vasili On Sat, Jun 6, 2009 at 7:22 PM, David Menendez wrote: > On Sat, Jun 6, 2009 at 7:45 PM, Vasili I. Galchin > wrote: > > Hello, > > > > I picked an exceedingly case to build an "Executable": > > > > Executable QNameTest > > Hs-source-dirs: Swish/ > > Main-Is: HaskellUtils/QNameTest.hs > > Other-Modules: HaskellUtils.QName > > > > Here are the results of a "cabal build -v": > > > > Creating dist/build/QNameTest (and its parents) > > Creating dist/build/QNameTest/QNameTest-tmp (and its parents) > > /usr/local/bin/ghc -o dist/build/QNameTest/QNameTest --make > > -hide-all-packages -i -idist/build/QNameTest/QNameTest-tmp -iSwish/ > > -idist/build/autogen -Idist/build/QNameTest/QNameTest-tmp -odir > > dist/build/QNameTest/QNameTest-tmp -hidir > dist/build/QNameTest/QNameTest-tmp > > -stubdir dist/build/QNameTest/QNameTest-tmp -package HUnit-1.2.0.0 > -package > > array-0.1.0.0 -package base-3.0.1.0 -package binary-0.4.2 -package > > bytestring-0.9.1.0 -package containers-0.1.0.1 -package mtl-1.1.0.1 > -package > > old-time-1.0.0.0 -package parallel-1.0.0.0 -package parsec-2.1.0.0 > -package > > random-1.0.0.0 -O Swish/HaskellUtils/QNameTest.hs > > > > Swish/HaskellUtils/QNameTest.hs:36:7: > > Could not find module `Swish.HaskellUtils.QName': > > Use -v to see a list of the files searched for. > > > > ??? > > I'm guessing QNameTest.hs imports Swish.HaskellUtils.QName, which > means that GHC is looking for a file Swish/HaskellUtils/QName.hs. But > you've indicated that the root of the source tree is a directory > called Swish/, so GHC is looking for > Swish/Swish/HaskellUtils/QName.hs. > > I'd try eliminating the hs-source-dirs field. > > -- > Dave Menendez > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090606/d29336a5/attachment.html From vigalchin at gmail.com Sun Jun 7 00:15:28 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Sat Jun 6 23:59:21 2009 Subject: [Haskell-cafe] Re: Still having problems building a very simple "Executable" .... In-Reply-To: <5ae4f2ba0906061645j69e0b547t379c6d8c04208027@mail.gmail.com> References: <5ae4f2ba0906061645j69e0b547t379c6d8c04208027@mail.gmail.com> Message-ID: <5ae4f2ba0906062115t326e8735gadab56324a26bd9a@mail.gmail.com> Here is the beginning of QNameTest .. i.e. interface plus imports: module Swish.HaskellUtils.QNameTest where^M ^M import System.IO^M ( Handle, IOMode(WriteMode)^M , openFile, hClose, hPutStr, hPutStrLn^M )^M ^M import Data.Maybe^M ( fromJust )^M ^M import Test.HUnit^M ( Test(TestCase,TestList,TestLabel)^M , assertBool, assertEqual, assertString^M , runTestTT, runTestText, putTextToHandle^M )^M ^M import Swish.HaskellUtils.QName^M ( QName(..)^M , newQName, qnameFromPair, qnameFromURI^M , getNamespace, getLocalName, getQNameURI^M , splitURI^M )^M Following is the linking info for QNameTest ... I don't see a -package switch for Swish.HaskellUtils.Qname! why? Creating dist/build/QNameTest (and its parents) Creating dist/build/QNameTest/QNameTest-tmp (and its parents) /usr/local/bin/ghc -o dist/build/QNameTest/QNameTest --make -hide-all-packages -i -idist/build/QNameTest/QNameTest-tmp -iSwish/ -idist/build/autogen -Idist/build/QNameTest/QNameTest-tmp -odir dist/build/QNameTest/QNameTest-tmp -hidir dist/build/QNameTest/QNameTest-tmp -stubdir dist/build/QNameTest/QNameTest-tmp -package HUnit-1.2.0.0 -package array-0.1.0.0 -package base-3.0.1.0 -package binary-0.4.2 -package bytestring-0.9.1.0 -package containers-0.1.0.1 -package mtl-1.1.0.1 -package old-time-1.0.0.0 -package parallel-1.0.0.0 -package parsec-2.1.0.0 -package random-1.0.0.0 -O Swish/HaskellUtils/QNameTest.hs Swish/HaskellUtils/QNameTest.hs:36:7: Could not find module `Swish.HaskellUtils.QName': Use -v to see a list of the files searched for. Regards, Vasili On Sat, Jun 6, 2009 at 6:45 PM, Vasili I. Galchin wrote: > Hello, > > I picked an exceedingly case to build an "Executable": > > Executable QNameTest > Hs-source-dirs: Swish/ > Main-Is: HaskellUtils/QNameTest.hs > Other-Modules: HaskellUtils.QName > > Here are the results of a "cabal build -v": > > Creating dist/build/QNameTest (and its parents) > Creating dist/build/QNameTest/QNameTest-tmp (and its parents) > /usr/local/bin/ghc -o dist/build/QNameTest/QNameTest --make > -hide-all-packages -i -idist/build/QNameTest/QNameTest-tmp -iSwish/ > -idist/build/autogen -Idist/build/QNameTest/QNameTest-tmp -odir > dist/build/QNameTest/QNameTest-tmp -hidir dist/build/QNameTest/QNameTest-tmp > -stubdir dist/build/QNameTest/QNameTest-tmp -package HUnit-1.2.0.0 -package > array-0.1.0.0 -package base-3.0.1.0 -package binary-0.4.2 -package > bytestring-0.9.1.0 -package containers-0.1.0.1 -package mtl-1.1.0.1 -package > old-time-1.0.0.0 -package parallel-1.0.0.0 -package parsec-2.1.0.0 -package > random-1.0.0.0 -O Swish/HaskellUtils/QNameTest.hs > > Swish/HaskellUtils/QNameTest.hs:36:7: > Could not find module `Swish.HaskellUtils.QName': > Use -v to see a list of the files searched for. > > ??? > > Thanks, > > Vasili > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090606/58c14850/attachment-0001.html From iavor.diatchki at gmail.com Sun Jun 7 00:43:12 2009 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Sun Jun 7 00:26:57 2009 Subject: [Haskell-cafe] Building network package on Windows Message-ID: <5ab17e790906062143h3968488bg577cdbe0de796bd9@mail.gmail.com> Hi, I have been trying to build the package "network" from hackage (version 2.2.1.3) on Windows Vista, and I could really use some help. Building on the command line, or under cygwin completely failed (command line due to cabal not being able to execute something---possibly configure---although it would not say; cygwin first due to lack of gcc, which is tested but, apparently, the outcome ignored, and after gcc was installed some incompatibility with the header files which were detected but reported unusable). I managed to build the library under MinGW with msys without serious obstacles. I can also build my package against the result and all is well. Unfortunately, if I try to use my package to build an executable application I get a linker error, reporting a missing symbol during linking: C:\Users\diatchki\AppData\Roaming\cabal\network-2.2.1.3\ghc-6.10.3/libHSnetwork-2.2.1.3.a(Socket.o):fake:(.text+0xb014): undefined reference to `getnameinfo' collect2: ld returned 1 exit status Now, "getnameinfo" is present in the header files, and it is also defined in the library ws2_32.a which is being passed to GHC so I am not sure what is going on. Any ideas? Searching the web suggests that the problem may be somehow related to the standard calling conventions but I don't really understand. Also, if I understand correctly, this functionality is related to IPv6 support, which I do not need at the moment, so it would be great if it could be easily disabled in some way. Any ideas, suggestion, workarounds, etc. would be greatly appreciated, -Iavor PS: I am using GHC 6.10.3 From dave at zednenem.com Sun Jun 7 01:17:10 2009 From: dave at zednenem.com (David Menendez) Date: Sun Jun 7 01:00:56 2009 Subject: [Haskell-cafe] Still having problems building a very simple "Executable" .... In-Reply-To: <5ae4f2ba0906062054t4b8144fcreaacbf2dc3605b43@mail.gmail.com> References: <5ae4f2ba0906061645j69e0b547t379c6d8c04208027@mail.gmail.com> <49a77b7a0906061722x5d1f8112pe82b746a6c3a2206@mail.gmail.com> <5ae4f2ba0906062054t4b8144fcreaacbf2dc3605b43@mail.gmail.com> Message-ID: <49a77b7a0906062217h4469883dn356da3ac4f872c31@mail.gmail.com> On Sat, Jun 6, 2009 at 11:54 PM, Vasili I. Galchin wrote: > Hi David, > > ???? I commented out "Hs-source-dirs" > > Executable???????? QNameTest > --?? Hs-source-dirs: Swish/ > ?? Main-Is:??????? HaskellUtils/QNameTest.hs Swish/HaskellUtils/QNameTest.hs > ?? Other-Modules:? HaskellUtils.QName Swish.HaskellUtils.QName -- Dave Menendez From mxcantor at gmail.com Sun Jun 7 01:40:17 2009 From: mxcantor at gmail.com (Max Cantor) Date: Sun Jun 7 01:24:08 2009 Subject: [Haskell-cafe] Generic polyvariadic printf in Haskell98 In-Reply-To: <20090605182911.24745e8d.mle+hs@mega-nerd.com> References: <20090605075700.56C32176F6@Adric.metnet.navy.mil> <20090605182911.24745e8d.mle+hs@mega-nerd.com> Message-ID: <140C4C0B-62C0-4FD6-AB55-6F6DA98392F2@gmail.com> To be fair, isn't the printf typing in ocaml a massively ugly hack to the type system? Isn't there an example in the template haskell tutorial that gives a typesafe, clean generic printf function? Max On Jun 5, 2009, at 4:29 PM, Erik de Castro Lopo wrote: > oleg@okmij.org wrote: > >> Still, the code is a bit unsatisfactory because of the appearances of >> "error" in pr_aux functions. The errors like passing too many or too >> few arguments to printf (as demanded by the format specification) are >> caught only at run-time. We can certainly do better. > > I'd love to see it. > > Coming from Ocaml one of the things I miss is compile time > checking of printf arguments. > > Erik > -- > ---------------------------------------------------------------------- > Erik de Castro Lopo > http://www.mega-nerd.com/ > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From vigalchin at gmail.com Sun Jun 7 02:33:26 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Sun Jun 7 02:17:11 2009 Subject: [Haskell-cafe] Still having problems building a very simple "Executable" .... In-Reply-To: <49a77b7a0906062217h4469883dn356da3ac4f872c31@mail.gmail.com> References: <5ae4f2ba0906061645j69e0b547t379c6d8c04208027@mail.gmail.com> <49a77b7a0906061722x5d1f8112pe82b746a6c3a2206@mail.gmail.com> <5ae4f2ba0906062054t4b8144fcreaacbf2dc3605b43@mail.gmail.com> <49a77b7a0906062217h4469883dn356da3ac4f872c31@mail.gmail.com> Message-ID: <5ae4f2ba0906062333q645f1c41l42074009e9056093@mail.gmail.com> thanks, David. Vasili On Sun, Jun 7, 2009 at 12:17 AM, David Menendez wrote: > On Sat, Jun 6, 2009 at 11:54 PM, Vasili I. Galchin > wrote: > > Hi David, > > > > I commented out "Hs-source-dirs" > > > > Executable QNameTest > > -- Hs-source-dirs: Swish/ > > Main-Is: HaskellUtils/QNameTest.hs > > Swish/HaskellUtils/QNameTest.hs > > > Other-Modules: HaskellUtils.QName > > Swish.HaskellUtils.QName > > -- > Dave Menendez > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090607/c392a74d/attachment.html From dominic at steinitz.org Sun Jun 7 02:50:22 2009 From: dominic at steinitz.org (Dominic Steinitz) Date: Sun Jun 7 02:34:27 2009 Subject: [Haskell-cafe] Re: Haddock : parse error on input `{-# UNPACK' References: <20090606125614.93aca46d.mle+hs@mega-nerd.com> <20090607101205.d0e6f1f0.mle+hs@mega-nerd.com> Message-ID: Erik de Castro Lopo mega-nerd.com> writes: > > Dominic Steinitz wrote: > > > Erik de Castro Lopo mega-nerd.com> writes: > > > > > > > > src/Data/Binary/Strict/IncrementalGet.hs:106:11: > > > parse error on input `{-# UNPACK' > > > > > > > This is a haddock error and I presume a bug in haddock. > > Well I raised a bug here: > > http://trac.haskell.org/haddock/ticket/109 > > Thats actually not the problem. I'm trying to build a debian package > for this thing and this haddock problem is preventing that. > > Erik This seems to be the problem: http://hackage.haskell.org/trac/hackage/ticket/230. There's obviously a work round for it as the haddock for the binary package builds (e.g. http://hackage.haskell.org/packages/archive/binary/0.5.0.1/doc/html/Data-Binary-Get.html) but I don't know what it is. What's even more frustrating is one of the authors of has tried: #ifndef __HADDOCK__ -- | The parse state data S = S {-# UNPACK #-} !BL.ByteString -- ^ input {-# UNPACK #-} !Int -- ^ bytes read {-# UNPACK #-} ![B.ByteString] {-# UNPACK #-} !Int -- ^ the failure depth #endif and haddock ignores this. And the binary package just has this (no ifdefs!): -- Our internal buffer type data Buffer = Buffer {-# UNPACK #-} !(ForeignPtr Word8) {-# UNPACK #-} !Int -- offset {-# UNPACK #-} !Int -- used bytes {-# UNPACK #-} !Int -- length left Perhaps one of the authors of binary can tell us their secret of success? Dominic. From dominic at steinitz.org Sun Jun 7 03:20:44 2009 From: dominic at steinitz.org (Dominic Steinitz) Date: Sun Jun 7 03:04:46 2009 Subject: [Haskell-cafe] Re: Haddock : parse error on input `{-# UNPACK' References: <20090606125614.93aca46d.mle+hs@mega-nerd.com> <20090607101205.d0e6f1f0.mle+hs@mega-nerd.com> Message-ID: Dominic Steinitz steinitz.org> writes: > > Erik de Castro Lopo mega-nerd.com> writes: > > > > > Dominic Steinitz wrote: > > > > > Erik de Castro Lopo mega-nerd.com> writes: > > > > > > > > > > > src/Data/Binary/Strict/IncrementalGet.hs:106:11: > > > > parse error on input `{-# UNPACK' > > > > > > > > > > This is a haddock error and I presume a bug in haddock. > > > > Well I raised a bug here: > > > > http://trac.haskell.org/haddock/ticket/109 > > Ha! It's yet another of haddock's quirks. If I replace -- ^ by -- then haddock accepts {-#. I'll update the ticket you created. -- | The parse state data S = S {-# UNPACK #-} !BL.ByteString -- ^ input {-# UNPACK #-} !Int -- ^ bytes read {-# UNPACK #-} ![B.ByteString] {-# UNPACK #-} !Int -- ^ the failure depth -- | The parse state data S = S {-# UNPACK #-} !BL.ByteString -- input {-# UNPACK #-} !Int -- bytes read {-# UNPACK #-} ![B.ByteString] {-# UNPACK #-} !Int -- the failure depth Dominic. From vigalchin at gmail.com Sun Jun 7 03:26:48 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Sun Jun 7 03:10:40 2009 Subject: [Haskell-cafe] totally confused about Haskell namespace issue conventions Message-ID: <5ae4f2ba0906070026t413927acl7bf2d28912663976@mail.gmail.com> Hello, Should namespace designation be specified in modules or in the .cabal file? Or to put it another way should a relative namespace be specified in a Haskell module and the remaining "top" part be specified in the associated .cabal file? Of course, yes/no answers are probably not sufficient ... i.e. please elaborate. Kind regards, Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090607/3a1fcb0d/attachment.html From vigalchin at gmail.com Sun Jun 7 03:46:07 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Sun Jun 7 03:29:53 2009 Subject: [Haskell-cafe] Re: totally confused about Haskell namespace issue conventions In-Reply-To: <5ae4f2ba0906070026t413927acl7bf2d28912663976@mail.gmail.com> References: <5ae4f2ba0906070026t413927acl7bf2d28912663976@mail.gmail.com> Message-ID: <5ae4f2ba0906070046gb2c07e6m84d9ba866495ddd3@mail.gmail.com> let put this subject in another way ... assuming there a coding convention, vis-a-vis Haskell namespace, what is the division of responsibility between a Haskell module and it's associated .cabal? Regards, Vasili On Sun, Jun 7, 2009 at 2:26 AM, Vasili I. Galchin wrote: > Hello, > > Should namespace designation be specified in modules or in the .cabal > file? Or to put it another way should a relative namespace be specified in a > Haskell module and the remaining "top" part be specified in the associated > .cabal file? Of course, yes/no answers are probably not sufficient ... i.e. > please elaborate. > > Kind regards, Vasili > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090607/c3f4dfce/attachment.html From mle+hs at mega-nerd.com Sun Jun 7 04:13:11 2009 From: mle+hs at mega-nerd.com (Erik de Castro Lopo) Date: Sun Jun 7 03:56:59 2009 Subject: [Haskell-cafe] Re: Haddock : parse error on input `{-# UNPACK' In-Reply-To: References: <20090606125614.93aca46d.mle+hs@mega-nerd.com> <20090607101205.d0e6f1f0.mle+hs@mega-nerd.com> Message-ID: <20090607181311.72ce6bf0.mle+hs@mega-nerd.com> Dominic Steinitz wrote: > -- | The parse state > data S = S {-# UNPACK #-} !BL.ByteString -- ^ input > {-# UNPACK #-} !Int -- ^ bytes read > {-# UNPACK #-} ![B.ByteString] > {-# UNPACK #-} !Int -- ^ the failure depth > > -- | The parse state > data S = S {-# UNPACK #-} !BL.ByteString -- input > {-# UNPACK #-} !Int -- bytes read > {-# UNPACK #-} ![B.ByteString] > {-# UNPACK #-} !Int -- the failure depth Thanks Dominic. Thats a workaround I can use. Cheers, Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/ From vigalchin at gmail.com Sun Jun 7 04:23:26 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Sun Jun 7 04:07:12 2009 Subject: [Haskell-cafe] Re: totally confused about Haskell namespace issue conventions In-Reply-To: <5ae4f2ba0906070046gb2c07e6m84d9ba866495ddd3@mail.gmail.com> References: <5ae4f2ba0906070026t413927acl7bf2d28912663976@mail.gmail.com> <5ae4f2ba0906070046gb2c07e6m84d9ba866495ddd3@mail.gmail.com> Message-ID: <5ae4f2ba0906070123t59eb4d67tecd1a7ad42d44859@mail.gmail.com> let me state another way .... as far as namespace is concerned what is division between a module's name and it's associated .cabal with it's Hs-Source-Dirs directive? This is kinda' absolute vs relative path I think. Regards, Vasili On Sun, Jun 7, 2009 at 2:46 AM, Vasili I. Galchin wrote: > let put this subject in another way ... assuming there a coding convention, > vis-a-vis Haskell namespace, what is the division of responsibility between > a Haskell module and it's associated .cabal? > > Regards, > > Vasili > > On Sun, Jun 7, 2009 at 2:26 AM, Vasili I. Galchin wrote: > >> Hello, >> >> Should namespace designation be specified in modules or in the >> .cabal file? Or to put it another way should a relative namespace be >> specified in a Haskell module and the remaining "top" part be specified in >> the associated .cabal file? Of course, yes/no answers are probably not >> sufficient ... i.e. please elaborate. >> >> Kind regards, Vasili >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090607/7193d3c6/attachment.html From v.reshetnikov at gmail.com Sun Jun 7 05:07:59 2009 From: v.reshetnikov at gmail.com (Vladimir Reshetnikov) Date: Sun Jun 7 04:51:45 2009 Subject: [Haskell-cafe] Question on rank-N polymorphism In-Reply-To: References: <4770d2590906070017v19b3c927nee57a0de38821f7d@mail.gmail.com> Message-ID: <4770d2590906070207w568a1382tfbcbdcfba5d9065d@mail.gmail.com> Hi Zsolt, fs :: (((a, a) -> a) -> t) -> (t, t) fs g = (g fst, g snd) examples = (fs fmap, fs liftA, fs liftM, fs id, fs ($(1,"2")), fs ((,)id), fs (:[]), fs repeat) No instance for (Num [Char]) arising from the literal `1' at M.hs:6:54 Possible fix: add an instance declaration for (Num [Char]) In the expression: 1 In the second argument of `($)', namely `(1, "2")' In the first argument of `fs', namely `($ (1, "2"))' Anyways, this signature is not what intended. I want it to work for all tuples, regardless of their element types. Thanks Vladimir On 6/7/09, Zsolt Dollenstein wrote: > On Sun, Jun 7, 2009 at 9:17 AM, Vladimir > Reshetnikov wrote: >> Hi Zsolt, >> >> It does not compiles with GHC without type annotations. > > It does with mine: The Glorious Glasgow Haskell Compilation System, version > 6.10.2 > > Anyway, try this: fs :: (((a, a) -> a) -> t) -> (t, t) > >> >> Thanks, >> Vladimir >> >> On 6/7/09, Zsolt Dollenstein wrote: >>> Hi Vladimir, >>> >>> On Sun, Jun 7, 2009 at 12:06 AM, Vladimir >>> Reshetnikov wrote: >>>> Hi, >>>> >>>> I have the following code: >>>> >>>> -------------------------------------------------------------------------------- >>>> fs g = (g fst, g snd) >>>> examples = (fs fmap, fs liftA, fs liftM, fs id, fs ($(1,"2")), fs >>>> ((,)id), fs (:[]), fs repeat) >>>> -------------------------------------------------------------------------------- >>>> >>>> The idea is that fs accepts a polymorphic function as its argument. >>>> What type signature can I specify for f in order to compile this code? >>> >>> Have you tried putting the above into ghci for example, then asking for >>> ":t >>> fs"? >>> Or am I misunderstanding your point? >>> >>> Cheers, >>> Zsolt >>> >>>> If it is not possible in Haskell, is there another language with >>>> static typing which allows this? >>>> >>>> Thanks, >>>> Vladimir >>>> _______________________________________________ >>>> Haskell-Cafe mailing list >>>> Haskell-Cafe@haskell.org >>>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>>> >>> >> > > From ryani.spam at gmail.com Sun Jun 7 05:15:26 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Sun Jun 7 04:59:11 2009 Subject: [Haskell-cafe] Question on rank-N polymorphism In-Reply-To: <4770d2590906061506w16d44af1i9a23bd0c6c1c5387@mail.gmail.com> References: <4770d2590906061506w16d44af1i9a23bd0c6c1c5387@mail.gmail.com> Message-ID: <2f9b2d30906070215k493111bo961fa162bb352be9@mail.gmail.com> This is a really interesting question. So, fs is well-typed in Haskell: fs :: (((a,a) -> a) -> t) -> (t,t) i.e. fs id :: ((a,a) -> a, (a,a) -> a) However, I believe what you are asking is for fs to be equivalent to the following: > fs2 f g = (f fst, g snd) which has the type fs2 :: (((a, b) -> a) -> t) -> (((a1, b1) -> b1) -> t1) -> (t, t1) except with the argument broadcast polymorphically to both positions. This means the argument must have the multitype g :: ((a,b) -> a) -> t /\ ((a1,b1) -> b1) -> t1 for some t and t1 which are functions of a,b and a1,b1. Unfortunately I don't believe it is possible to encode this type in System F or System F(c), the underlying lambda-calculus used by GHC, so Haskell isn't going to be able to solve this problem. But there are statically typed languages which can solve this problem. You can take the big hammer of dependent types, and write fs something like this (not Haskell; this is a dependently-typed language): typeof_g :: (Type -> Type -> Type -> Type) -> Type typeof_g res_type = (a :: Type) -> (b :: Type) -> (c :: Type) -> ((a,b) -> c) -> res_type a b c fs :: (res_type :: Type -> Type -> Type -> Type) -> (g :: typeof_g res_type) -> (a :: Type) -> (b :: Type) -> (res_type a b a, res_type a b b) fs _ g a b = (g a b a fst, g a b b snd) So, you'd write fs id like this: > fs (\a b c. (a,b) -> c) (\a b c. id ((a,b) -> c)) This is a fascinating problem, though. What put you on this path? -- ryan On Sat, Jun 6, 2009 at 3:06 PM, Vladimir Reshetnikov wrote: > Hi, > > I have the following code: > > -------------------------------------------------------------------------------- > fs g = (g fst, g snd) > examples = (fs fmap, fs liftA, fs liftM, fs id, fs ($(1,"2")), fs > ((,)id), fs (:[]), fs repeat) > -------------------------------------------------------------------------------- > > The idea is that fs accepts a polymorphic function as its argument. > What type signature can I specify for f in order to compile this code? > If it is not possible in Haskell, is there another language with > static typing which allows this? > > Thanks, > Vladimir > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From magnus at therning.org Sun Jun 7 05:47:28 2009 From: magnus at therning.org (Magnus Therning) Date: Sun Jun 7 05:31:22 2009 Subject: [Haskell-cafe] totally confused about Haskell namespace issue conventions In-Reply-To: <5ae4f2ba0906070026t413927acl7bf2d28912663976@mail.gmail.com> References: <5ae4f2ba0906070026t413927acl7bf2d28912663976@mail.gmail.com> Message-ID: <4A2B8CB0.3050109@therning.org> Vasili I. Galchin wrote: > Hello, > > Should namespace designation be specified in modules or in the > .cabal file? Or to put it another way should a relative namespace be > specified in a Haskell module and the remaining "top" part be specified > in the associated .cabal file? Of course, yes/no answers are probably > not sufficient ... i.e. please elaborate. This is my, probably incomplete, understanding of how things work. The module statement at the top of a Haskell source file should contain the complete name, e.g. module Foo.Bar.Baz If you use GHC directly to build (e.g. using --make) then it will look for the module above at $x/Foo/Bar/Baz.hs, where $x is on of the paths where GHC has been told to look (e.g. using -i). In a Cabal file you mention the complete names of module you use/build (e.g. Foo.Bar.Baz above). Hs-Source-Dirs adds directories to the paths where GHC looks for modules ($x above). /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 197 bytes Desc: OpenPGP digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090607/472a142a/signature.bin From ajsavige at yahoo.com.au Sun Jun 7 05:59:34 2009 From: ajsavige at yahoo.com.au (Andrew Savige) Date: Sun Jun 7 05:43:19 2009 Subject: [Haskell-cafe] Roman to Decimal Algorithms Message-ID: <19197.6066.qm@web56405.mail.re3.yahoo.com> I recently played in a code golf Roman to Decimal challenge (in Perl, Python, Ruby and PHP). In playing this game, I found some interesting short algorithms for converting from Roman Numerals to Decimal. Because I think some of these are new, I'd like to present them here, in case they are not really new after all, or in case there are problems with these algorithms that I've overlooked. I'd like to eventually write up a "rosetta code" article comparing the implementation of these algorithms in various languages, including Haskell. Since I'm only a very occasional Haskell programmer, I thought it best to get feedback from Haskell experts before inflicting any of my Haskell code on a wider audience. Hence this post. To keep this post reasonably brief, note that these algorithms are for "modern" Roman Numerals only, limited to the range 1-3999, and with no error checking. That is, the code below assumes that the input is always a well formed Roman Numeral. I have tested each algorithm against every modern Roman Numeral in the range 1-3999. As a starting point, note this "HaskellWiki" function: romanToInt :: String -> Int romanToInt = fst ????????????? . foldr (\p (t,s) -> if p >= s then (t+p,p) else (t-p,p)) (0,0) ????????????? . map (fromJust . flip lookup (zip "IVXLCDM" [1,5,10,50,100,500,1000])) taken from http://haskell.cs.yale.edu/haskellwiki/Roman_numerals. I'm going to essentially duplicate the functionality of this code. {-# OPTIONS_GHC -fglasgow-exts -Wall #-} import Data.Char (toUpper) rtoa :: Char -> Int rtoa 'M' = 1000 rtoa 'D' =? 500 rtoa 'C' =? 100 rtoa 'L' =?? 50 rtoa 'X' =?? 10 rtoa 'V' =??? 5 rtoa 'I' =??? 1 rtoa r?? = error $ "Invalid rtoa char:" ++ show r urtoa :: Char -> Int urtoa = rtoa . toUpper romanToInt :: String -> Int romanToInt = foldl1 (\t n -> t+n-t`mod`n*2) . map urtoa The essential difference between this solution and the HaskellWiki one is the use of the "running total" for state rather than the "previous value". I see this as an improvement mainly because it is shorter -- though you might argue that it is less clear. An alternative way to express the romanToInt function is: romanToInt = foldl (\t c -> t+(urtoa c)-t`mod`(urtoa c)*2) 0 I'm open to persuasion as to which is better Haskell style. Since I'm not playing golf anymore, the rtoa function above, though hardly short, seemed to me to be the simplest and clearest way to express converting a single Roman Numeral to its corresponding arabic number. Again, suggestions for the "best"/most efficient way to do this in Haskell are most welcome. A common, and often winning technique, in golf is to perform these sorts of conversions by concocting a "magic formula". For fun, I rewrote rtoa using a magic formula I used in the golf game: rtoa c = 10^(205558`mod`(ord c)`mod`7)`mod`9995 I'm not suggesting that magic formulae are useful outside of golf and this second rtoa function, though shorter, is much less clear. I might add that this particular magic formula appears to be less useful in Haskell golf than the other languages because `mod` is five times longer than the % operator of the other languages. :) By way of explanation, notice that this formula: ?205558`mod`(ord c)`mod`7 maps I->0, X->1, C->2, M->3, V->4, L->5, D->6 as shown below: ?Roman?? m????? 10^m?? 10^m`mod`9995 ?-----?? -????? -----? ------------- ?? M???? 3?????? 1000????? 1000 ?? D???? 6??? 1000000?????? 500 ?? C???? 2??????? 100?????? 100 ?? L???? 5???? 100000??????? 50 ?? X???? 1???????? 10??????? 10 ?? V???? 4????? 10000???????? 5 ?? I???? 0????????? 1???????? 1 Noticing this, you can replace the 205558`mod`(ord c)`mod`7 magic formula with a function that returns a string index (index() in Perl and Python). I am sometimes overwhelmed by the quantity and richness of all the functions in the GHC Haskell libraries. I eventually found a Haskell solution that seemed to work: {-# OPTIONS_GHC -fglasgow-exts -XOverloadedStrings -Wall #-} import Data.ByteString.Char8 (elemIndex) import Data.Maybe (fromJust) rtoa c = 10^(fromJust (elemIndex c "IXCMVLD"))`mod`9995 I got this to work by trial and error and have no clue what this "-XOverloadedStrings" and "Data.ByteString.Char8" business really means. If there is a better Haskell way of finding the numeric index of a particular character in a string, please let me know. Alternatively, you could write the rtoa function using an approach taken from the original HaskellWiki solution: rtoa = fromJust . flip lookup (zip "IVXLCDM" [1,5,10,50,100,500,1000]) What is your recommendation as to the "best"/most efficient way of writing the rtoa function in Haskell? Finally, here is an example complete test program. Suggestions for improving the style of this code are welcome. {-# OPTIONS_GHC -fglasgow-exts -Wall #-} import Data.Char (toUpper) import Data.List (concat, intersperse) rtoa :: Char -> Int rtoa 'M' = 1000 rtoa 'D' =? 500 rtoa 'C' =? 100 rtoa 'L' =?? 50 rtoa 'X' =?? 10 rtoa 'V' =??? 5 rtoa 'I' =??? 1 rtoa r?? = error $ "Invalid rtoa char:" ++ show r urtoa :: Char -> Int urtoa = rtoa . toUpper -- one is derived from http://haskell.cs.yale.edu/haskellwiki/Roman_numerals one :: String -> Int one = fst . foldr (\p (t,s) -> if p >= s then (t+p,p) else (t-p,p)) (0,0) . map urtoa two :: String -> Int two = foldl1 (\t n -> t+n-t`mod`n*2) . map urtoa three :: String -> Int three = foldl (\t c -> t+(urtoa c)-t`mod`(urtoa c)*2) 0 myshow :: String -> (String -> Int) -> String -> String myshow capt fn val = capt ++ val ++ " " ++ (show (fn val)) testdata :: [String] testdata =? [ "I", "xiv", "DXVI", "CMLXIII" ] main :: IO () main = do ? putStrLn $ (concat $ intersperse "\n" (map (\c -> (myshow "one? : " one? c))? testdata)) ? putStrLn $ (concat $ intersperse "\n" (map (\c -> (myshow "two? : " two c))?? testdata)) ? putStrLn $ (concat $ intersperse "\n" (map (\c -> (myshow "three: " three c)) testdata)) Cheers, /-\ Need a Holiday? Win a $10,000 Holiday of your choice. Enter now.http://us.lrd.yahoo.com/_ylc=X3oDMTJxN2x2ZmNpBF9zAzIwMjM2MTY2MTMEdG1fZG1lY2gDVGV4dCBMaW5rBHRtX2xuawNVMTEwMzk3NwR0bV9uZXQDWWFob28hBHRtX3BvcwN0YWdsaW5lBHRtX3BwdHkDYXVueg--/SIG=14600t3ni/**http%3A//au.rd.yahoo.com/mail/tagline/creativeholidays/*http%3A//au.docs.yahoo.com/homepageset/%3Fp1=other%26p2=au%26p3=mailtagline From ttencate at gmail.com Sun Jun 7 06:51:41 2009 From: ttencate at gmail.com (Thomas ten Cate) Date: Sun Jun 7 06:35:27 2009 Subject: [Haskell-cafe] using phantom types to validate html In-Reply-To: <775c14610906061141j5bc89aa2h8908bfde25163178@mail.gmail.com> References: <775c14610906061141j5bc89aa2h8908bfde25163178@mail.gmail.com> Message-ID: I have been thinking about this same problem a while ago, and found that HaXml [1] can generate Haskell types from a DTD schema. However, the code that you need to build HTML from that is quite verbose. Being no expert in Haskell, I talked to Twan van Laarhoven, who came up with something [2] that looks quite similar to your solution. It allows you to write stuff like this: test = html $ body [p ["x",em "y"], ul [li "1", li "2"]] Your use of phantom types looks a lot like his. The main difference with your solution is that Twan's generates strings right away, instead of using an intermediate data structure. Whether or not this is desirable depends on the application, I guess. A slight disadvantage is that the monomorphism restriction doesn't allow you to use the same value as children of two nodes of different types. In practice, this will probably not occur often. The linked file provides a workaround, but NoMonomorphismRestriction will of course also work. Generating such code for the full HTML spec, or any XML for that matter, while also including more advanced validation rules like "only 1 head section" would be an interesting exercise. If you manage to pull this off, I'm definitely interested. Hope this helps, Thomas [1] http://www.cs.york.ac.uk/fp/HaXml/ [2] http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2581#a2582 On Sat, Jun 6, 2009 at 20:41, Mathijs Kwik wrote: > Hi all, > > Please have a look at > http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2575#a2575 > I wanted to use the typesystem to mandate businesslogic (in this case > w3c validation rules). > Thanks to some helpful people in #haskell I learned a bit about phantom types. > Please let me know if I implemented them correctly. > > Also this little experiment raises some questions: > The code becomes very verbose if there are more elements added or more > rules to check. > Since repetitive code can be a source of error, and hellish to > maintain, I would like to know if there's some way to get this > generated, or maybe there's some meta-programming stuff I don't know > about. > Another thing I can't figure out yet is how to do more advanced > validation rules like "an html element cannot have 2 head sections", > or (made up) "a span element isn't allowed to be a child(any level > deep) of a p element". > > I think this would ask for an exponentially growing number of strange > types and classes. Am I right? > > Just to be clear: this is just some practice to use the typesystem. > I'm well aware that just using runtime validation checks will be a lot > easier and clearer in most cases. > > Thanks, > Mathijs > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From deniz.a.m.dogan at gmail.com Sun Jun 7 07:18:28 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Sun Jun 7 07:02:14 2009 Subject: [Haskell-cafe] xmobar plugin to show connectivity Message-ID: <7b501d5c0906070418s78f766e7o1530b35e359b7c1c@mail.gmail.com> Hi I'd like an xmobar plugin which in one way or another displays whether or not I'm connected to some network, i.e. if my network interface has an IP address. Has something liket his been done already? If not, what would be the best way to do this? -- Deniz Dogan From apfelmus at quantentunnel.de Sun Jun 7 07:38:19 2009 From: apfelmus at quantentunnel.de (Heinrich Apfelmus) Date: Sun Jun 7 07:22:16 2009 Subject: [Haskell-cafe] Re: using phantom types to validate html In-Reply-To: <775c14610906061141j5bc89aa2h8908bfde25163178@mail.gmail.com> References: <775c14610906061141j5bc89aa2h8908bfde25163178@mail.gmail.com> Message-ID: Mathijs Kwik wrote: > > http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2575#a2575 > I wanted to use the typesystem to mandate businesslogic (in this case > w3c validation rules). You may want to have a look at Peter Thiemann's WASH/HTML http://www.informatik.uni-freiburg.de/~thiemann/WASH/#washhtml which can statically ensure that only well-formed (with a few minor caveats I think) HTML is generated. Regards, apfelmus -- http://apfelmus.nfshost.com From ryani.spam at gmail.com Sun Jun 7 08:32:16 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Sun Jun 7 08:16:01 2009 Subject: [Haskell-cafe] Question on rank-N polymorphism In-Reply-To: <4770d2590906070228v6174a8e2tad793c840df1378f@mail.gmail.com> References: <4770d2590906061506w16d44af1i9a23bd0c6c1c5387@mail.gmail.com> <2f9b2d30906070215k493111bo961fa162bb352be9@mail.gmail.com> <4770d2590906070228v6174a8e2tad793c840df1378f@mail.gmail.com> Message-ID: <2f9b2d30906070532t51409c33y9a3b294a09ac1851@mail.gmail.com> Well, I don't really recommend programming in dependently typed languages right now :) But if you must, Agda has been getting a lot of attention recently. Also, the theorem prover Coq is based on the dependently-typed lambda calculus. In Haskell, giving a function an intersection type is generally done with typeclasses. You can write, for example: class Fs a where type FsResult a fs :: a -> FsResult a data Fmap = Fmap instance Fs Fmap where type FsResult a = forall f a b. Functor f => (f (a,b) -> f a, f (a,b) -> f b) fs Fmap = (fmap fst, fmap snd) (although this seems unusable to me!) You can also use Template Haskell to copy the argument: -- I may have the syntax wrong here fs :: a -> Q Exp fs a = [e| ($a fst, $a snd) ] test :: (Int, String) test = $(fs (`id` (1,"2")) -- ryan On Sun, Jun 7, 2009 at 2:28 AM, Vladimir Reshetnikov wrote: > Hi Ryan, > > Thanks for your explanation. What language with dependent types would > you recommend me to look at? > > Now I am studying rank-N polymorphism in Haskell and trying to > generalize some combinators in my libraries to multitypes. This is how > I came to this question. > > Thanks, > Vladimir > > On 6/7/09, Ryan Ingram wrote: >> This is a really interesting question. >> >> So, fs is well-typed in Haskell: >> ? ?fs :: (((a,a) -> a) -> t) -> (t,t) >> i.e. >> ? ?fs id :: ((a,a) -> a, (a,a) -> a) >> >> However, I believe what you are asking is for fs to be equivalent to >> the following: >>> fs2 f g = (f fst, g snd) >> >> which has the type >> fs2 :: (((a, b) -> a) -> t) -> (((a1, b1) -> b1) -> t1) -> (t, t1) >> >> except with the argument broadcast polymorphically to both positions. >> >> This means the argument must have the multitype >> >> g :: ((a,b) -> a) -> t ?/\ ?((a1,b1) -> b1) -> t1 >> >> for some t and t1 which are functions of a,b and a1,b1. >> >> Unfortunately I don't believe it is possible to encode this type in >> System F or System F(c), the underlying lambda-calculus used by GHC, >> so Haskell isn't going to be able to solve this problem. ?But there >> are statically typed languages which can solve this problem. >> >> You can take the big hammer of dependent types, and write fs something >> like this (not Haskell; this is a dependently-typed language): >> >> typeof_g :: (Type -> Type -> Type -> Type) -> Type >> typeof_g res_type = (a :: Type) -> (b :: Type) -> (c :: Type) -> >> ((a,b) -> c) -> res_type a b c >> >> fs :: (res_type :: Type -> Type -> Type -> Type) -> (g :: typeof_g >> res_type) >> ? -> (a :: Type) -> (b :: Type) -> (res_type a b a, res_type a b b) >> fs _ g a b = (g a b a fst, g a b b snd) >> >> So, you'd write fs id like this: >>> fs (\a b c. (a,b) -> c) (\a b c. id ((a,b) -> c)) >> >> This is a fascinating problem, though. ?What put you on this path? >> >> ? -- ryan >> >> On Sat, Jun 6, 2009 at 3:06 PM, Vladimir >> Reshetnikov wrote: >>> Hi, >>> >>> I have the following code: >>> >>> -------------------------------------------------------------------------------- >>> fs g = (g fst, g snd) >>> examples = (fs fmap, fs liftA, fs liftM, fs id, fs ($(1,"2")), fs >>> ((,)id), fs (:[]), fs repeat) >>> -------------------------------------------------------------------------------- >>> >>> The idea is that fs accepts a polymorphic function as its argument. >>> What type signature can I specify for f in order to compile this code? >>> If it is not possible in Haskell, is there another language with >>> static typing which allows this? >>> >>> Thanks, >>> Vladimir >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> Haskell-Cafe@haskell.org >>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>> >> > From briqueabraque at yahoo.com Sun Jun 7 11:06:31 2009 From: briqueabraque at yahoo.com (=?ISO-8859-1?Q?Maur=ED=ADcio?=) Date: Sun Jun 7 10:50:32 2009 Subject: [Haskell-cafe] Re: totally confused about Haskell namespace issue conventions In-Reply-To: <5ae4f2ba0906070123t59eb4d67tecd1a7ad42d44859@mail.gmail.com> References: <5ae4f2ba0906070026t413927acl7bf2d28912663976@mail.gmail.com> <5ae4f2ba0906070046gb2c07e6m84d9ba866495ddd3@mail.gmail.com> <5ae4f2ba0906070123t59eb4d67tecd1a7ad42d44859@mail.gmail.com> Message-ID: > as far as namespace is concerned what is division between a module's > name and it's associated .cabal with it's Hs-Source-Dirs directive? This > is kinda' absolute vs relative path I think. Vasili, First, let's talk about Haskell modules, without mentioning cabal. When Haskell 98 standard came, modules had just a name, like, say, 'Complex'. You can still see those names in GHC library for compatibility: http://www.haskell.org/ghc/docs/latest/html/libraries Another interesting think you can see in that link is the separation of modules into 'packages'. Right to the name of every module there's a package name, like 'haskell98', 'base', 'stm-2.1.1.2' etc. GHC and others adopted the convention of using dot in module names to have a standard way of showing hierarchy between modules. There's also a convention used in GHC (and others?) of allowing only one module per file and, when looking for such file (as in --make) compose the search path with the module name, replacing dots by the start of a sub-directory name. So: suppose your search path (a colon separate list of directories) is '.:/hs:sub' and GHC wants a file for module Data.Our.Test. Then it looks for: ./Data.Our.Test /hs/Data.OurTest ./sub/Data.OurTest You can find details on that (like how to add to the search path) here: http://www.haskell.org/ghc/docs/latest/html/users_guide/separate-compilation.html Now about .cabal file. When you use it, it helps you generate a package. In 'hs-source-dirs' you say what is the search path. In 'exposed-modules' you say wich modules are going to be seen by users of your package. You can also use 'other-modules' to name modules your package needs but are not going to be visible to other packages. Just say if anything is not clear. Best, Maur?cio From wss at Cs.Nott.AC.UK Sun Jun 7 12:20:04 2009 From: wss at Cs.Nott.AC.UK (Wouter Swierstra) Date: Sun Jun 7 12:08:26 2009 Subject: [Haskell-cafe] Question on rank-N polymorphism In-Reply-To: <4770d2590906061506w16d44af1i9a23bd0c6c1c5387@mail.gmail.com> References: <4770d2590906061506w16d44af1i9a23bd0c6c1c5387@mail.gmail.com> Message-ID: <28549CCF-6F7F-406D-A4FE-75190F6F7A4E@cs.nott.ac.uk> > The idea is that fs accepts a polymorphic function as its argument. > What type signature can I specify for f in order to compile this code? As you said yourself, you need to add a type signature to fs: > {-# LANGUAGE RankNTypes #-} > > fs :: ((forall a . ((a, a) -> a)) -> t) -> (t, t) > fs g = (g fst, g snd) > > examples = (fs id, fs repeat, fs (\x -> [x]), fs ((,)id)) Hope this helps, Wouter This message has been checked for viruses but the contents of an attachment may still contain software viruses, which could damage your computer system: you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. From rendel at cs.au.dk Sun Jun 7 12:47:31 2009 From: rendel at cs.au.dk (Tillmann Rendel) Date: Sun Jun 7 12:31:26 2009 Subject: [Haskell-cafe] Roman to Decimal Algorithms In-Reply-To: <19197.6066.qm@web56405.mail.re3.yahoo.com> References: <19197.6066.qm@web56405.mail.re3.yahoo.com> Message-ID: <4A2BEF23.9080508@cs.au.dk> Hi Andrew, Andrew Savige wrote: > Noticing this, you can replace the 205558`mod`(ord c)`mod`7 magic > formula with a function that returns a string index (index() in > Perl and Python). I am sometimes overwhelmed by the quantity and > richness of all the functions in the GHC Haskell libraries. Have you tried hoogle? http://haskell.org/hoogle/?hoogle=String+-%3E+Maybe+Int This suggests Data.List.elemIndex. Tillmann From ptrash at web.de Sun Jun 7 13:39:15 2009 From: ptrash at web.de (ptrash) Date: Sun Jun 7 13:23:04 2009 Subject: [Haskell-cafe] comprehension problem In-Reply-To: References: <23858359.post@talk.nabble.com> Message-ID: <23913380.post@talk.nabble.com> Cool, thanks a lot. Ross Mellgren wrote: > > P Float is the constructor to create a value of this type, similar to > data declarations. > > That is, 0.5 :: Float, P 0.5 :: Probability > > The {} notation after D creates a record accessor, also similar to > data declarations. It's equivalent to making an unD that unwraps the > value yourself: > > newtype Dist a = D { unD :: [(a, Probability)] } > > is the same as > > newtype Dist a = D [(a, Probability)] > > unD :: Dist a -> [(a, Probability)] > unD (D x) = x > > a in Dist a is a type variable, for example you could have Dist Float > (containing [(Float, Probability)]), or Dist String (containing > [(String, Probability)]) > > -Ross > > On Jun 3, 2009, at 4:01 PM, ptrash wrote: > >> >> Hi, >> >> what does this to code rows mean: >> >> newtype Probability = P Float >> newtype Dist a = D {unD :: [(a, Probability)]} >> >> newtype definies a new type called Probability. But what does P >> Float mean? >> >> And what is the a in Dist a? >> What does D {...} mean? >> >> Thanks for your help. >> -- >> View this message in context: >> http://www.nabble.com/comprehension-problem-tp23858359p23858359.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 > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- View this message in context: http://www.nabble.com/comprehension-problem-tp23858359p23913380.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From ptrash at web.de Sun Jun 7 13:41:56 2009 From: ptrash at web.de (ptrash) Date: Sun Jun 7 13:25:40 2009 Subject: [Haskell-cafe] Change value of a variable Message-ID: <23913404.post@talk.nabble.com> Hi, how can I change the value of a variable. let x = 1 x = x + 2 First I set the value of x to 1. Then I want to increase it by 2. This way doesn't work, because I think it is a infinite expression. Is there a way to change the value? -- View this message in context: http://www.nabble.com/Change-value-of-a-variable-tp23913404p23913404.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From bulat.ziganshin at gmail.com Sun Jun 7 14:01:31 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Jun 7 13:45:28 2009 Subject: [Haskell-cafe] Change value of a variable In-Reply-To: <23913404.post@talk.nabble.com> References: <23913404.post@talk.nabble.com> Message-ID: <1886439980.20090607220131@gmail.com> Hello ptrash, Sunday, June 7, 2009, 9:41:56 PM, you wrote: > Hi, how can I change the value of a variable. there are no variables in haskell :))) x, like any other identifier, is a value. when you translate to Haskell some algo that needs to update variable contents, you may either 1) use recursion: length (x:xs) = 1 + length xs length [] = 0 2) use references (IORef). like in C, references by itself are non-mutable, but they point to values that can be mutated -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From martijn at van.steenbergen.nl Sun Jun 7 14:25:15 2009 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Sun Jun 7 14:09:18 2009 Subject: [Haskell-cafe] Roman to Decimal Algorithms In-Reply-To: <19197.6066.qm@web56405.mail.re3.yahoo.com> References: <19197.6066.qm@web56405.mail.re3.yahoo.com> Message-ID: <4A2C060B.5050407@van.steenbergen.nl> Hi Andrew, I haven't read your whole message but if shortness is your goal, here are some ideas: Andrew Savige wrote: > rtoa c = 10^(205558`mod`(ord c)`mod`7)`mod`9995 > > I'm not suggesting that magic formulae are useful outside of golf and > this second rtoa function, though shorter, is much less clear. I might > add that this particular magic formula appears to be less useful in > Haskell golf than the other languages because `mod` is five times > longer than the % operator of the other languages. :) Why not rename mod like so? (%)=mod rtoa c=10^(205558%ord c%7)%9995 > Alternatively, you could write the rtoa function using an approach > taken from the original HaskellWiki solution: > > rtoa = fromJust . flip lookup (zip "IVXLCDM" [1,5,10,50,100,500,1000]) You can write this as: Just rtoa=flip lookup (zip "IVXLCDM" [1,5,10,50,100,500,1000]) Which is another few characters shorter. :-) HTH, Martijn. From keithshep at gmail.com Sun Jun 7 14:46:30 2009 From: keithshep at gmail.com (Keith Sheppard) Date: Sun Jun 7 14:30:16 2009 Subject: [Haskell-cafe] Change value of a variable In-Reply-To: <23913404.post@talk.nabble.com> References: <23913404.post@talk.nabble.com> Message-ID: <92e42b740906071146w4befe3b5kda9b449462e46c29@mail.gmail.com> I guess the short answer is that it is not possible. 'x' is immutable and if you want a different value than 'x' that expression has to be given a different name like: let x=1 y=x+2 ... But I'm not sure if that helps you. Haskell does things very differently than the imperative languages and forces you to think differently about how to solve problems. When I started learning haskell I found that I had to think more about composing/decomposing expressions and less about sequencing actions and side effects like you do in most of the more popular languages (I really have come to prefer the Haskell way). I think we may be able to give a more helpful answer if give a more high level algorithm/use case... why do you want to change the value of x -Keith On Sun, Jun 7, 2009 at 1:41 PM, ptrash wrote: > > Hi, how can I change the value of a variable. > > let x = 1 > x = x + 2 > > First I set the value of x to 1. Then I want to increase it by 2. This way > doesn't work, because I think it is a infinite expression. > > Is there a way to change the value? > > > -- > View this message in context: http://www.nabble.com/Change-value-of-a-variable-tp23913404p23913404.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 > -- keithsheppard.name From ptrash at web.de Sun Jun 7 15:03:55 2009 From: ptrash at web.de (ptrash) Date: Sun Jun 7 14:47:38 2009 Subject: [Haskell-cafe] Change value of a variable In-Reply-To: <23913404.post@talk.nabble.com> References: <23913404.post@talk.nabble.com> Message-ID: <23914185.post@talk.nabble.com> Hi, thanks for the answers. I want to make something like a counter. I have written a recursive method which for example runs x times and counts how many times it runs, and also count some other thinks. Add the end I want a statistic about certain thinks returned by the method. -- View this message in context: http://www.nabble.com/Change-value-of-a-variable-tp23913404p23914185.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From bulat.ziganshin at gmail.com Sun Jun 7 15:21:50 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Jun 7 15:06:14 2009 Subject: [Haskell-cafe] Change value of a variable In-Reply-To: <23914185.post@talk.nabble.com> References: <23913404.post@talk.nabble.com> <23914185.post@talk.nabble.com> Message-ID: <1892769985.20090607232150@gmail.com> Hello ptrash, Sunday, June 7, 2009, 11:03:55 PM, you wrote: > Hi, thanks for the answers. > I want to make something like a counter. I have written a recursive method > which for example runs x times and counts how many times it runs, and also > count some other thinks. Add the end I want a statistic about certain thinks > returned by the method. then the best way is to add this counter as one more param of recursive procedure -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From deniz.a.m.dogan at gmail.com Sun Jun 7 15:23:17 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Sun Jun 7 15:07:01 2009 Subject: [Haskell-cafe] Change value of a variable In-Reply-To: <23914185.post@talk.nabble.com> References: <23913404.post@talk.nabble.com> <23914185.post@talk.nabble.com> Message-ID: <7b501d5c0906071223t49451ag26b36b1c404ccc87@mail.gmail.com> 2009/6/7 ptrash : > > Hi, thanks for the answers. > > I want to make something like a counter. I have written a recursive method > which for example runs x times and counts how many times it runs, and also > count some other thinks. Add the end I want a statistic about certain thinks > returned by the method. Depending on exactly what you want, you may or may not want to look into monads, specifically the State or Writer monad. Could you give some more specific details on what you are trying to accomplish? -- Deniz Dogan From ketil at malde.org Sun Jun 7 15:26:33 2009 From: ketil at malde.org (Ketil Malde) Date: Sun Jun 7 15:09:56 2009 Subject: [Haskell-cafe] Change value of a variable In-Reply-To: <23914185.post@talk.nabble.com> (ptrash@web.de's message of "Sun\, 7 Jun 2009 12\:03\:55 -0700 \(PDT\)") References: <23913404.post@talk.nabble.com> <23914185.post@talk.nabble.com> Message-ID: <87y6s3onfa.fsf@malde.org> ptrash writes: > I want to make something like a counter. I have written a recursive method > which for example runs x times and counts how many times it runs, and also > count some other thinks. Add the end I want a statistic about certain thinks > returned by the method. Keep in mind that a function's result depends only on its parameters, so any state you want to retain must be part of the parameters. So you might be looking for something like: iterateN x f y = if x == 0 then y else iterateN (x-1) f (f y) -k -- If I haven't seen further, it is by standing in the footprints of giants From ptrash at web.de Sun Jun 7 15:33:23 2009 From: ptrash at web.de (ptrash) Date: Sun Jun 7 15:17:08 2009 Subject: [Haskell-cafe] Random Number Message-ID: <23914474.post@talk.nabble.com> Hi, is the are way (or a build in method) in haskell to get a random number from a number bottom to a number top? Something like let randomNumber = random 1 30 to get a random number between 1 and 30. -- View this message in context: http://www.nabble.com/Random-Number-tp23914474p23914474.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From ptrash at web.de Sun Jun 7 15:44:18 2009 From: ptrash at web.de (ptrash) Date: Sun Jun 7 15:28:04 2009 Subject: [Haskell-cafe] Change value of a variable In-Reply-To: <23913404.post@talk.nabble.com> References: <23913404.post@talk.nabble.com> Message-ID: <23914558.post@talk.nabble.com> What i am exactly to do is this: I have a list of pupils (type Pupil = (Name, Grade)) where I store the name of the pupil and which grade he has. No I want to get the number (and average number) of each grade. Something like 10 Pupils have a A (23%), 2 Pupils have a B ( 4 %) etc -- View this message in context: http://www.nabble.com/Change-value-of-a-variable-tp23913404p23914558.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From jefferson.r.heard at gmail.com Sun Jun 7 15:51:22 2009 From: jefferson.r.heard at gmail.com (Jeff Heard) Date: Sun Jun 7 15:35:06 2009 Subject: [Haskell-cafe] Change value of a variable In-Reply-To: <23914558.post@talk.nabble.com> References: <23913404.post@talk.nabble.com> <23914558.post@talk.nabble.com> Message-ID: <4165d3a70906071251m5dd3200fne9cf275b608bb717@mail.gmail.com> Sounds like a fold to me. Try looking at the doc of either foldl/r/l' or mapAccum depending on what you want.. Then write a function for one iteration that returns the value from that iteration combined with the value from the last iteration -- Jeff On Sun, Jun 7, 2009 at 3:44 PM, ptrash wrote: > > What i am exactly to do is this: > > I have a list of pupils (type Pupil = (Name, Grade)) where I store the name > of the pupil and which grade he has. No I want to get the number (and > average number) of each grade. Something like 10 Pupils have a A (23%), 2 > Pupils have a B ( 4 %) etc > -- > View this message in context: http://www.nabble.com/Change-value-of-a-variable-tp23913404p23914558.html > Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From hiena03 at gmail.com Sun Jun 7 15:55:35 2009 From: hiena03 at gmail.com (=?ISO-8859-1?Q?Jos=E9_Prous?=) Date: Sun Jun 7 15:39:21 2009 Subject: [Haskell-cafe] Random Number In-Reply-To: <23914474.post@talk.nabble.com> References: <23914474.post@talk.nabble.com> Message-ID: look in System.Random randomRIO :: (Random a) => (a, a) -> IO a you can do randomNumber<-randomRIO (1,30) On Sun, Jun 7, 2009 at 3:33 PM, ptrash wrote: > > Hi, > > is the are way (or a build in method) in haskell to get a random number > from > a number bottom to a number top? > > Something like > > let randomNumber = random 1 30 > > to get a random number between 1 and 30. > -- > View this message in context: > http://www.nabble.com/Random-Number-tp23914474p23914474.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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090607/53fb83ef/attachment.html From gtener at gmail.com Sun Jun 7 15:55:58 2009 From: gtener at gmail.com (=?UTF-8?Q?Krzysztof_Skrz=C4=99tnicki?=) Date: Sun Jun 7 15:39:41 2009 Subject: [Haskell-cafe] Random Number In-Reply-To: <23914474.post@talk.nabble.com> References: <23914474.post@talk.nabble.com> Message-ID: <220e47b40906071255y5cf9559fp5d8b3751b81b717@mail.gmail.com> On Sun, Jun 7, 2009 at 21:33, ptrash wrote: > > Hi, > > is the are way (or a build in method) in haskell to get a random number from > a number bottom to a number top? > > Something like > > let randomNumber = random 1 30 > > to get a random number between 1 and 30. I don't mean to be rude, but did you even tried to read the documentation? The function you want is here: http://www.haskell.org/ghc/docs/latest/html/libraries/random/System-Random.html Before you ask any other questions please read this essay: http://mattgemmell.com/2008/12/08/what-have-you-tried Best regards Krzysztof Skrz?tnicki From ryani.spam at gmail.com Sun Jun 7 16:06:26 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Sun Jun 7 15:50:10 2009 Subject: [Haskell-cafe] Question on rank-N polymorphism In-Reply-To: <28549CCF-6F7F-406D-A4FE-75190F6F7A4E@cs.nott.ac.uk> References: <4770d2590906061506w16d44af1i9a23bd0c6c1c5387@mail.gmail.com> <28549CCF-6F7F-406D-A4FE-75190F6F7A4E@cs.nott.ac.uk> Message-ID: <2f9b2d30906071306m36757befvead39f3dc7df9b1f@mail.gmail.com> The most interesting example is fs ($ (1, "2")) Which I haven't been able to make typecheck. Here's some well-typed code: > fs2 f g = (f fst, g snd) > ab f = f ('a', "b") > test = fs2 ab ab > -- test2 = fs ab The question is, is it possible to write fs such that your examples typecheck and test2 also typechecks? I find this example interesting because it's the smallest example I've seen of a well-typed program which would "just work" in Scheme or Lisp, but which we can't assign a type to in Haskell. -- ryan On Sun, Jun 7, 2009 at 9:20 AM, Wouter Swierstra wrote: >> The idea is that fs accepts a polymorphic function as its argument. >> What type signature can I specify for f in order to compile this code? > > As you said yourself, you need to add a type signature to fs: > >> {-# LANGUAGE RankNTypes #-} >> > >> fs :: ((forall a . ((a, a) -> a)) -> t) -> (t, t) >> fs g = (g fst, g snd) >> >> examples = (fs id, fs repeat, fs (\x -> [x]), fs ((,)id)) > > > Hope this helps, > > ?Wouter > > > This message has been checked for viruses but the contents of an attachment > may still contain software viruses, which could damage your computer system: > you are advised to perform your own checks. Email communications with the > University of Nottingham may be monitored as permitted by UK legislation. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From bulat.ziganshin at gmail.com Sun Jun 7 16:34:18 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Jun 7 16:18:20 2009 Subject: [Haskell-cafe] Change value of a variable In-Reply-To: <23914558.post@talk.nabble.com> References: <23913404.post@talk.nabble.com> <23914558.post@talk.nabble.com> Message-ID: <677010371.20090608003418@gmail.com> Hello ptrash, Sunday, June 7, 2009, 11:44:18 PM, you wrote: > I have a list of pupils (type Pupil = (Name, Grade)) where I store the name > of the pupil and which grade he has. No I want to get the number (and > average number) of each grade. Something like 10 Pupils have a A (23%), 2 > Pupils have a B ( 4 %) etc it doesn't need variables, you just going to change your mind, Neo :) the way it may be calculated in FP is 1) sort list by grades 2) group it by grades 3) count number of elements in each group just look into Data.List functions. or, alternatively, read A Tour of the Haskell Prelude http://haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html http://undergraduate.csse.uwa.edu.au/units/CITS3211/lectureNotes/tourofprelude.html -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From lemming at henning-thielemann.de Sun Jun 7 16:36:25 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Sun Jun 7 16:21:13 2009 Subject: [Haskell-cafe] Monad transformer responsibilities In-Reply-To: <2f9b2d30906050329o41239b5ahd653964f7d4bd02d@mail.gmail.com> References: <4A28EB38.3050604@van.steenbergen.nl> <2f9b2d30906050329o41239b5ahd653964f7d4bd02d@mail.gmail.com> Message-ID: <4A2C24C9.1040708@henning-thielemann.de> Ryan Ingram schrieb: >>From what I understand, the current best practices are to build your > package dependencies like so: > > Parsec MyMonadT > MyMonadT_Parsec -- orphan instances go here > ProjectPackage > > This does mean splitting up your project into three packages, but > decouples the orphan instance into its own package where it can do the > least damage :) +1 You may also document in MyMonadT where the official orphan instance can be found (in MyMonadT_Parsec) and that no other instance should be defined. From lemming at henning-thielemann.de Sun Jun 7 16:42:22 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Sun Jun 7 16:27:42 2009 Subject: [Haskell-cafe] Monad transformer responsibilities In-Reply-To: <4A28F602.70103@web.de> References: <4A28EB38.3050604@van.steenbergen.nl> <4A28F602.70103@web.de> Message-ID: <4A2C262E.8080805@henning-thielemann.de> Stephan Friedrichs schrieb: > Hi, > > it's alomost the same problem when you're writing a library with > optional quickcheck test cases: Where to put the Arbitrary instances? > > - You can't put them into quickcheck > - You don't want to put them in the library (because of the quickcheck > dependency) ... and because there are two incompatible QuickCheck versions. > - So you have to declare them near the test cases and they're orphan > instances > > The entire project doesn't issue a single warning when compiling with > -Wall *except* two orphan instances when building the test cases... However, I had sometimes the case, where a type from another library was part of my tests and thus I needed its Arbitrary instance. I could have defined instances for the foreign types, but they would have been orphan and I risk that the library author decides to add the instances later. From iainspeed at gmail.com Sun Jun 7 16:50:18 2009 From: iainspeed at gmail.com (Iain Barnett) Date: Sun Jun 7 16:34:21 2009 Subject: [Haskell-cafe] Random Number In-Reply-To: <23914474.post@talk.nabble.com> References: <23914474.post@talk.nabble.com> Message-ID: <61EF11E6-E847-44C9-B380-669420F82B98@gmail.com> On 7 Jun 2009, at 8:33 pm, ptrash wrote: > > Hi, > > is the are way (or a build in method) in haskell to get a random > number from > a number bottom to a number top? > > Something like > > let randomNumber = random 1 30 > > to get a random number between 1 and 30. rand :: Int -> Int -> IO Int rand low high = getStdRandom (randomR (low,high)) this worked for me, I also had quite a few random questions on here a few months ago! :) Beware it is an IO int. On 7 Jun 2009, at 8:55 pm, Krzysztof Skrz?tnicki wrote: > I don't mean to be rude, but did you even tried to read the > documentation? The function you want is here: > http://www.haskell.org/ghc/docs/latest/html/libraries/random/System- > Random.html > > Before you ask any other questions please read this essay: > http://mattgemmell.com/2008/12/08/what-have-you-tried > > Best regards > > Krzysztof Skrz?tnicki > Bit harsh isn't it? He asked for an example function, not an entire program. Iain From nowgate at yahoo.com Sun Jun 7 17:47:32 2009 From: nowgate at yahoo.com (michael rice) Date: Sun Jun 7 17:31:16 2009 Subject: [Haskell-cafe] Random Number Message-ID: <305986.61730.qm@web31103.mail.mud.yahoo.com> Good essay. Try this one for a laugh: http://www.mcs.vuw.ac.nz/comp/Publications/CS-TR-02-9.abs.html A good place to begin is PDF pg. 19. Michael --- On Sun, 6/7/09, Krzysztof Skrz?tnicki wrote: From: Krzysztof Skrz?tnicki Subject: Re: [Haskell-cafe] Random Number To: "ptrash" Cc: haskell-cafe@haskell.org Date: Sunday, June 7, 2009, 3:55 PM On Sun, Jun 7, 2009 at 21:33, ptrash wrote: > > Hi, > > is the are way (or a build in method) in haskell to get a random number from > a number bottom to a number top? > > Something like > > let randomNumber = random 1 30 > > to get a random number between 1 and 30. I don't mean to be rude, but did you even tried to read the documentation? The function you want is here: http://www.haskell.org/ghc/docs/latest/html/libraries/random/System-Random.html Before you ask any other questions please read this essay: http://mattgemmell.com/2008/12/08/what-have-you-tried Best regards Krzysztof Skrz?tnicki _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090607/68f21bd9/attachment.html From ajsavige at yahoo.com.au Sun Jun 7 18:34:50 2009 From: ajsavige at yahoo.com.au (Andrew Savige) Date: Sun Jun 7 18:18:35 2009 Subject: [Haskell-cafe] Roman to Decimal Algorithms In-Reply-To: <4A2BEF23.9080508@cs.au.dk> References: <19197.6066.qm@web56405.mail.re3.yahoo.com> <4A2BEF23.9080508@cs.au.dk> Message-ID: <130975.52914.qm@web56405.mail.re3.yahoo.com> Tillmann Rendel wrote: > Have you tried hoogle? > >? http://haskell.org/hoogle/?hoogle=String+-%3E+Maybe+Int > > This suggests Data.List.elemIndex. Hadn't heard of hoogle before. Will use it from now on though. :) Hoogle's suggestion of Data.List.elemIndex works like a charm. Thanks, /-\ Need a Holiday? Win a $10,000 Holiday of your choice. Enter now.http://us.lrd.yahoo.com/_ylc=X3oDMTJxN2x2ZmNpBF9zAzIwMjM2MTY2MTMEdG1fZG1lY2gDVGV4dCBMaW5rBHRtX2xuawNVMTEwMzk3NwR0bV9uZXQDWWFob28hBHRtX3BvcwN0YWdsaW5lBHRtX3BwdHkDYXVueg--/SIG=14600t3ni/**http%3A//au.rd.yahoo.com/mail/tagline/creativeholidays/*http%3A//au.docs.yahoo.com/homepageset/%3Fp1=other%26p2=au%26p3=mailtagline From ajsavige at yahoo.com.au Sun Jun 7 18:47:23 2009 From: ajsavige at yahoo.com.au (Andrew Savige) Date: Sun Jun 7 18:31:07 2009 Subject: [Haskell-cafe] Roman to Decimal Algorithms In-Reply-To: <4A2C060B.5050407@van.steenbergen.nl> References: <19197.6066.qm@web56405.mail.re3.yahoo.com> <4A2C060B.5050407@van.steenbergen.nl> Message-ID: <541692.46367.qm@web56402.mail.re3.yahoo.com> Martijn van Steenbergen wrote: > Why not rename mod like so? > > (%)=mod > rtoa c=10^(205558%ord c%7)%9995 Thanks Martijn. My first Haskell golfing tip. :) I found I had to write it with an extra set of parens to get it to work: rtoa c=(10^(205558%ord c)%7)%9995 Though it wasn't my original intention to play Haskell golf, assuming upper case Roman Numerals, we can now write the whole thing as: (%)=mod romanToInt=foldl1(\t n->t+n-t%n*2).map(\c->(10^(205558%ord c)%7)%9995) Can anyone shorten that further? Thanks, /-\ Need a Holiday? Win a $10,000 Holiday of your choice. Enter now.http://us.lrd.yahoo.com/_ylc=X3oDMTJxN2x2ZmNpBF9zAzIwMjM2MTY2MTMEdG1fZG1lY2gDVGV4dCBMaW5rBHRtX2xuawNVMTEwMzk3NwR0bV9uZXQDWWFob28hBHRtX3BvcwN0YWdsaW5lBHRtX3BwdHkDYXVueg--/SIG=14600t3ni/**http%3A//au.rd.yahoo.com/mail/tagline/creativeholidays/*http%3A//au.docs.yahoo.com/homepageset/%3Fp1=other%26p2=au%26p3=mailtagline From iavor.diatchki at gmail.com Sun Jun 7 20:04:19 2009 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Sun Jun 7 19:48:04 2009 Subject: [Haskell-cafe] Re: Building network package on Windows In-Reply-To: <5ab17e790906062143h3968488bg577cdbe0de796bd9@mail.gmail.com> References: <5ab17e790906062143h3968488bg577cdbe0de796bd9@mail.gmail.com> Message-ID: <5ab17e790906071704h19255d38oa82b48ef842764f9@mail.gmail.com> Hello, Here is an update, in case anyone else runs into the same problem. My understanding, is that the problem was caused by a mistake in the "configure" script for the "network" package, which after (correctly) detecting that IPv6 functionality was not available on my platform, it (incorrectly) tried to "gain" this functionality by redefining the version of my platform. Concretely, apparently I have "Windows Vista Basic Home Edition", which seems to identify itself as version 0x400, while the missing functions are only available on versions of windows >= 0x501. My workaround was to: 1. checkout the network package from the repository on code.haskell.com 2. modify configure.ac to comment out the section where it sets the windows version to 0x501 3. autoreconf 4. build using the usual cabal way Another thing to watch out for: if you already have packages that were built against the old version of network, they will continue to use that. So, I had to: 1. remove all of these packages, 2. remove the old version of network (to avoid confusion), and 3. then resintall the packages. It would be nice if we had a more automatic way to do that (perhaps we do, but I don't know it?). It seems that if this is not done GHC could panic, which is what happened to me. I am not sure why that happened but I am guessing that it was related to the fact that interface to the package changed without its version changing. In general, it seems a bad idea that the same version of the network package exhibits different APIs, depending on the configuration of the underlying system. -Iavor On Sat, Jun 6, 2009 at 9:43 PM, Iavor Diatchki wrote: > Hi, > I have been trying to build the package "network" from hackage > (version 2.2.1.3) on Windows Vista, and I could really use some help. > > Building on the command line, or under cygwin completely failed > (command line due to cabal not being able to execute > something---possibly configure---although it would not say; cygwin > first due to lack of gcc, which is tested but, apparently, the outcome > ignored, and after gcc was installed some incompatibility with the > header files which were detected but reported unusable). > > I managed to build the library under MinGW with msys without serious > obstacles. ?I can also build my package against the result and all is > well. ?Unfortunately, if I try to use my package to build an > executable application I get a linker error, reporting a missing > symbol during linking: > C:\Users\diatchki\AppData\Roaming\cabal\network-2.2.1.3\ghc-6.10.3/libHSnetwork-2.2.1.3.a(Socket.o):fake:(.text+0xb014): > undefined reference to `getnameinfo' > collect2: ld returned 1 exit status > > Now, "getnameinfo" is present in the header files, and it is also > defined in the library ws2_32.a which is being passed to GHC so I am > not sure what is going on. ?Any ideas? ?Searching the web suggests > that the problem may be somehow related to the standard calling > conventions but I don't really understand. ?Also, if I understand > correctly, this functionality is related to IPv6 support, which I do > not need at the moment, so it would be great if it could be easily > disabled in some way. > > Any ideas, suggestion, workarounds, etc. would be greatly appreciated, > -Iavor > > PS: I am using GHC 6.10.3 > From mwassell at bigpond.net.au Sun Jun 7 20:26:46 2009 From: mwassell at bigpond.net.au (Mark Wassell) Date: Sun Jun 7 20:10:37 2009 Subject: [Haskell-cafe] ghci: can't load .so/.DLL for: m (addDLL: could not load DLL) / is there a libm.dll for Windows Message-ID: <4A2C5AC6.2030201@bigpond.net.au> Hello, I get this when using the logfloat package via ghci on Windows. For example *Main> :m + Data.Number.LogFloat *Main Data.Number.LogFloat> logFloat (1.0::Float) Loading package syb ... linking ... done. Loading package array-0.2.0.0 ... linking ... done. Loading package logfloat-0.12.0.1 ... can't load .so/.DLL for: m (addDLL: could not load DLL) *Main Data.Number.LogFloat> When compiling the program using ghc, it works fine. This was previously reported as a ghc bug http://hackage.haskell.org/trac/ghc/ticket/3242 where the reporter was getting the message using hipmunk. The ticket was closed as the issue was deemed to be a bug in hipmunk, not GHC. As the ticket reporter asked, what is the correct approch to get around this? I have tried specifying -lm on ghci startup line but my system doesn't seem to have a libm.dll or anything similar. Is there such a thing? Thanks Mark From wren at freegeek.org Sun Jun 7 20:51:32 2009 From: wren at freegeek.org (wren ng thornton) Date: Sun Jun 7 20:35:16 2009 Subject: [Haskell-cafe] ghci: can't load .so/.DLL for: m (addDLL: could not load DLL) / is there a libm.dll for Windows In-Reply-To: <4A2C5AC6.2030201@bigpond.net.au> References: <4A2C5AC6.2030201@bigpond.net.au> Message-ID: <4A2C6094.9000507@freegeek.org> Mark Wassell wrote: > Hello, > > I get this when using the logfloat package via ghci on Windows. For example > > *Main> :m + Data.Number.LogFloat > *Main Data.Number.LogFloat> logFloat (1.0::Float) > Loading package syb ... linking ... done. > Loading package array-0.2.0.0 ... linking ... done. > Loading package logfloat-0.12.0.1 ... can't load .so/.DLL for: m > (addDLL: could not load DLL) > *Main Data.Number.LogFloat> > > When compiling the program using ghc, it works fine. This was previously > reported as a ghc bug http://hackage.haskell.org/trac/ghc/ticket/3242 > where the reporter was getting the message using hipmunk. The ticket was > closed as the issue was deemed to be a bug in hipmunk, not GHC. > > As the ticket reporter asked, what is the correct approch to get around > this? I have tried specifying -lm on ghci startup line but my system > doesn't seem to have a libm.dll or anything similar. Is there such a thing? I don't know about a general solution, but I'd love to hear one. This is a known issue for the logfloat package using GHCi on Windows, documented[1] in the ./INSTALL file under the Windows FFI section. When using the compiler, the C functions are provided by libmingwex.a which is bundled with GHC, but for some reason the interpreter doesn't find the same library. If you need to run code in GHCi and want a workaround, you can recompile the library disabling the use of the FFI by passing the -f-useFFI flag to `runhaskell Setup.hs configure`. (I'm not sure how to do that if you're using the cabal-install tool.) This will degrade the precision of miniscule LogFloat values, but should otherwise work fine. [1] As of version 0.12.0.3 which is available from darcs: http://community.haskell.org/~wren/logfloat The only differences between 0.12.0.3 and 0.12.0.1 are in the metadata files: INSTALL, TODO, VERSION. -- Live well, ~wren From invite+yn4n5bx at facebookmail.com Sun Jun 7 22:58:49 2009 From: invite+yn4n5bx at facebookmail.com (Andrew Smith) Date: Sun Jun 7 22:42:33 2009 Subject: [Haskell-cafe] Take a look at my photos on Facebook Message-ID: Hi haskell-cafe@haskell.org, I set up a Facebook Profile where I can post my pictures, videos and events and I want to add you as a friend so you can see it. First, you need to join Facebook! Once you join, you can also create your own profile. Thanks, Andrew To join Facebook, please follow the link below: http://www.facebook.com/p.php?i=675326041&k=RZM5Y4QZR5WMZAEIS15UY&r haskell-cafe@haskell.org was invited to join Facebook by Andrew Smith. If you do not wish to receive this type of email from Facebook in the future, please click on the link below to unsubscribe. http://www.facebook.com/o.php?k=917e28&u=531922198&mid=967b97G1fb47d16G0G8 Facebook's offices are located at 1601 S. California Ave., Palo Alto, CA 94304. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090607/384a72fd/attachment.html From warren.henning at gmail.com Sun Jun 7 23:13:27 2009 From: warren.henning at gmail.com (Warren Henning) Date: Sun Jun 7 22:57:12 2009 Subject: [Haskell-cafe] Take a look at my photos on Facebook In-Reply-To: References: Message-ID: <9e5767b0906072013o4a6f2089gd2881a45a4c2cc63@mail.gmail.com> 2009/6/7 Andrew Smith : > Facebook ............................................________........................ ....................................,.-??...................``~.,.................. .............................,.-?...................................?-.,............ .........................,/...............................................?:,........ .....................,?......................................................\,..... .................../...........................................................,}.... ................./......................................................,:`^`..}.... .............../...................................................,:?........./..... ..............?.....__.........................................:`.........../..... ............./__.(.....?~-,_..............................,:`........../........ .........../(_....?~,_........?~,_....................,:`........_/........... ..........{.._$;_......?=,_.......?-,_.......,.-~-,},.~?;/....}........... ...........((.....*~_.......?=-._......?;,,./`..../?............../............ ...,,,___.\`~,......?~.,....................`.....}............../............. ............(....`=-,,.......`........................(......;_,,-?............... ............/.`~,......`-...............................\....../\................... .............\`~.*-,.....................................|,./.....\,__........... ,,_..........}.>-._\...................................|..............`=~-,.... .....`=~-,_\_......`\,.................................\........................ ...................`=~-,,.\,...............................\....................... ................................`:,,...........................`\..............__.. .....................................`=-,...................,%`>--==``....... ........................................_\..........._,-%.......`\............... ...................................,<`.._|_,-&``................`\.............. From magicloud.magiclouds at gmail.com Mon Jun 8 01:09:47 2009 From: magicloud.magiclouds at gmail.com (Magicloud Magiclouds) Date: Mon Jun 8 00:53:31 2009 Subject: [Haskell-cafe] How to convert DiffTime to a number? Message-ID: <3bd412d40906072209j26ed3e1agf49d585cb4687969@mail.gmail.com> Hi, Documents said that DiffTime could treat as "how many seconds". So how to convert it to a number of seconds? Thanks. -- ??????? ??????? From magicloud.magiclouds at gmail.com Mon Jun 8 01:44:21 2009 From: magicloud.magiclouds at gmail.com (Magicloud Magiclouds) Date: Mon Jun 8 01:28:05 2009 Subject: [Haskell-cafe] Re: How to convert DiffTime to a number? In-Reply-To: <3bd412d40906072209j26ed3e1agf49d585cb4687969@mail.gmail.com> References: <3bd412d40906072209j26ed3e1agf49d585cb4687969@mail.gmail.com> Message-ID: <3bd412d40906072244i1ed19494j1a2499a629219e5c@mail.gmail.com> Ah, floor $ toRational dt. On Mon, Jun 8, 2009 at 1:09 PM, Magicloud Magiclouds wrote: > Hi, > ?Documents said that DiffTime could treat as "how many seconds". So > how to convert it to a number of seconds? > > Thanks. > -- > ??????? > ??????? > -- ??????? ??????? From johan.tibell at gmail.com Mon Jun 8 02:47:09 2009 From: johan.tibell at gmail.com (Johan Tibell) Date: Mon Jun 8 02:31:12 2009 Subject: [Haskell-cafe] Re: Building network package on Windows In-Reply-To: <5ab17e790906071704h19255d38oa82b48ef842764f9@mail.gmail.com> References: <5ab17e790906062143h3968488bg577cdbe0de796bd9@mail.gmail.com> <5ab17e790906071704h19255d38oa82b48ef842764f9@mail.gmail.com> Message-ID: <90889fe70906072347h4c2d643eqdf68c38ad4d6cb82@mail.gmail.com> On Mon, Jun 8, 2009 at 2:04 AM, Iavor Diatchki wrote: > Hello, > Here is an update, in case anyone else runs into the same problem. > > My understanding, is that the problem was caused by a mistake in the > "configure" script for the "network" package, which after (correctly) > detecting that IPv6 functionality was not available on my platform, it > (incorrectly) tried to "gain" this functionality by redefining the > version of my platform. Concretely, apparently I have "Windows Vista > Basic Home Edition", which seems to identify itself as version 0x400, > while the missing functions are only available on versions of windows > >= 0x501. > > My workaround was to: > 1. checkout the network package from the repository on code.haskell.com > 2. modify configure.ac to comment out the section where it sets the > windows version to 0x501 > 3. autoreconf > 4. build using the usual cabal way > Do you mind filing a bug at http://trac.haskell.org/network so we can track this problem and hopefully fix it in the future (I'm afraid someone with better Windows knowledge will have to do it)? Thanks, Johan -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090608/a3ac9ea6/attachment.html From r.a.niemeijer at tue.nl Mon Jun 8 03:20:30 2009 From: r.a.niemeijer at tue.nl (Niemeijer, R.A.) Date: Mon Jun 8 03:04:33 2009 Subject: [Haskell-cafe] ANNOUNCE: StrictBench 0.1 - Benchmarking code through strict evaluation In-Reply-To: <20090607183022.1793932467A@www.haskell.org> References: <20090607183022.1793932467A@www.haskell.org> Message-ID: <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB27@EXCHANGE10.campus.tue.nl> Hello everyone, In the last month or so, I've found myself using the following snippet a lot: import Control.Parallel.Strategies import Test.BenchPress bench 1 . print . rnf This snippet fully evaluates a value and prints how long it took to do so. I regularly use it to see where the bottlenecks lie in my algorithms. It has the minor annoyance, however, that it prints a lot of information (min, max, mean, median, percentiles) that is all identical, because I only run it once. The reason I only run it once is that I'm typically evaluating a pure value, which means that any subsequent attempts to benchmark the evaluation time will take no time at all, since it has already been evaluated. To solve this, I decided to write a small library to make this process easier and only print the time taken once. The result is StrictBench, which can be found at http://hackage.haskell.org/cgi-bin/hackage-scripts/package/StrictBench. A short example: import Test.StrictBench main = bench [1..10000000 :: Integer] This code would give 2890.625 ms as output. For the rest of the documentation I refer you to the Hackage page. Regards, Remco Niemeijer From ttencate at gmail.com Mon Jun 8 03:42:50 2009 From: ttencate at gmail.com (Thomas ten Cate) Date: Mon Jun 8 03:26:32 2009 Subject: [Haskell-cafe] Re: Building network package on Windows In-Reply-To: <5ab17e790906071704h19255d38oa82b48ef842764f9@mail.gmail.com> References: <5ab17e790906062143h3968488bg577cdbe0de796bd9@mail.gmail.com> <5ab17e790906071704h19255d38oa82b48ef842764f9@mail.gmail.com> Message-ID: On Mon, Jun 8, 2009 at 02:04, Iavor Diatchki wrote: > Hello, > Here is an update, in case anyone else runs into the same problem. > > My understanding, is that the problem was caused by a mistake in the > "configure" script for the "network" package, which after (correctly) > detecting that IPv6 functionality was not available on my platform, it > (incorrectly) tried to "gain" this functionality by redefining the > version of my platform. ?Concretely, apparently I have "Windows Vista > Basic Home Edition", which seems to identify itself as version 0x400, > while the missing functions are only available on versions of windows >>= 0x501. 0x400 is, if I'm not mistaken, Windows 95. Vista is 0x600 [1]. I don't think they *identify* themselves as such; rather, the program itself specifies what Windows versions it wants to be able to run on. In particular, the macros _WIN32_WINNT and WINVER should be defined as the *minimum* platform version on which the compiled binary is to work. Therefore, if functionality from XP (0x501) is needed, it is perfectly okay to redefine these macros to 0x501. This will flip some switches in included header files that enable declarations for the desired functionality. Of course, the binary will then only run on platforms that actually have this functionality. Hope that clears things up a bit. Thomas [1] http://msdn.microsoft.com/en-us/library/aa383745.aspx From david.waern at gmail.com Mon Jun 8 03:56:58 2009 From: david.waern at gmail.com (David Waern) Date: Mon Jun 8 03:40:43 2009 Subject: [Haskell-cafe] Re: Haddock : parse error on input `{-# UNPACK' In-Reply-To: References: <20090606125614.93aca46d.mle+hs@mega-nerd.com> <20090607101205.d0e6f1f0.mle+hs@mega-nerd.com> Message-ID: 2009/6/7 Dominic Steinitz : > Ha! It's yet another of haddock's quirks. If I replace -- ^ by -- then haddock > accepts {-#. I'll update the ticket you created. > > -- | The parse state > data S = S {-# UNPACK #-} !BL.ByteString ?-- ^ input > ? ? ? ? ? {-# UNPACK #-} !Int ?-- ^ bytes read > ? ? ? ? ? {-# UNPACK #-} ![B.ByteString] > ? ? ? ? ? {-# UNPACK #-} !Int ?-- ^ the failure depth > > -- | The parse state > data S = S {-# UNPACK #-} !BL.ByteString ?-- input > ? ? ? ? ? {-# UNPACK #-} !Int ?-- bytes read > ? ? ? ? ? {-# UNPACK #-} ![B.ByteString] > ? ? ? ? ? {-# UNPACK #-} !Int ?-- the failure depth Haddock doesn't actually support comments on individual constructor arguments. People often get confused by this, and the error message isn't especially useful. We have a ticket for giving better error messages: http://trac.haskell.org/haddock/ticket/94 We also have a ticket about the feature itself: http://trac.haskell.org/haddock/ticket/95 David From r.a.niemeijer at tue.nl Mon Jun 8 04:10:10 2009 From: r.a.niemeijer at tue.nl (Niemeijer, R.A.) Date: Mon Jun 8 03:53:55 2009 Subject: [Haskell-cafe] Slow documentation generation on Hackage In-Reply-To: <20090607183022.1793932467A@www.haskell.org> References: <20090607183022.1793932467A@www.haskell.org> Message-ID: <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB6D@EXCHANGE10.campus.tue.nl> Hello everyone. Last night I uploaded my first Hackage library with documentation (StrictBench). I learned that it takes somewhere between 2 and 8 hours for the link to the documentation to become active. This is confusing for first-time package authors (I went to #haskell to ask what I had forgotten) and annoying for everyone (Don Stewart submitted it to reddit shorly after I published it, which kind of wastes the time of everyone who checks it out before the documentation is up). Moreover, there seems to be no reason for it; on your own computer haddock takes just (milli)seconds. Hence I wanted to ask if this is a bug or if there is a good technical or social reason for it, and whether there is any way around it. Regards, Remco Niemeijer From allbery at ece.cmu.edu Mon Jun 8 04:36:14 2009 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Mon Jun 8 04:20:12 2009 Subject: [Haskell-cafe] Slow documentation generation on Hackage In-Reply-To: <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB6D@EXCHANGE10.campus.tue.nl> References: <20090607183022.1793932467A@www.haskell.org> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB6D@EXCHANGE10.campus.tue.nl> Message-ID: <525C5338-5A42-4477-9532-0718D90509D3@ece.cmu.edu> On Jun 8, 2009, at 04:10 , Niemeijer, R.A. wrote: > Hence I wanted to ask if this is a bug or if there is a good > technical or social reason for it, and whether there is any way > around it. Auto-running haddock on upload strikes me as a good way to open hackage.haskell.org to a denial of service attack. Additionally, I *think* haddock is run as part of the automated build tests, which (again) happen on a regular schedule instead of being triggered by uploads to avoid potential denial of service attacks. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090608/cf388534/PGP.bin From allbery at ece.cmu.edu Mon Jun 8 04:40:43 2009 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Mon Jun 8 04:24:29 2009 Subject: [Haskell-cafe] Slow documentation generation on Hackage In-Reply-To: <525C5338-5A42-4477-9532-0718D90509D3@ece.cmu.edu> References: <20090607183022.1793932467A@www.haskell.org> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB6D@EXCHANGE10.campus.tue.nl> <525C5338-5A42-4477-9532-0718D90509D3@ece.cmu.edu> Message-ID: On Jun 8, 2009, at 04:36 , Brandon S. Allbery KF8NH wrote: > On Jun 8, 2009, at 04:10 , Niemeijer, R.A. wrote: >> Hence I wanted to ask if this is a bug or if there is a good >> technical or social reason for it, and whether there is any way >> around it. > > Auto-running haddock on upload strikes me as a good way to open > hackage.haskell.org to a denial of service attack. I should clarify: yes, in a valid project haddock takes almost no time. Nevertheless: (1) if many uploads of even valid packages are made in a very short time, the system load could well be severely impacted; (2) what of malicious packages, which might trigger bugs in haddock leading to (say) 100% CPU loops? That we don't know of any doesn't mean there aren't any, unless the test suite is absolutely 100% complete (and for a large program, that becomes as hard to verify as the program itself. now consider that haddock is part of ghc these days...). -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090608/1accd8d9/PGP.bin From r.a.niemeijer at tue.nl Mon Jun 8 05:05:59 2009 From: r.a.niemeijer at tue.nl (Niemeijer, R.A.) Date: Mon Jun 8 04:49:43 2009 Subject: [Haskell-cafe] Slow documentation generation on Hackage In-Reply-To: References: <20090607183022.1793932467A@www.haskell.org> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB6D@EXCHANGE10.campus.tue.nl> <525C5338-5A42-4477-9532-0718D90509D3@ece.cmu.edu> Message-ID: <9BEB5EF43B5A4042B60C0D8179782DB3D69443DBAD@EXCHANGE10.campus.tue.nl> If that is the main concern, would the following not work? - Hackage accounts already have to be created manually, so there is no chance of a DDoS. - Uploading to hackage requires a username and password, which means the user can be identified. Set a timeout on uploads for each user: packages sent within 2 minutes of the previous one are automatically refused. Prevents quantity-based DoS. - Generate haddock docs immediately on upload, but apply a 2-second timeout; if it takes longer, the process is killed and no documentation is generated. Prevents exploit-based DoS. - If many valid packages are uploaded in a short time (though I have my doubts as to how often that is going to happen), put them in a queue. Documentation will take a bit longer to generate, but the server can control the load. Prevents inadvertent DoS. Result: immediate documentation for every contributor with good intentions (which, face it, is going to be all of them; I doubt Haskell is popular enough yet to be the target of DoS attacks) and no possibility for DoS attacks. I might be overlooking something, but I believe this should work just fine. -----Original Message----- From: Brandon S. Allbery KF8NH [mailto:allbery@ece.cmu.edu] Sent: maandag 8 juni 2009 10:41 To: Brandon S. Allbery KF8NH Cc: Niemeijer, R.A.; haskell-cafe@haskell.org Subject: Re: [Haskell-cafe] Slow documentation generation on Hackage On Jun 8, 2009, at 04:36 , Brandon S. Allbery KF8NH wrote: > On Jun 8, 2009, at 04:10 , Niemeijer, R.A. wrote: >> Hence I wanted to ask if this is a bug or if there is a good >> technical or social reason for it, and whether there is any way >> around it. > > Auto-running haddock on upload strikes me as a good way to open > hackage.haskell.org to a denial of service attack. I should clarify: yes, in a valid project haddock takes almost no time. Nevertheless: (1) if many uploads of even valid packages are made in a very short time, the system load could well be severely impacted; (2) what of malicious packages, which might trigger bugs in haddock leading to (say) 100% CPU loops? That we don't know of any doesn't mean there aren't any, unless the test suite is absolutely 100% complete (and for a large program, that becomes as hard to verify as the program itself. now consider that haddock is part of ghc these days...). -- 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 Malcolm.Wallace at cs.york.ac.uk Mon Jun 8 05:18:34 2009 From: Malcolm.Wallace at cs.york.ac.uk (Malcolm Wallace) Date: Mon Jun 8 05:02:26 2009 Subject: [Haskell-cafe] Cabal "addressibility" problem In-Reply-To: <5ae4f2ba0906051233u351e1ef5q31dde69482a4628f@mail.gmail.com> References: <5ae4f2ba0906051233u351e1ef5q31dde69482a4628f@mail.gmail.com> Message-ID: <20090608101834.70079464.Malcolm.Wallace@cs.york.ac.uk> "Vasili I. Galchin" wrote: > Executable GraphPartitionTest > Main-Is: Swish.HaskellRDF.GraphPartitionTest.hs > Other-modules: Swish.HaskellRDF.GraphPartition > Swish.HaskellRDF.GraphClass > Swish.HaskellUtils.ListHelpers > Swish.HaskellUtils.TestHelpers The "Main-Is:" line is wrong: it should be: > Main-Is: Swish/HaskellRDF/GraphPartitionTest.hs That is, it should name a filepath (usings slashes), not a module (using dots). Regards, Malcolm From ketil at malde.org Mon Jun 8 05:24:38 2009 From: ketil at malde.org (Ketil Malde) Date: Mon Jun 8 05:08:10 2009 Subject: [Haskell-cafe] Slow documentation generation on Hackage In-Reply-To: <9BEB5EF43B5A4042B60C0D8179782DB3D69443DBAD@EXCHANGE10.campus.tue.nl> (R. A. Niemeijer's message of "Mon\, 8 Jun 2009 11\:05\:59 +0200") References: <20090607183022.1793932467A@www.haskell.org> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB6D@EXCHANGE10.campus.tue.nl> <525C5338-5A42-4477-9532-0718D90509D3@ece.cmu.edu> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DBAD@EXCHANGE10.campus.tue.nl> Message-ID: <87d49fnkmh.fsf@malde.org> "Niemeijer, R.A." writes: > If that is the main concern, would the following not work? [...] > Result: immediate documentation for every contributor with good > intentions Or simply, on upload, generate the doc directory with a temporary page saying that documentation will arrive when it's good and ready? Result: as before, but with less confusion for new contributors. So not as good as Niemeijer's suggestions, but probably easier to implement. -k -- If I haven't seen further, it is by standing in the footprints of giants From ron at gamr7.com Mon Jun 8 06:40:46 2009 From: ron at gamr7.com (Ron de Bruijn) Date: Mon Jun 8 06:24:04 2009 Subject: [Haskell-cafe] Hsmagick crash Message-ID: <4A2CEAAE.7080005@gamr7.com> Hi, I am trying to extract the image data from various file formats and it appeared that hsmagick would be the right package to use. However, it doesn't actually work or I use it incorrectly. If you have installed hsmagick and change the value of some_png_file to some existing png file, you should see that it crashes at some random pixel. For the particular 256*256 image I had, it crashed on pixel_nr `elem` [54,56,57]. I am open to suggestions for better ways to get a Array (Int,Int) RGB from e.g. a png file. import Graphics.Transform.Magick.Images import Graphics.Transform.Magick.Types import Foreign.Storable import Control.Monad image_file_name_to_2d_array file = do himage <- readImage file let ptr_to_image = image himage himage_ <- peekElemOff ptr_to_image 0 let bounds@(_rows, _cols) = (rows himage_,columns himage_) number_of_pixels = fromIntegral _rows * fromIntegral _cols mapM (\pixel_nr -> do putStrLn ("Pixel: " ++ show pixel_nr) pixel_packet <- liftM background_color_ $ peekElemOff ptr_to_image pixel_nr let red_component = red pixel_packet putStrLn ("Pixel packet: " ++ show red_component) return red_component) [0.. number_of_pixels - 1] some_png_file = "foo.png" t = do initialize_image_library image_file_name_to_2d_array some_png_file initialize_image_library = initializeMagick Best regards, Ron de Bruijn From mwassell at bigpond.net.au Mon Jun 8 06:53:58 2009 From: mwassell at bigpond.net.au (Mark Wassell) Date: Mon Jun 8 06:37:48 2009 Subject: [Haskell-cafe] Hsmagick crash In-Reply-To: <4A2CEAAE.7080005@gamr7.com> References: <4A2CEAAE.7080005@gamr7.com> Message-ID: <4A2CEDC6.9000807@bigpond.net.au> Have you tried http://hackage.haskell.org/cgi-bin/hackage-scripts/package/pngload ? Mark Ron de Bruijn wrote: > Hi, > > I am trying to extract the image data from various file formats and it > appeared that hsmagick would be the right package to use. > > However, it doesn't actually work or I use it incorrectly. If you have > installed hsmagick and change the value of some_png_file to some > existing png file, you should see that it crashes at some random > pixel. For the particular 256*256 image I had, it crashed on pixel_nr > `elem` [54,56,57]. > > I am open to suggestions for better ways to get a Array (Int,Int) RGB > from e.g. a png file. > > import Graphics.Transform.Magick.Images > import Graphics.Transform.Magick.Types > import Foreign.Storable > import Control.Monad > > image_file_name_to_2d_array file = do > himage <- readImage file > let ptr_to_image = image himage > himage_ <- peekElemOff ptr_to_image 0 > let bounds@(_rows, _cols) = (rows himage_,columns himage_) > number_of_pixels = fromIntegral _rows * fromIntegral _cols > mapM (\pixel_nr -> do > putStrLn ("Pixel: " ++ show pixel_nr) > pixel_packet <- liftM background_color_ $ > peekElemOff > ptr_to_image > pixel_nr > let red_component = red pixel_packet > putStrLn ("Pixel packet: " ++ show red_component) > return red_component) > [0.. number_of_pixels - 1] > > some_png_file = "foo.png" > > t = do > initialize_image_library > image_file_name_to_2d_array some_png_file > > initialize_image_library = initializeMagick > > Best regards, > Ron de Bruijn > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From magnus at therning.org Mon Jun 8 06:58:35 2009 From: magnus at therning.org (Magnus Therning) Date: Mon Jun 8 06:42:18 2009 Subject: [Haskell-cafe] ANNOUNCE: StrictBench 0.1 - Benchmarking code through strict evaluation In-Reply-To: <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB27@EXCHANGE10.campus.tue.nl> References: <20090607183022.1793932467A@www.haskell.org> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB27@EXCHANGE10.campus.tue.nl> Message-ID: On Mon, Jun 8, 2009 at 8:20 AM, Niemeijer, R.A. wrote: > Hello everyone, > > In the last month or so, I've found myself using the following snippet a lot: > > import Control.Parallel.Strategies > import Test.BenchPress > > bench 1 . print . rnf > > This snippet fully evaluates a value and prints how long it took to do so. I regularly use it to see where the bottlenecks lie in my algorithms. ?It has the minor annoyance, however, that it prints a lot of information (min, max, mean, median, percentiles) that is all identical, because I only run it once. The reason I only run it once is that I'm typically evaluating a pure value, which means that any subsequent attempts to benchmark the evaluation time will take no time at all, since it has already been evaluated. > > To solve this, I decided to write a small library to make this process easier and only print the time taken once. The result is StrictBench, which can be found at http://hackage.haskell.org/cgi-bin/hackage-scripts/package/StrictBench. Is there no way to force repeated evaluation of a pure value? (It'd be nice to be able to perform time measurements on pure code so that it's possible to compare Haskell implementations of algorithms to implementations in other languages, without running into confounding factors.) /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe From deduktionstheorem at web.de Mon Jun 8 07:06:30 2009 From: deduktionstheorem at web.de (Stephan Friedrichs) Date: Mon Jun 8 06:50:16 2009 Subject: [Haskell-cafe] Monad transformer responsibilities In-Reply-To: <4A2C262E.8080805@henning-thielemann.de> References: <4A28EB38.3050604@van.steenbergen.nl> <4A28F602.70103@web.de> <4A2C262E.8080805@henning-thielemann.de> Message-ID: <4A2CF0B6.7030703@web.de> Henning Thielemann wrote: > [...] > >> - So you have to declare them near the test cases and they're orphan >> instances >> >> The entire project doesn't issue a single warning when compiling with >> -Wall *except* two orphan instances when building the test cases... > > However, I had sometimes the case, where a type from another library was > part of my tests and thus I needed its Arbitrary instance. I could have > defined instances for the foreign types, but they would have been orphan > and I risk that the library author decides to add the instances later. > Hmm... maybe it is a good idea to aktivate the instance declaration with a cabal flag? I've already got: Flag Test Description: Build a binary running test cases Default: False and I could easily add something like if flag( Test ) CPP-Options: -D__TEST__ Build-Depends: QuickCheck >= 2 && < 3 and data MyType = ... #ifdef __TEST__ instance Arbitrary MyType where ... #endif A usage of cabal flags that strongly reminds me of Gentoo's useflags :) However, this will result in a total mess with more than one such flag... //Stephan -- Fr?her hie? es ja: Ich denke, also bin ich. Heute wei? man: Es geht auch so. - Dieter Nuhr From ron at gamr7.com Mon Jun 8 07:11:57 2009 From: ron at gamr7.com (Ron de Bruijn) Date: Mon Jun 8 06:55:16 2009 Subject: [Haskell-cafe] Hsmagick crash In-Reply-To: <4A2CEDC6.9000807@bigpond.net.au> References: <4A2CEAAE.7080005@gamr7.com> <4A2CEDC6.9000807@bigpond.net.au> Message-ID: <4A2CF1FD.2030805@gamr7.com> Mark Wassell schreef: > Have you tried > http://hackage.haskell.org/cgi-bin/hackage-scripts/package/pngload ? Hi Mark, I just did: import Codec.Image.PNG png_file_to_2d_array file = do either_error_string_or_png <- loadPNGFile file either (\s -> error $ "(png_file_to_2d_array) " ++ s) (\png -> putStrLn (show (dimensions png)) ) either_error_string_or_png and then calling it gives: *** Exception: (png_file_to_2d_array) failed to parse chunk "IHDR", (line 1, column 1): unexpected 0x0 expecting valid colorType: supported Ct2,Ct6 Best regards, Ron From ttencate at gmail.com Mon Jun 8 07:28:16 2009 From: ttencate at gmail.com (Thomas ten Cate) Date: Mon Jun 8 07:11:59 2009 Subject: [Haskell-cafe] Slow documentation generation on Hackage In-Reply-To: <9BEB5EF43B5A4042B60C0D8179782DB3D69443DBAD@EXCHANGE10.campus.tue.nl> References: <20090607183022.1793932467A@www.haskell.org> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB6D@EXCHANGE10.campus.tue.nl> <525C5338-5A42-4477-9532-0718D90509D3@ece.cmu.edu> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DBAD@EXCHANGE10.campus.tue.nl> Message-ID: On Mon, Jun 8, 2009 at 11:05, Niemeijer, R.A. wrote: > which, face it, is going to be all of them; I doubt Haskell > is popular enough yet to be the target of DoS attacks Second that. I think this is a good case in which some security should be traded in for usability. And even if a DoS attack occurs, it just causes some downtime... not unlike the certain hours of downtime that the documentation currently has. If there's actually an exploitable leak in Haddock that allows the server to be compromised (not just DoSed), then the current Haddock generation is just as vulnerable. But of course I'm not the maintainers of Hackage... it's up to them to decide. Thomas From ttencate at gmail.com Mon Jun 8 07:43:01 2009 From: ttencate at gmail.com (Thomas ten Cate) Date: Mon Jun 8 07:26:50 2009 Subject: [Haskell-cafe] Hsmagick crash In-Reply-To: <4A2CF1FD.2030805@gamr7.com> References: <4A2CEAAE.7080005@gamr7.com> <4A2CEDC6.9000807@bigpond.net.au> <4A2CF1FD.2030805@gamr7.com> Message-ID: On Mon, Jun 8, 2009 at 13:11, Ron de Bruijn wrote: > Mark Wassell schreef: >> Have you tried >> http://hackage.haskell.org/cgi-bin/hackage-scripts/package/pngload ? > Hi Mark, > > I just did: > > import Codec.Image.PNG > > png_file_to_2d_array file = do > ?either_error_string_or_png <- loadPNGFile file > ?either > ? ?(\s -> error $ "(png_file_to_2d_array) " ++ s) > ? ?(\png -> > ? ? ?putStrLn (show (dimensions png)) > ? ? ?) > ? ?either_error_string_or_png > > and then calling it gives: > > *** Exception: (png_file_to_2d_array) failed to parse chunk "IHDR", (line 1, > column 1): > unexpected 0x0 > expecting valid colorType: supported Ct2,Ct6 Testing this code with the PNG file from [1] gives me (png_file_to_2d_array) "PNG_transparency_demonstration_2.png" (line 1, column 1): unexpected 0x2d I guess that proves that it's not just you, but not much else. Thomas [1] http://upload.wikimedia.org/wikipedia/commons/9/9a/PNG_transparency_demonstration_2.png From martijn at van.steenbergen.nl Mon Jun 8 08:05:27 2009 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Mon Jun 8 07:49:10 2009 Subject: [Haskell-cafe] Maintaining laziness: another example Message-ID: <4A2CFE87.6060303@van.steenbergen.nl> Hello, While grading a Haskell student's work I ran into an example of a program not being lazy enough. Since it's such a basic and nice example I thought I'd share it with you: One part of the assignment was to define append :: [a] -> [a] -> [a], another to define cycle2 :: [a] -> [a]. This was her (the majority of the students in this course is female!) solution: > append :: [a] -> [a] -> [a] > append [] ys = ys > append xs [] = xs > append (x:xs) ys = x : (append xs ys) > > cycle2 :: [a] -> [a] > cycle2 [] = error "empty list" > cycle2 xs = append xs (cycle2 xs) This definition of append works fine on any non-bottom input (empty, finite, infinite), but due to the unnecessary second append case, cycle2 never produces any result. Martijn. From ekirpichov at gmail.com Mon Jun 8 08:31:19 2009 From: ekirpichov at gmail.com (Eugene Kirpichov) Date: Mon Jun 8 08:15:02 2009 Subject: [Haskell-cafe] Maintaining laziness: another example In-Reply-To: <4A2CFE87.6060303@van.steenbergen.nl> References: <4A2CFE87.6060303@van.steenbergen.nl> Message-ID: <5e0214850906080531q72df7bf4pb198b451f2a280e3@mail.gmail.com> Cool! Probably one should start teaching with 'case' instead of pattern function definitions; that would put an accent on what is forced and in what order. Only after the student understands the laziness issues, introduce pattern signatures. 2009/6/8 Martijn van Steenbergen : > Hello, > > While grading a Haskell student's work I ran into an example of a program > not being lazy enough. Since it's such a basic and nice example I thought > I'd share it with you: > > One part of the assignment was to define append :: [a] -> [a] -> [a], > another to define cycle2 :: [a] -> [a]. This was her (the majority of the > students in this course is female!) solution: > >> append :: [a] -> [a] -> [a] >> append [] ys = ys >> append xs [] = xs >> append (x:xs) ys = x : (append xs ys) >> >> cycle2 :: [a] -> [a] >> cycle2 [] = error "empty list" >> cycle2 xs = append xs (cycle2 xs) > > This definition of append works fine on any non-bottom input (empty, finite, > infinite), but due to the unnecessary second append case, cycle2 never > produces any result. > > Martijn. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- Eugene Kirpichov Web IR developer, market.yandex.ru From martijn at van.steenbergen.nl Mon Jun 8 08:56:25 2009 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Mon Jun 8 08:40:16 2009 Subject: [Haskell-cafe] ANNOUNCE: StrictBench 0.1 - Benchmarking code through strict evaluation In-Reply-To: References: <20090607183022.1793932467A@www.haskell.org> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB27@EXCHANGE10.campus.tue.nl> Message-ID: <4A2D0A79.3040102@van.steenbergen.nl> Magnus Therning wrote: > Is there no way to force repeated evaluation of a pure value? (It'd > be nice to be able to perform time measurements on pure code so that > it's possible to compare Haskell implementations of algorithms to > implementations in other languages, without running into confounding > factors.) I'm really curious about this too. My guess is that the answer is "no" because doing so would (among other things) mean a thunk have to be copied first before it is evaluated, to preserve the unevaluated version. And what guarantee is there that values further down the expression haven't been evaluated already? Efficient lazy evaluation is hard; inefficient lazy evalation is even harder. ;-) Martijn. From jac at informatik.uni-kiel.de Mon Jun 8 08:57:55 2009 From: jac at informatik.uni-kiel.de (Jan Christiansen) Date: Mon Jun 8 08:41:49 2009 Subject: [Haskell-cafe] Maintaining laziness: another example In-Reply-To: <5e0214850906080531q72df7bf4pb198b451f2a280e3@mail.gmail.com> References: <4A2CFE87.6060303@van.steenbergen.nl> <5e0214850906080531q72df7bf4pb198b451f2a280e3@mail.gmail.com> Message-ID: Hi, this is a very nice example. On 08.06.2009, at 14:31, Eugene Kirpichov wrote: > Cool! Probably one should start teaching with 'case' instead of > pattern function definitions; that would put an accent on what is > forced and in what order. I like this idea. > Only after the student understands the laziness issues, introduce > pattern signatures. But I think this will not solve the problem. Even for an experienced Haskell programmer it is not easy to check whether a function is too strict. I think it would be helpful if you define your functions using case expressions but in general you do not want to do this. For example consider the implementation of insect of Data.List. intersect xs ys = [x | x <- xs, any (==x) ys] This definition is too strict. The evaluation of intersect [] [1..] yields [] while the evaluation of intersect [1..] [] does not terminate. This function can be improved such that it yields the empty list in both cases. This function was probably not implemented by a Haskell novice ; ) Cheers, Jan From martijn at van.steenbergen.nl Mon Jun 8 09:01:40 2009 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Mon Jun 8 08:45:22 2009 Subject: [Haskell-cafe] Maintaining laziness: another example In-Reply-To: References: <4A2CFE87.6060303@van.steenbergen.nl> <5e0214850906080531q72df7bf4pb198b451f2a280e3@mail.gmail.com> Message-ID: <4A2D0BB4.6030308@van.steenbergen.nl> Jan Christiansen wrote: > This definition is too strict. The evaluation of intersect [] [1..] > yields [] while the evaluation of intersect [1..] [] does not terminate. > This function can be improved such that it yields the empty list in both > cases. This function was probably not implemented by a Haskell novice ; ) Right, so unlike in append in this example the extra case for [] is actually desirable! Welcome to Haskell. ;-) Martijn. From batterseapower at hotmail.com Mon Jun 8 09:03:54 2009 From: batterseapower at hotmail.com (Max Bolingbroke) Date: Mon Jun 8 08:47:37 2009 Subject: [Haskell-cafe] Re: [Haskell] ANNOUNCE: testrunner-0.9 In-Reply-To: <200906081224.36779.tux_rocker@reinier.de> References: <200906081224.36779.tux_rocker@reinier.de> Message-ID: <9d4d38820906080603x9acf62dm32474012c451981a@mail.gmail.com> Your feature list sounds like an almost exact duplicate of that for my test-framework package, which has been available on Hackage for months (although it's almost totally unadvertised!): https://github.com/batterseapower/test-framework/tree http://hackage.haskell.org/cgi-bin/hackage-scripts/package/test-framework There is also John's testpack: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/testpack Seems like we need to advertise these better :-) Cheers, Max 2009/6/8 Reinier Lamers : > Dear all, > > testrunner is a new framework to run unit tests. It has the following > distinguishing features: > > * It can run unit tests in parallel. > * It can run QuickCheck and HUnit tests as well as simple boolean expressions. > * It comes with a ready-made main function for your unit test executable. > * This main function recognizes command-line arguments to select tests by name > ?and replay QuickCheck tests. > > testrunner was conceived as a part of the darcs project. > > The home page is http://projects.haskell.org/testrunner/. > > testrunner can be downloaded from > http://projects.haskell.org/testrunner/releases/testrunner-0.9.tar.gz, or with > darcs with a "darcs get http://code.haskell.org/testrunner/". > > Regards, > Reinier Lamers (tux_rocker) > > > _______________________________________________ > Haskell mailing list > Haskell@haskell.org > http://www.haskell.org/mailman/listinfo/haskell > > From magnus at therning.org Mon Jun 8 09:12:12 2009 From: magnus at therning.org (Magnus Therning) Date: Mon Jun 8 08:55:55 2009 Subject: [Haskell-cafe] ANNOUNCE: StrictBench 0.1 - Benchmarking code through strict evaluation In-Reply-To: <4A2D0A79.3040102@van.steenbergen.nl> References: <20090607183022.1793932467A@www.haskell.org> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB27@EXCHANGE10.campus.tue.nl> <4A2D0A79.3040102@van.steenbergen.nl> Message-ID: On Mon, Jun 8, 2009 at 1:56 PM, Martijn van Steenbergen wrote: > Magnus Therning wrote: >> >> Is there no way to force repeated evaluation of a pure value? ?(It'd >> be nice to be able to perform time measurements on pure code so that >> it's possible to compare Haskell implementations of algorithms to >> implementations in other languages, without running into confounding >> factors.) > > I'm really curious about this too. > > My guess is that the answer is "no" because doing so would (among other > things) mean a thunk have to be copied first before it is evaluated, to > preserve the unevaluated version. And what guarantee is there that values > further down the expression haven't been evaluated already? Efficient lazy > evaluation is hard; inefficient lazy evalation is even harder. ;-) Yes, I guessed as much. I was hoping that there might be some way of tricking GHC into being more inefficient though, something like a rollback in evaluation state. /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe From kenneth.hoste at ugent.be Mon Jun 8 09:29:27 2009 From: kenneth.hoste at ugent.be (Kenneth Hoste) Date: Mon Jun 8 09:13:34 2009 Subject: [Haskell-cafe] ANNOUNCE: StrictBench 0.1 - Benchmarking code through strict evaluation In-Reply-To: References: <20090607183022.1793932467A@www.haskell.org> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB27@EXCHANGE10.campus.tue.nl> <4A2D0A79.3040102@van.steenbergen.nl> Message-ID: <2CF97A8F-CDBF-4E2F-9A61-09EAEABBD92D@ugent.be> Hi all, On Jun 8, 2009, at 15:12 , Magnus Therning wrote: > On Mon, Jun 8, 2009 at 1:56 PM, Martijn van > Steenbergen wrote: >> Magnus Therning wrote: >>> >>> Is there no way to force repeated evaluation of a pure value? (It'd >>> be nice to be able to perform time measurements on pure code so that >>> it's possible to compare Haskell implementations of algorithms to >>> implementations in other languages, without running into confounding >>> factors.) >> >> I'm really curious about this too. >> >> My guess is that the answer is "no" because doing so would (among >> other >> things) mean a thunk have to be copied first before it is >> evaluated, to >> preserve the unevaluated version. And what guarantee is there that >> values >> further down the expression haven't been evaluated already? >> Efficient lazy >> evaluation is hard; inefficient lazy evalation is even harder. ;-) > > Yes, I guessed as much. I was hoping that there might be some way of > tricking GHC into being more inefficient though, something like a > rollback in evaluation state. I've been playing around with MicroBench [1], and I believe there is a way to trick GHC (at least the 6.10.2 version) into being inefficient. Below is a snippet of the code I used to benchmark various implementations of a function. The key is partial function application and the IO monad. Don't ask me why it works, but I believe it does. -- benchmark a given function by applying it n times to the given value benchmark :: (a -> b) -> a -> Int -> IO() benchmark f x n = do r <- mapM (\y -> return $! f y) (replicate n x) performGC return () The performGC might not be 100% necessary, but I see it as a part of the function evaluation (i.e. make the runtime clean up the mess the function made). Of course this assumes performGC to be called before using "benchmark". Note: MicroBench was doing something similar, but was using mapM_ instead, which no longer seems to fool GHC into evaluating the function n times. mapM does seem to work though. K. -- Kenneth Hoste Paris research group - ELIS - Ghent University, Belgium email: kenneth.hoste@elis.ugent.be website: http://www.elis.ugent.be/~kehoste blog: http://boegel.kejo.be From sebf at informatik.uni-kiel.de Mon Jun 8 09:32:09 2009 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Mon Jun 8 09:15:55 2009 Subject: [Haskell-cafe] ANNOUNCE: StrictBench 0.1 - Benchmarking code through strict evaluation In-Reply-To: <4A2D0A79.3040102@van.steenbergen.nl> References: <20090607183022.1793932467A@www.haskell.org> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB27@EXCHANGE10.campus.tue.nl> <4A2D0A79.3040102@van.steenbergen.nl> Message-ID: <9697CBA6-4315-496B-904A-0910AAB819F2@informatik.uni-kiel.de> On Jun 8, 2009, at 2:56 PM, Martijn van Steenbergen wrote: >> Is there no way to force repeated evaluation of a pure value? > I'm really curious about this too. could it be done by wrapping the computation in a function which is repeatedly called and compiling with -fno-full-laziness to prevent the compiler from floating the computation to the top-level? -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From shinnonoir at gmail.com Mon Jun 8 09:48:18 2009 From: shinnonoir at gmail.com (Raynor Vliegendhart) Date: Mon Jun 8 09:32:00 2009 Subject: [Haskell-cafe] Maintaining laziness: another example In-Reply-To: <4A2CFE87.6060303@van.steenbergen.nl> References: <4A2CFE87.6060303@van.steenbergen.nl> Message-ID: <6d961e560906080648n778a7e0bra88f4bd54da3639@mail.gmail.com> This might be slightly related. When I was assisting a Haskell lab course, I encountered solutions like the following: > removeRoot :: BSTree a -> BSTree a > removeRoot (Node x Empty Empty) = Empty > removeRoot (Node x left Empty) = left > removeRoot (Node x Empty right) = right > removeRoot (Node x left right) = undefined {- not needed for discussion -} The first removeRoot case is unnecessary. Students new to Haskell (or maybe new to recursion in general?) seem to consider more base cases than needed. -Raynor On 6/8/09, Martijn van Steenbergen wrote: > Hello, > > While grading a Haskell student's work I ran into an example of a program > not being lazy enough. Since it's such a basic and nice example I thought > I'd share it with you: > > One part of the assignment was to define append :: [a] -> [a] -> [a], > another to define cycle2 :: [a] -> [a]. This was her (the majority of the > students in this course is female!) solution: > > > append :: [a] -> [a] -> [a] > > append [] ys = ys > > append xs [] = xs > > append (x:xs) ys = x : (append xs ys) > > > > cycle2 :: [a] -> [a] > > cycle2 [] = error "empty list" > > cycle2 xs = append xs (cycle2 xs) > > > > This definition of append works fine on any non-bottom input (empty, finite, > infinite), but due to the unnecessary second append case, cycle2 never > produces any result. > > Martijn. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From nccb2 at kent.ac.uk Mon Jun 8 11:01:37 2009 From: nccb2 at kent.ac.uk (Neil Brown) Date: Mon Jun 8 10:45:21 2009 Subject: [Haskell-cafe] ANN: alloy-1.0.0 (generic programming) Message-ID: <4A2D27D1.1030401@kent.ac.uk> Hi all, I've just put the first release of the Alloy generic programming library on Hackage [1]. Alloy (n?e Polyplate) is intended to be a fairly fast blend of several other generics approaches, such as SYB (but without the dynamic typing) and Uniplate (but allowing an arbitrary number of target types), for performing transformations on specific types in large tree structures. There is a tutorial explaining how to use the library [2], the API documentation should be live on Hackage shortly [1], and there is also a recent draft of a paper with benchmarks and details of the inner workings for those who are interested [3]. [1] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/alloy [2] http://twistedsquare.com/Alloy-Tutorial.pdf [3] http://twistedsquare.com/Alloy.pdf Thanks, Neil. From sebf at informatik.uni-kiel.de Mon Jun 8 12:41:48 2009 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Mon Jun 8 12:25:32 2009 Subject: [Haskell-cafe] purely functional lazy non-deterministic programming References: Message-ID: [crosspost from Haskell-libraries and Curry mailing list] Dear Haskell and Curry programmers, there is now a Haskell library that supports lazy functional-logic programming in Haskell. It is available from http://sebfisch.github.com/explicit-sharing and can be obtained from Hackage using cabal-install. The project page links to tutorials that explain how to use the library and to an ICFP'09 paper (joint work with Oleg Kiselyov and Chung-chieh Shan) that explains the implemented ideas in depth. Have fun! Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From nowgate at yahoo.com Mon Jun 8 12:42:04 2009 From: nowgate at yahoo.com (michael rice) Date: Mon Jun 8 12:25:47 2009 Subject: [Haskell-cafe] Problem with Data.Map Message-ID: <643740.75398.qm@web31104.mail.mud.yahoo.com> I'm trying to understand Map type for possible use in another problem I'm working on, but am stymied right off the bat. ==========Here's my source: import Data.Map (Map) import qualified Data.Map as Map l1 = "abc" l2 = [1,2,3] ==========Here's my error: Prelude> :l maptest [1 of 1] Compiling Main???????????? ( maptest.hs, interpreted ) Ok, modules loaded: Main. *Main> l1 Loading package syb ... linking ... done. Loading package array-0.2.0.0 ... linking ... done. Loading package containers-0.2.0.0 ... linking ... done. "abc" *Main> l2 [1,2,3] *Main> zip l1 l2 [('a',1),('b',2),('c',3)] *Main> fromList $ zip l1 l2 :1:0: Not in scope: `fromList' *Main> =========== Why isn't this working? Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090608/6b966d2b/attachment.html From jochem at functor.nl Mon Jun 8 12:45:54 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Mon Jun 8 12:29:39 2009 Subject: [Haskell-cafe] Problem with Data.Map In-Reply-To: <643740.75398.qm@web31104.mail.mud.yahoo.com> References: <643740.75398.qm@web31104.mail.mud.yahoo.com> Message-ID: <4A2D4042.6090201@functor.nl> michael rice wrote: > I'm trying to understand Map type for possible use in another problem I'm working on, but am stymied right off the bat. > > ==========Here's my source: > > import Data.Map (Map) > import qualified Data.Map as Map > > *Main> fromList $ zip l1 l2 > > :1:0: Not in scope: `fromList' You imported map "qualified as Map", that means that only 'Map.fromList' and 'Data.Map.fromList' are in scope, and not 'fromList'. The reason one normally does it like this is that a lot of function names clash with the Prelude (on purpose). Normally one uses "qualified as M" or "qualified as Map" to shorten the notation. HTH, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From nowgate at yahoo.com Mon Jun 8 12:51:42 2009 From: nowgate at yahoo.com (michael rice) Date: Mon Jun 8 12:35:24 2009 Subject: [Haskell-cafe] Problem with Data.Map Message-ID: <499459.5992.qm@web31102.mail.mud.yahoo.com> I don't understand your response. I copied the imports from Hoogles Data.Map page. What should the imports be? Michael --- On Mon, 6/8/09, Jochem Berndsen wrote: From: Jochem Berndsen Subject: Re: [Haskell-cafe] Problem with Data.Map To: "michael rice" Cc: haskell-cafe@haskell.org Date: Monday, June 8, 2009, 12:45 PM michael rice wrote: > I'm trying to understand Map type for possible use in another problem I'm working on, but am stymied right off the bat. > > ==========Here's my source: > > import Data.Map (Map) > import qualified Data.Map as Map > > *Main> fromList $ zip l1 l2 > > :1:0: Not in scope: `fromList' You imported map "qualified as Map", that means that only 'Map.fromList' and 'Data.Map.fromList' are in scope, and not 'fromList'. The reason one normally does it like this is that a lot of function names clash with the Prelude (on purpose). Normally one uses "qualified as M" or "qualified as Map" to shorten the notation. HTH, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090608/dcaae127/attachment.html From nowgate at yahoo.com Mon Jun 8 12:58:12 2009 From: nowgate at yahoo.com (michael rice) Date: Mon Jun 8 12:41:55 2009 Subject: [Haskell-cafe] Problem with Data.Map Message-ID: <788194.97383.qm@web31107.mail.mud.yahoo.com> Gotcha. Thanks! Also wondering why I need two imports for one module. Michael --- On Mon, 6/8/09, Jochem Berndsen wrote: From: Jochem Berndsen Subject: Re: [Haskell-cafe] Problem with Data.Map To: "michael rice" Cc: haskell-cafe@haskell.org Date: Monday, June 8, 2009, 12:52 PM michael rice wrote: > I don't understand your response. I copied the imports from Hoogles Data.Map page. What should the imports be? > > Michael The imports are fine, but instead of 'fromList' you should use 'Map.fromList' or 'Data.Map.fromList'. Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090608/83f63d89/attachment-0001.html From jochem at functor.nl Mon Jun 8 12:59:41 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Mon Jun 8 12:43:23 2009 Subject: [Haskell-cafe] Problem with Data.Map In-Reply-To: <788194.97383.qm@web31107.mail.mud.yahoo.com> References: <788194.97383.qm@web31107.mail.mud.yahoo.com> Message-ID: <4A2D437D.2090001@functor.nl> michael rice wrote: > Gotcha. Thanks! > > Also wondering why I need two imports for one module. This is not strictly necessary, but the scoping also applies to the type 'Map' itself, thus leaving the import Data.Map (Map) (this brings only the name "Map" in scope from module Data.Map) out would force you to write Data.Map.Map everywhere instead of just 'Map'. Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From noteed at gmail.com Mon Jun 8 13:00:08 2009 From: noteed at gmail.com (minh thu) Date: Mon Jun 8 12:44:10 2009 Subject: [Haskell-cafe] Problem with Data.Map In-Reply-To: <499459.5992.qm@web31102.mail.mud.yahoo.com> References: <499459.5992.qm@web31102.mail.mud.yahoo.com> Message-ID: <40a414c20906081000x66ba92ebu9a880fd14dcfcf5a@mail.gmail.com> Hi, > import Blurp bring every thing defined in the Blurp module in scope. So if blah is defined in blurp, > blah will work as expected. > import qualified Blurp as B does the same thing but everything defined in Blurp should be qualified (i.e. prefixed) with B. > B.blah will work, not > blah So your import statement is right but you should write Map.fromList instead of just fromList. The goal is to have multiple identical names from different modules and still be able to use them at the same time, but qualified, for instance lookup is defined in both Data.List and Data.Map. > import qualified Data.List as L > import qualified Data.Map as M > L.lookup > M.lookup The two last lines are unambiguous. Cheers, Thu 2009/6/8 michael rice : > I don't understand your response. I copied the imports from Hoogles Data.Map > page. What should the imports be? > > Michael > > --- On Mon, 6/8/09, Jochem Berndsen wrote: > > From: Jochem Berndsen > Subject: Re: [Haskell-cafe] Problem with Data.Map > To: "michael rice" > Cc: haskell-cafe@haskell.org > Date: Monday, June 8, 2009, 12:45 PM > > michael rice wrote: >> I'm trying to understand Map type for possible use in another problem I'm >> working on, but am stymied right off the bat. >> >> ==========Here's my source: >> >> import Data.Map (Map) >> import qualified Data.Map as Map >> >> *Main> fromList $ zip l1 l2 >> >> :1:0: Not in scope: `fromList' > > You imported map "qualified as Map", that means that only 'Map.fromList' > and 'Data.Map.fromList' are in scope, and not 'fromList'. The reason one > normally does it like this is that a lot of function names clash with > the Prelude (on purpose). Normally one uses "qualified as M" or > "qualified as Map" to shorten the notation. > > HTH, > > -- > Jochem Berndsen | jochem@functor.nl > GPG: 0xE6FABFAB > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From jochem at functor.nl Mon Jun 8 12:52:41 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Mon Jun 8 12:48:42 2009 Subject: [Haskell-cafe] Problem with Data.Map In-Reply-To: <499459.5992.qm@web31102.mail.mud.yahoo.com> References: <499459.5992.qm@web31102.mail.mud.yahoo.com> Message-ID: <4A2D41D9.1010406@functor.nl> michael rice wrote: > I don't understand your response. I copied the imports from Hoogles Data.Map page. What should the imports be? > > Michael The imports are fine, but instead of 'fromList' you should use 'Map.fromList' or 'Data.Map.fromList'. Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From nowgate at yahoo.com Mon Jun 8 13:17:41 2009 From: nowgate at yahoo.com (michael rice) Date: Mon Jun 8 13:01:24 2009 Subject: [Haskell-cafe] Problem with Data.Map Message-ID: <383586.64686.qm@web31106.mail.mud.yahoo.com> Thanks, guys. Sounds like Lisp packages. Now I see the functionality of the A or B, etc.: Fewer keystrokes. Michael --- On Mon, 6/8/09, minh thu wrote: From: minh thu Subject: Re: [Haskell-cafe] Problem with Data.Map To: "michael rice" Cc: "Jochem Berndsen" , haskell-cafe@haskell.org Date: Monday, June 8, 2009, 1:00 PM Hi, > import Blurp bring every thing defined in the Blurp module in scope. So if blah is defined in blurp, > blah will work as expected. > import qualified Blurp as B does the same thing but everything defined in Blurp should be qualified (i.e. prefixed) with B. > B.blah will work, not > blah So your import statement is right but you should write Map.fromList instead of just fromList. The goal is to have multiple identical names from different modules and still be able to use them at the same time, but qualified, for instance lookup is defined in both Data.List and Data.Map. > import qualified Data.List as L > import qualified Data.Map as M > L.lookup > M.lookup The two last lines are unambiguous. Cheers, Thu 2009/6/8 michael rice : > I don't understand your response. I copied the imports from Hoogles Data.Map > page. What should the imports be? > > Michael > > --- On Mon, 6/8/09, Jochem Berndsen wrote: > > From: Jochem Berndsen > Subject: Re: [Haskell-cafe] Problem with Data.Map > To: "michael rice" > Cc: haskell-cafe@haskell.org > Date: Monday, June 8, 2009, 12:45 PM > > michael rice wrote: >> I'm trying to understand Map type for possible use in another problem I'm >> working on, but am stymied right off the bat. >> >> ==========Here's my source: >> >> import Data.Map (Map) >> import qualified Data.Map as Map >> >> *Main> fromList $ zip l1 l2 >> >> :1:0: Not in scope: `fromList' > > You imported map "qualified as Map", that means that only 'Map.fromList' > and 'Data.Map.fromList' are in scope, and not 'fromList'. The reason one > normally does it like this is that a lot of function names clash with > the Prelude (on purpose). Normally one uses "qualified as M" or > "qualified as Map" to shorten the notation. > > HTH, > > -- > Jochem Berndsen | jochem@functor.nl > GPG: 0xE6FABFAB > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090608/65a95aaf/attachment.html From iavor.diatchki at gmail.com Mon Jun 8 14:04:18 2009 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Mon Jun 8 13:48:04 2009 Subject: [Haskell-cafe] Re: Building network package on Windows In-Reply-To: References: <5ab17e790906062143h3968488bg577cdbe0de796bd9@mail.gmail.com> <5ab17e790906071704h19255d38oa82b48ef842764f9@mail.gmail.com> Message-ID: <5ab17e790906081104t790d4428of3edd8b9eb5af80e@mail.gmail.com> Hi, Interesting. In that case, does anyone have any ideas about the linker errors? -Iavor On Mon, Jun 8, 2009 at 12:42 AM, Thomas ten Cate wrote: > On Mon, Jun 8, 2009 at 02:04, Iavor Diatchki wrote: >> Hello, >> Here is an update, in case anyone else runs into the same problem. >> >> My understanding, is that the problem was caused by a mistake in the >> "configure" script for the "network" package, which after (correctly) >> detecting that IPv6 functionality was not available on my platform, it >> (incorrectly) tried to "gain" this functionality by redefining the >> version of my platform. ?Concretely, apparently I have "Windows Vista >> Basic Home Edition", which seems to identify itself as version 0x400, >> while the missing functions are only available on versions of windows >>>= 0x501. > > 0x400 is, if I'm not mistaken, Windows 95. Vista is 0x600 [1]. I don't > think they *identify* themselves as such; rather, the program itself > specifies what Windows versions it wants to be able to run on. > > In particular, the macros _WIN32_WINNT and WINVER should be defined as > the *minimum* platform version on which the compiled binary is to > work. Therefore, if functionality from XP (0x501) is needed, it is > perfectly okay to redefine these macros to 0x501. This will flip some > switches in included header files that enable declarations for the > desired functionality. Of course, the binary will then only run on > platforms that actually have this functionality. > > Hope that clears things up a bit. > > Thomas > > [1] http://msdn.microsoft.com/en-us/library/aa383745.aspx > From batterseapower at hotmail.com Mon Jun 8 14:07:52 2009 From: batterseapower at hotmail.com (Max Bolingbroke) Date: Mon Jun 8 13:51:35 2009 Subject: [Haskell-cafe] Re: [Haskell] ANNOUNCE: testrunner-0.9 In-Reply-To: <200906081546.13437.tux_rocker@reinier.de> References: <200906081224.36779.tux_rocker@reinier.de> <9d4d38820906080603x9acf62dm32474012c451981a@mail.gmail.com> <200906081546.13437.tux_rocker@reinier.de> Message-ID: <9d4d38820906081107h4d379959v2be0af1dd56abac1@mail.gmail.com> 2009/6/8 Reinier Lamers : > I checked out testpack and that did not meet my requirements. I don't know if > I considered test-framework. If I did, it may be that I was turned off by the > fact that the 'home page' link on cabal just goes to a web presentation of the > source tree on github. Reinier, You are quite right that this is a weakness. I've been meaning to put a site together for a while, and your comment gave me the impetus to do it: http://batterseapower.github.com/test-framework/ That's much friendlier! All the best, Max From briqueabraque at yahoo.com Mon Jun 8 14:23:16 2009 From: briqueabraque at yahoo.com (=?ISO-8859-1?Q?Maur=ED=ADcio?=) Date: Mon Jun 8 14:07:12 2009 Subject: [Haskell-cafe] Why do ghc-built binaries use timer_create? Message-ID: This comes from an issue in haskell-beginner, although it have already been touched here. If you use recent versions of ghc to build a program and try the resulting binary on an old linux distro, you may get a message about timer_create receiving the wrong parameters. Curiously, as sugested in the other thread, it seems building with ghc -threaded solves the problem. So, I'm just curious: how is timer_create used, and why maybe it's not used with -threaded? Thanks, Maur?cio From jmillikin at gmail.com Mon Jun 8 14:39:25 2009 From: jmillikin at gmail.com (John Millikin) Date: Mon Jun 8 14:23:07 2009 Subject: [Haskell-cafe] Incremental XML parsing with namespaces? Message-ID: <3283f7fe0906081139t1b9475d1sa9dba2c2a17ff4fe@mail.gmail.com> I'm trying to convert an XML document, incrementally, into a sequence of XML events. A simple example XML document: ? ?Doc title ? ?abc1234 ? ?Hello world! The document can be very large, and arrives in chunks over a socket, so I need to be able to "feed" the text data into a parser and receive a list of XML events per chunk. Chunks can be separated in time by intervals of several minutes to an hour, so pausing processing for the arrival of the entire document is not an option. The type signatures would be something like: type Namespace = String type LocalName = String data Attribute = Attribute Namespace LocalName String data XMLEvent = ? ?EventElementBegin Namespace LocalName [Attribute] | ? ?EventElementEnd Namespace LocalName | ? ?EventContent String | EventError String parse :: Parser -> String -> (Parser, [XMLEvent]) I've looked at HaXml, HXT, and hexpat, and unless I'm missing something, none of them can achieve this: + HaXml and hexpat seem to disregard namespaces entirely -- that is, the root element is parsed to "doc" instead of ("org:myproject:mainns", "doc"), and the second child is "x:ref" instead of ("org:myproject:otherns", "ref"). Obviously, this makes parsing mixed-namespace documents effectively impossible. I found an email from 2004[1] that mentions a "filter" for namespace support in HaXml, but no further information and no working code. + HXT looks promising, because I see explicit mention in the documentation of recording and propagating namespaces. However, I can't figure out if there's an incremental mode. A page on the wiki[2] suggests that SAX is supported in the "html tag soup" parser, but I want incremental parsing of *valid* documents. If incremental parsing is supported by the standard "arrow" interface, I don't see any obvious way to pull events out into a list -- I'm a Haskell newbie, and still haven't quite figured out monads yet, let alone Arrows. Are there any libraries that support namespace-aware incremental parsing? [1] http://www.haskell.org/pipermail/haskell-cafe/2004-June/006252.html [2] http://www.haskell.org/haskellwiki/HXT/Conversion_of_Haskell_data_from/to_XML From nowgate at yahoo.com Mon Jun 8 14:59:53 2009 From: nowgate at yahoo.com (michael rice) Date: Mon Jun 8 14:43:36 2009 Subject: [Haskell-cafe] Applying Data.Map Message-ID: <781453.33760.qm@web31106.mail.mud.yahoo.com> I wrote a Haskell solution for the Prolog problem stated below. I had written a function SQUISH before discovering that NUB does the same thing. While the solution works, I thought maybe I could apply some functions in the Data.Map module, and so wrote a second version of SERIALIZE, one no longer needing TRANSLATE. Using the Data.Map module is probably overkill for this particular problem, but wanted to familiarize myself with Map type. Suggestions welcome. Prolog code also included below for those interested. Michael =========== {- ?From "Prolog By Example", Coelho, Cotta, Problem 42, pg. 63 ?? Verbal statement: ?? Generate a list of serial numbers for the items of a given list, ?? the members of which are to be numbered in alphabetical order. ?? For example, the list [p,r,o,l,o,g] must generate [4,5,3,2,3,1] -} {- Prelude> :l serialize [1 of 1] Compiling Main???????????? ( serialize.hs, interpreted ) Ok, modules loaded: Main. *Main> serialize "prolog" [4,5,3,2,3,1] *Main> -} ===========Haskell code========== import Data.Char import Data.List import Data.Map (Map) import qualified Data.Map as Map {- translate :: [Char] -> [(Char,Int)] -> [Int] translate [] _ = [] translate (x:xs) m = (fromJust (lookup x m)) : (translate xs m ) -} {- serialize :: [Char] -> [Int] serialize s = let c = nub $ sort s ????????????????? n = [1..(length c)] ????????????? in translate s (zip c n) -} serialize :: [Char] -> [Int] serialize s = let c = nub $ sort s ????????????????? n = [1..(length c)] ????????????????? m = Map.fromList $ zip c n ????????????? in map (\c -> m Map.! c) s ============Prolog code============ serialize(L,R) :- pairlists(L,R,A),arrange(A,T), ????????????????? numbered(T,1,N). ??????????????????????????????????????????????? ?? <- typo? pairlists([X|L],[Y|R],[pair(X,Y)|A]) :- pairlist(L,R,A). pairlists([],[],[]). arrange([X|L],tree(T1,X,T2)) :- partition(L,X,L1,L2), ??????????????????????????????? arrange(L1,T1), ??????????????????????????????? arrange(L2,T2). arrange([],_). partition([X|L],X,L1,L2) :- partition(L,X,L1,L2). partition([X|L],Y,[X|L1],L2) :- before(X,Y), ??????????????????????????????? partition(L,Y,L1,L2). partition([X|L],Y,L1,[X|L2]) :- before(Y,X), ??????????????????????????????? partition(L,Y,L1,L2). partition([],_,[],[]). before(pair(X1,Y1),pair(X2,Y2)) :- X1 Today, I was working on coding a solver for the game "doublets". It's a word game where you transform the start word into the end word one letter at a time (and the intermediate states must also be valid words). For example, one solution to ("warm", "cold") is ["warm", "ward", "card", "cord", "cold"] So, one of my first goals was to write a function that would generate the possible words a given word could transition to. Here's a simple recursive implementation: transition :: [Char] -> [[Char]] transition [] = [] transition (c:cs) = map (c:) (transition cs) ++ map (:cs) ['a'..'z'] For some reason, I find this formulation to be strangely unsatisfying. It seems to me that this sort of computation -- i.e. modifying each element of a container (but only one at a time) -- should be expressible with some higher order function. In a nutshell, what I'm looking for would be a function, say "each" with this type. each :: (Container c) => (a -> a) -> c a -> c (c a) I'm not particularly sure what Class to substitute for "Container". Comonad seemed like a promising solution initially, and provides the basis for my current implementation of the "doublets" solver. The problem being that cobind (extend) takes a function of type (w a - > a) instead of (a -> a). I suspect that there may be a clever way to write "each" by using liftW in combination with .>> or something like that, but presently, I'm at a loss. Has anyone else encountered this sort of abstraction before. I'd love to hear your ideas about what Classes "each" should support, and how to implement it. Matt From gue.schmidt at web.de Mon Jun 8 15:25:15 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Mon Jun 8 15:09:11 2009 Subject: [Haskell-cafe] com-1.2.3 - problems installing Message-ID: Hi all, I'm trying to install com-1.2.3 on Win XP with ghc-6.10.3 I get this error message: Resolving dependencies... Configuring com-1.2.3... cabal: Missing dependencies on foreign libraries: * Missing header file: include/WideStringSrc.h * Missing C libraries: kernel32, user32, ole32, oleaut32, advapi32 This problem can usually be solved by installing the system packages that provide these libraries (you may need the "-dev" versions). If the libraries are already installed but in a non-standard location then you can use the flags --extra-include-dirs= and --extra-lib-dirs= to specify where they are. cabal: Error: some packages failed to install: com-1.2.3 failed during the configure step. The exception was: exit: ExitFailure 1 From bos at serpentine.com Mon Jun 8 16:23:31 2009 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon Jun 8 16:07:15 2009 Subject: [Haskell-cafe] Re: Building network package on Windows In-Reply-To: <5ab17e790906071704h19255d38oa82b48ef842764f9@mail.gmail.com> References: <5ab17e790906062143h3968488bg577cdbe0de796bd9@mail.gmail.com> <5ab17e790906071704h19255d38oa82b48ef842764f9@mail.gmail.com> Message-ID: On Sun, Jun 7, 2009 at 5:04 PM, Iavor Diatchki wrote: > Here is an update, in case anyone else runs into the same problem. > Thanks for following up. I wrote the code that performs that check, but unfortunately I don't have access to all of the permutations of Windows that are out there, so my ability to test is rather limited. I'm sorry for the trouble it caused you. Perhaps Vista Home Basic doesn't have IPv6 support? If that conjecture is true, I'm not sure how I'd have found it out :-( More likely, the name mangling is going wrong. As for your point that the network package exhibits different APIs depending on the underlying system, that's true, but it's hard to avoid. Writing a compatibility API for systems that don't have functioning IPv6 APIs is a chunk of boring work, and I had thought that such systems were rare. Anyway, please do file a bug, and we'll take the discussion of how to reproduce and fix your problem there. Thanks, Bryan. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090608/f4c9128e/attachment.html From bos at serpentine.com Mon Jun 8 16:27:07 2009 From: bos at serpentine.com (Bryan O'Sullivan) Date: Mon Jun 8 16:10:49 2009 Subject: [Haskell-cafe] Why do ghc-built binaries use timer_create? In-Reply-To: References: Message-ID: On Mon, Jun 8, 2009 at 11:23 AM, Maur??cio wrote: > This comes from an issue in haskell-beginner, although > it have already been touched here. If you use recent > versions of ghc to build a program and try the resulting > binary on an old linux distro, you may get a message > about timer_create receiving the wrong parameters. > For better or worse, this is something that people should not be trying in the first place, and the problem you report is a representative example of why. Taking code compiled on a new system and trying to run it on an old system will often fail due to API or ABI incompatibilities. Sometimes those failures are easy to see, as in your case; other times, they'll result in more subtle problems. The timer_create issue is a bit of a red herring. If it wasn't that, something else would probably break instead. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090608/5ed04160/attachment.html From wren at freegeek.org Mon Jun 8 16:36:00 2009 From: wren at freegeek.org (wren ng thornton) Date: Mon Jun 8 16:19:41 2009 Subject: [Haskell-cafe] Slow documentation generation on Hackage In-Reply-To: References: <20090607183022.1793932467A@www.haskell.org> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB6D@EXCHANGE10.campus.tue.nl> <525C5338-5A42-4477-9532-0718D90509D3@ece.cmu.edu> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DBAD@EXCHANGE10.campus.tue.nl> Message-ID: <4A2D7630.3030002@freegeek.org> Thomas ten Cate wrote: > Niemeijer, R.A. wrote: > > which, face it, is going to be all of them; I doubt Haskell > > is popular enough yet to be the target of DoS attacks > > Second that. I think this is a good case in which some security should > be traded in for usability. Those who would trade security for usability deserve neither usability nor security ;) Seriously, all the Haskell hackers I've encountered have been good people, but Haskell is the language of the hair shirt afterall. Security is hard enough to come by in the first place, sacrificing what little we have is not the right path. The Haskell interwebs are already too susceptible to downtimes from non-malicious sources, and it floods #haskell whenever it happens. I agree that the turnaround time is a bit long, but I think server stability is more important than instant feedback. It's easy enough to get an account on community.haskell.org and just upload your own docs there[1]. The thing I'd be more interested in getting quick feedback on is whether compilation succeeds in the Hackage environment, which is very different from my own build environment. Given the various constraints mentioned, and depending on the load averages for the servers, perhaps the simplest thing to do would be to just reduce the latency somewhat. Flushing the queue every 4~6 hrs seems both long enough to circumvent the major DoS problems, and short enough to be helpful to developers. Especially if the queue could be set up to be fair among users (e.g. giving each user some fixed number of slots or cycles per flush, delaying the rest until the next cycle). A different approach would be to do exponential slowdown per user. So if a user has submitted N jobs in the last Window (e.g. 24 hours), then the job is run around Epsilon^N after submission (where Epsilon is, say, 3 minutes). [1] I do: http://community.haskell.org/~wren/ The scripts to automate it are trivial, but I can share them if people like. -- Live well, ~wren From malcolm.wallace at cs.york.ac.uk Mon Jun 8 16:44:35 2009 From: malcolm.wallace at cs.york.ac.uk (Malcolm Wallace) Date: Mon Jun 8 16:28:33 2009 Subject: [Haskell-cafe] Incremental XML parsing with namespaces? In-Reply-To: <3283f7fe0906081139t1b9475d1sa9dba2c2a17ff4fe@mail.gmail.com> References: <3283f7fe0906081139t1b9475d1sa9dba2c2a17ff4fe@mail.gmail.com> Message-ID: <4BB426D6-B5C5-4625-B541-098F3628B135@cs.york.ac.uk> On 8 Jun 2009, at 19:39, John Millikin wrote: > + HaXml and hexpat seem to disregard namespaces entirely -- that is, > the root element is parsed to "doc" instead of > ("org:myproject:mainns", "doc"), and the second child is "x:ref" > instead of ("org:myproject:otherns", "ref"). Yes, HaXml makes no special effort to deal with namespaces. However, that does not mean that dealing with namespaces is "impossible" - it just requires a small amount of post-processing, that is all. For instance, it would not be difficult to start from the SAX-like parser http://hackage.haskell.org/packages/archive/HaXml/1.19.7/doc/html/Text-XML-HaXml-SAX.html taking e.g. a constructor value SaxElementOpen Name [Attribute] and converting it to your corresponding constructor value EventElementBegin Namespace LocalName [Attribute] Just filter the [Attribute] of the first type for the attribute name "xmlns", and pull that attribute value out to become your new Namespace value. Obviously there is a bit more to it than that, since namespace *defining* attributes, like your example xmlns:x="...", have an lexical scope. You will need some kind of state to track the scope, possibly in the parser itself, or again possibly in a post-processing step over the list of output XMLEvents. Regards, Malcolm From briqueabraque at yahoo.com Mon Jun 8 17:10:31 2009 From: briqueabraque at yahoo.com (=?ISO-8859-1?Q?Maur=ED=ADcio?=) Date: Mon Jun 8 16:54:28 2009 Subject: [Haskell-cafe] Re: Why do ghc-built binaries use timer_create? In-Reply-To: References: Message-ID: > This comes from an issue in haskell-beginner, (...) > > For better or worse, this is something that people should not be trying > in the first place, (...) Sure! That's what I sugested in the original question. I'm actually just curious on why timer_create is used at all. This is probably just a small detail in program initialization, and maybe a link to some description of what happens on program initialization (specially ghc generated binaries) behind the naive user view would do it. Thanks, Maur?cio From jmillikin at gmail.com Mon Jun 8 18:04:35 2009 From: jmillikin at gmail.com (John Millikin) Date: Mon Jun 8 17:48:16 2009 Subject: [Haskell-cafe] Incremental XML parsing with namespaces? In-Reply-To: <4BB426D6-B5C5-4625-B541-098F3628B135@cs.york.ac.uk> References: <3283f7fe0906081139t1b9475d1sa9dba2c2a17ff4fe@mail.gmail.com> <4BB426D6-B5C5-4625-B541-098F3628B135@cs.york.ac.uk> Message-ID: <3283f7fe0906081504q608cc96ftfb1eba7bf176acb@mail.gmail.com> On Mon, Jun 8, 2009 at 1:44 PM, Malcolm Wallace wrote: > Yes, HaXml makes no special effort to deal with namespaces. ?However, that > does not mean that dealing with namespaces is "impossible" - it just > requires a small amount of post-processing, that is all. > > For instance, it would not be difficult to start from the SAX-like parser > > ?http://hackage.haskell.org/packages/archive/HaXml/1.19.7/doc/html/Text-XML-HaXml-SAX.html > > taking e.g. a constructor value > ? ?SaxElementOpen Name [Attribute] > > and converting it to your corresponding constructor value > ? ?EventElementBegin Namespace LocalName [Attribute] > > Just filter the [Attribute] of the first type for the attribute name > "xmlns", and pull that attribute value out to become your new Namespace > value. > > Obviously there is a bit more to it than that, since namespace *defining* > attributes, like your example xmlns:x="...", have an lexical scope. ?You > will need some kind of state to track the scope, possibly in the parser > itself, or again possibly in a post-processing step over the list of output > XMLEvents. > The interface you linked to doesn't seem to have a way to "resume" parsing. That is, I can't feed it chunks of text and have it generate a (ParserState, [Event]) tuple for each chunk. Perhaps this is possible in Haskell without explicit state management? I've tried to write a test application to listen on a socket and print events as the arrive, but with no luck. Manually re-parsing the events isn't attractive, because it would require writing at least part of the parser manually. I had hoped to re-use an existing XML parser, rather than writing a new one. From jmillikin at gmail.com Mon Jun 8 18:05:51 2009 From: jmillikin at gmail.com (John Millikin) Date: Mon Jun 8 17:49:33 2009 Subject: [Haskell-cafe] Incremental XML parsing with namespaces? In-Reply-To: <4A2D87D9.2080700@freegeek.org> References: <3283f7fe0906081139t1b9475d1sa9dba2c2a17ff4fe@mail.gmail.com> <4A2D87D9.2080700@freegeek.org> Message-ID: <3283f7fe0906081505p51270e32r248a927684a2d3de@mail.gmail.com> On Mon, Jun 8, 2009 at 2:51 PM, wren ng thornton wrote: > One issue you'll have to deal with is that since output is delivered > on-line, by the time a validity (or well-formedness) error can be recognized > by the parser it'll be "too late". Thus the rest of your code will need to > be able to back out any global changes they've done when an asynchronous > error shows up. > > I'm sure you already knew that, but it's worth highlighting. (I recently > wrote similar code, but in Java. Haven't had the chance/need to do any xml > hacking in Haskell yet.) > This is acceptable -- I've written a small Python application that performs incremental parsing on the data stream, and aborting on first detection of an error is fine. From hjgtuyl at chello.nl Mon Jun 8 18:16:47 2009 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Mon Jun 8 18:00:24 2009 Subject: [Haskell-cafe] How to compile base? Message-ID: L.S., I tried to compile base-4.0.0.0 (on Windows XP) as follows: [...]\base\4.0.0.0>runhaskell Setup configure : module `Prelude' is not loaded It seems that Base needs another way to compile, how? -- Regards, Henk-Jan van Tuyl -- http://functor.bamikanarie.com http://Van.Tuyl.eu/ -- From westondan at imageworks.com Mon Jun 8 18:17:34 2009 From: westondan at imageworks.com (Dan Weston) Date: Mon Jun 8 18:01:22 2009 Subject: [Haskell-cafe] Comonadic composition and the game "Doublets" In-Reply-To: <8FF7CDE0-C429-4067-A8EF-ECC9FC353D9D@gmail.com> References: <8FF7CDE0-C429-4067-A8EF-ECC9FC353D9D@gmail.com> Message-ID: <4A2D8DFE.7020903@imageworks.com> I think the structure you are looking for is called a "wedge sum" [1], which is the coproduct in the category of the pointed spaces, each of which is (in this case) the group action of changing one letter to another in the ith position of a word of fixed length. One small tricky part is that, in contrast to the direct product of n 1-D spaces with a list comprehension, which enumerates the product space with duplicates: [(x,y,z,...) | x <- xs, y <- ys, z <- zs, ... ] with a wedge sum a naive algorithm overcounts the point (or origin, in this case the identity function). This can be seen in your transition function, where non-identity transformations are counted only once, but the identity transformation is counted n times: *Main> length . filter (== "abd") . transition $ "abc" 1 *Main> length . filter (== "abc") . transition $ "abc" 3 If you want your result to be a set, you may want to treat the identity transformation separately. [1] http://en.wikipedia.org/wiki/Wedge_sum Dan Matthew wrote: > Today, I was working on coding a solver for the game "doublets". > It's a word game where you transform the start word into the end > word one letter at a time (and the intermediate states must also > be valid words). For example, one solution to ("warm", "cold") is > > ["warm", "ward", "card", "cord", "cold"] > > So, one of my first goals was to write a function that would generate > the possible words a given word could transition to. Here's a simple > recursive implementation: > > transition :: [Char] -> [[Char]] > transition [] = [] > transition (c:cs) = map (c:) (transition cs) ++ map (:cs) ['a'..'z'] > > For some reason, I find this formulation to be strangely unsatisfying. > It seems to me that this sort of computation -- i.e. modifying each > element of a container (but only one at a time) -- should be > expressible with some higher order function. In a nutshell, what I'm > looking for would be a function, say "each" with this type. > > each :: (Container c) => (a -> a) -> c a -> c (c a) > > I'm not particularly sure what Class to substitute for "Container". > Comonad seemed like a promising solution initially, and provides > the basis for my current implementation of the "doublets" solver. > > The problem being that cobind (extend) takes a function of type (w a - > > a) > instead of (a -> a). I suspect that there may be a clever way to write > "each" by using liftW in combination with .>> or something like that, > but presently, I'm at a loss. > > Has anyone else encountered this sort of abstraction before. I'd love > to hear your ideas about what Classes "each" should support, and > how to implement it. > > > Matt > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From westondan at imageworks.com Mon Jun 8 18:19:09 2009 From: westondan at imageworks.com (Dan Weston) Date: Mon Jun 8 18:02:54 2009 Subject: [Haskell-cafe] Comonadic composition and the game "Doublets" In-Reply-To: <4A2D8DFE.7020903@imageworks.com> References: <8FF7CDE0-C429-4067-A8EF-ECC9FC353D9D@gmail.com> <4A2D8DFE.7020903@imageworks.com> Message-ID: <4A2D8E5D.4090904@imageworks.com> Oops. Make that: "a list comprehension, which enumerates the product space *without* duplicates"! Dan Weston wrote: > I think the structure you are looking for is called a "wedge sum" [1], > which is the coproduct in the category of the pointed spaces, each of > which is (in this case) the group action of changing one letter to > another in the ith position of a word of fixed length. > > One small tricky part is that, in contrast to the direct product of n > 1-D spaces with a list comprehension, which enumerates the product space > with duplicates: > > [(x,y,z,...) | x <- xs, y <- ys, z <- zs, ... ] > > with a wedge sum a naive algorithm overcounts the point (or origin, in > this case the identity function). This can be seen in your transition > function, where non-identity transformations are counted only once, but > the identity transformation is counted n times: > > *Main> length . filter (== "abd") . transition $ "abc" > 1 > *Main> length . filter (== "abc") . transition $ "abc" > 3 > > If you want your result to be a set, you may want to treat the identity > transformation separately. > > [1] http://en.wikipedia.org/wiki/Wedge_sum > > Dan > > Matthew wrote: >> Today, I was working on coding a solver for the game "doublets". >> It's a word game where you transform the start word into the end >> word one letter at a time (and the intermediate states must also >> be valid words). For example, one solution to ("warm", "cold") is >> >> ["warm", "ward", "card", "cord", "cold"] >> >> So, one of my first goals was to write a function that would generate >> the possible words a given word could transition to. Here's a simple >> recursive implementation: >> >> transition :: [Char] -> [[Char]] >> transition [] = [] >> transition (c:cs) = map (c:) (transition cs) ++ map (:cs) ['a'..'z'] >> >> For some reason, I find this formulation to be strangely unsatisfying. >> It seems to me that this sort of computation -- i.e. modifying each >> element of a container (but only one at a time) -- should be >> expressible with some higher order function. In a nutshell, what I'm >> looking for would be a function, say "each" with this type. >> >> each :: (Container c) => (a -> a) -> c a -> c (c a) >> >> I'm not particularly sure what Class to substitute for "Container". >> Comonad seemed like a promising solution initially, and provides >> the basis for my current implementation of the "doublets" solver. >> >> The problem being that cobind (extend) takes a function of type (w a - >> > a) >> instead of (a -> a). I suspect that there may be a clever way to write >> "each" by using liftW in combination with .>> or something like that, >> but presently, I'm at a loss. >> >> Has anyone else encountered this sort of abstraction before. I'd love >> to hear your ideas about what Classes "each" should support, and >> how to implement it. >> >> >> Matt >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> >> > From ryani.spam at gmail.com Mon Jun 8 18:21:41 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Mon Jun 8 18:05:22 2009 Subject: [Haskell-cafe] Comonadic composition and the game "Doublets" In-Reply-To: <8FF7CDE0-C429-4067-A8EF-ECC9FC353D9D@gmail.com> References: <8FF7CDE0-C429-4067-A8EF-ECC9FC353D9D@gmail.com> Message-ID: <2f9b2d30906081521o5d5f6838q3bb38cc95d9f2eb0@mail.gmail.com> You can write this in terms of comonads if you have this additional function: ] focus :: (Container w) => (a -> a) -> (w a -> w a) with the idea that "focus" modifies the current "point" of the comonad (the thing returned by extract) while leaving the rest alone. ] focus f w = something (f $ extract w) For lists, this is easy: > focus f (x:xs) = f x : xs Then we can use comonadic "extend" to build the sublists: > each :: (a -> a) -> [a] -> [[a]] > each = extend . focus However, I think each element of the result might be "focused" on the wrong target; we may need to be able to re-focus the lists at the beginning. (I haven't tested this code...) -- ryan On Mon, Jun 8, 2009 at 12:24 PM, Matthew wrote: > Today, I was working on coding a solver for the game "doublets". > It's a word game where you transform the start word into the end > word one letter at a time (and the intermediate states must also > be valid words). ?For example, one solution to ("warm", "cold") is > > ? ? ? ?["warm", "ward", "card", "cord", "cold"] > > So, one of my first goals was to write a function that would generate > the possible words a given word could transition to. ?Here's a simple > recursive implementation: > > ? ? ? ?transition :: [Char] -> [[Char]] > ? ? ? ?transition [] = [] > ? ? ? ?transition (c:cs) = map (c:) (transition cs) ++ map (:cs) ['a'..'z'] > > For some reason, I find this formulation to be strangely unsatisfying. > It seems to me that this sort of computation -- i.e. modifying each > element of a container (but only one at a time) -- should be > expressible with some higher order function. ?In a nutshell, what I'm > looking for would be a function, say "each" with this type. > > ? ? ? ?each :: (Container c) => (a -> a) -> c a -> c (c a) > > I'm not particularly sure what Class to substitute for "Container". > Comonad seemed like a promising solution initially, and provides > the basis for my current implementation of the "doublets" solver. > > The problem being that cobind (extend) takes a function of type (w a -> a) > instead of (a -> a). ?I suspect that there may be a clever way to write > "each" by using liftW in combination with .>> ?or something like that, > but presently, I'm at a loss. > > Has anyone else encountered this sort of abstraction before. ?I'd love > to hear your ideas about what Classes "each" should support, and > how to implement it. > > > Matt > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From lemming at henning-thielemann.de Mon Jun 8 18:39:00 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Mon Jun 8 18:23:40 2009 Subject: [Haskell-cafe] Incremental XML parsing with namespaces? In-Reply-To: <3283f7fe0906081504q608cc96ftfb1eba7bf176acb@mail.gmail.com> References: <3283f7fe0906081139t1b9475d1sa9dba2c2a17ff4fe@mail.gmail.com> <4BB426D6-B5C5-4625-B541-098F3628B135@cs.york.ac.uk> <3283f7fe0906081504q608cc96ftfb1eba7bf176acb@mail.gmail.com> Message-ID: <4A2D9304.2040209@henning-thielemann.de> John Millikin schrieb: > On Mon, Jun 8, 2009 at 1:44 PM, Malcolm > > The interface you linked to doesn't seem to have a way to "resume" > parsing. That is, I can't feed it chunks of text and have it generate > a (ParserState, [Event]) tuple for each chunk. Perhaps this is > possible in Haskell without explicit state management? I've tried to > write a test application to listen on a socket and print events as the > arrive, but with no luck. > > Manually re-parsing the events isn't attractive, because it would > require writing at least part of the parser manually. I had hoped to > re-use an existing XML parser, rather than writing a new one. I think you could use the parser as it is and do the name parsing later. Due to lazy evaluation both parsers would run in an interleaved way. But you may also be interested in: http://hackage.haskell.org/packages/archive/wraxml/0.4.2/doc/html/Text-XML-WraXML-Tree-Tagchup.html using http://hackage.haskell.org/packages/archive/xml-basic/0.1/doc/html/Text-XML-Basic-Name-Qualified.html From mle+hs at mega-nerd.com Mon Jun 8 18:54:17 2009 From: mle+hs at mega-nerd.com (Erik de Castro Lopo) Date: Mon Jun 8 18:38:01 2009 Subject: [Haskell-cafe] Deprecated packages on Hackage? Message-ID: <20090609085417.d8000776.mle+hs@mega-nerd.com> Hi all, Is there a way to list all the deprecated packages on hackage? For instance I found this: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/control-timeout-0.1.2 via a google search but its not listed on the main hackage packages page. However, there are other packages which are marked DEPRECATED in their description strings. Finally, if a package is deprecated it might be usefult to have a reason as well so the hackage entry might say: Deprecated : true (replaced by package XXX) or Deprecated : true (needs maintainer) Cheers, Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/ From nadine.and.henry at pobox.com Mon Jun 8 19:10:18 2009 From: nadine.and.henry at pobox.com (Henry Laxen) Date: Mon Jun 8 18:54:17 2009 Subject: [Haskell-cafe] A generics question Message-ID: Lets suppose I have a file that has encoded things of different types as integers, and now I would like to convert them back into specific instances of a data type. For example, I have a file that contains 1,1,2,3 and I would like the output to be [Red, Red, Green, Blue]. I also would like to do this generically, so that if I wanted to convert the same list of integers into say Sizes, I would get [Small, Small, Medium, Large] Now please have a look at the following code: {-# LANGUAGE DeriveDataTypeable #-} import Data.Generics data Color = Red | Green | Blue deriving (Eq,Ord,Read,Show,Typeable,Data) data Size = Small | Mediaum | Large deriving (Eq,Ord,Read,Show,Typeable,Data) g = Green c = undefined :: Color s = undefined :: Size t = do print $ toConstr g -- Green print $ dataTypeOf c -- DataType {tycon = "Main.Color", datarep = AlgRep [Red,Green,Blue]} convert :: (Data a, Data b) =Int -a -b convert i x = let c = dataTypeConstrs (dataTypeOf x) !! (i-1) in fromConstr c I would like to be able to say: x = convert 1 c and have it assign Red to x then I would like to say: y = convert 1 s and have it assign Small to y, however, when I try that I get: Ambiguous type variable `b' in the constraint: `Data b' arising from a use of `convert' at :1:8-18 Probable fix: add a type signature that fixes these type variable(s) Of course if I say x :: Color = convert 1 c, it works, but I would like to avoid that if possible, as all of the information is already contained in the parameter c. Is there any way to do this? Thanks in advance for your wise counsel. Best wishes, Henry Laxen From duncan.coutts at worc.ox.ac.uk Mon Jun 8 05:57:45 2009 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Mon Jun 8 19:22:42 2009 Subject: [Haskell-cafe] Slow documentation generation on Hackage In-Reply-To: <87d49fnkmh.fsf@malde.org> References: <20090607183022.1793932467A@www.haskell.org> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB6D@EXCHANGE10.campus.tue.nl> <525C5338-5A42-4477-9532-0718D90509D3@ece.cmu.edu> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DBAD@EXCHANGE10.campus.tue.nl> <87d49fnkmh.fsf@malde.org> Message-ID: <1244455065.29805.576.camel@localhost> On Mon, 2009-06-08 at 11:24 +0200, Ketil Malde wrote: > "Niemeijer, R.A." writes: > > > If that is the main concern, would the following not work? > > [...] > > > Result: immediate documentation for every contributor with good > > intentions Having the server generate docs itself would be regressing towards a worse design. The server should just manage upload/download, storage and management of information. It should not be running builds and generating docs. > Or simply, on upload, generate the doc directory with a temporary page > saying that documentation will arrive when it's good and ready? And use a design where there isn't just a single build client, like the design for the new hackage-server. Any authorised client should be able to upload docs. That should include the package maintainer as well as authorised build bots. Then we can easily adjust the time between package upload and documentation generation without having to tell the server anything. Duncan From ross at soi.city.ac.uk Mon Jun 8 19:41:46 2009 From: ross at soi.city.ac.uk (Ross Paterson) Date: Mon Jun 8 19:25:30 2009 Subject: [Haskell-cafe] Deprecated packages on Hackage? In-Reply-To: <20090609085417.d8000776.mle+hs@mega-nerd.com> References: <20090609085417.d8000776.mle+hs@mega-nerd.com> Message-ID: <20090608234146.GA11030@soi.city.ac.uk> On Tue, Jun 09, 2009 at 08:54:17AM +1000, Erik de Castro Lopo wrote: > Is there a way to list all the deprecated packages on hackage? Not unless you have an account on that machine. They're hiding, because their maintainers wanted them withdrawn. > Finally, if a package is deprecated it might be usefult to have > a reason as well so the hackage entry might say: > > Deprecated : true (replaced by package XXX) > > or > > Deprecated : true (needs maintainer) The former exists, and is used by the following: http-shed -> httpd-shed ieee754-parser -> data-binary-ieee754 Thingie -> Hieroglyph From iavor.diatchki at gmail.com Mon Jun 8 19:48:53 2009 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Mon Jun 8 19:32:33 2009 Subject: [Haskell-cafe] Re: Building network package on Windows In-Reply-To: References: <5ab17e790906062143h3968488bg577cdbe0de796bd9@mail.gmail.com> <5ab17e790906071704h19255d38oa82b48ef842764f9@mail.gmail.com> Message-ID: <5ab17e790906081648i2d9e11f6ic189667c6d6d470a@mail.gmail.com> Hi, As Thomas pointed out, it is not clear if this is a bug, or if there is something confused between the different versions of Windows and MinGW (or I just did something wrong) but I'll make a ticket so that we can track the issue. I am by no means a Windows developer but I would be happy to try out fixes/ideas on my Windows machine as I think that it is important that we have as good support for Windows as we do on the various Unix-like systems. -Iavor On Mon, Jun 8, 2009 at 1:23 PM, Bryan O'Sullivan wrote: > On Sun, Jun 7, 2009 at 5:04 PM, Iavor Diatchki > wrote: >> >> Here is an update, in case anyone else runs into the same problem. > > Thanks for following up. I wrote the code that performs that check, but > unfortunately I don't have access to all of the permutations of Windows that > are out there, so my ability to test is rather limited. I'm sorry for the > trouble it caused you. Perhaps Vista Home Basic doesn't have IPv6 support? > If that conjecture is true, I'm not sure how I'd have found it out :-( More > likely, the name mangling is going wrong. > > As for your point that the network package exhibits different APIs depending > on the underlying system, that's true, but it's hard to avoid. Writing a > compatibility API for systems that don't have functioning IPv6 APIs is a > chunk of boring work, and I had thought that such systems were rare. > > Anyway, please do file a bug, and we'll take the discussion of how to > reproduce and fix your problem there. > > Thanks, > Bryan. > From ross at soi.city.ac.uk Mon Jun 8 19:52:26 2009 From: ross at soi.city.ac.uk (Ross Paterson) Date: Mon Jun 8 19:36:08 2009 Subject: [Haskell-cafe] Slow documentation generation on Hackage In-Reply-To: <525C5338-5A42-4477-9532-0718D90509D3@ece.cmu.edu> References: <20090607183022.1793932467A@www.haskell.org> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB6D@EXCHANGE10.campus.tue.nl> <525C5338-5A42-4477-9532-0718D90509D3@ece.cmu.edu> Message-ID: <20090608235226.GA11080@soi.city.ac.uk> On Mon, Jun 08, 2009 at 04:36:14AM -0400, Brandon S. Allbery KF8NH wrote: > Additionally, I *think* haddock is run as part of the automated build > tests, which (again) happen on a regular schedule instead of being > triggered by uploads to avoid potential denial of service attacks. That's correct. One workaround is to upload your package just before 0:00, 6:00, 12:00 or 18:00 UK time. From dagit at codersbase.com Mon Jun 8 20:20:45 2009 From: dagit at codersbase.com (Jason Dagit) Date: Mon Jun 8 20:04:26 2009 Subject: [Haskell-cafe] A generics question In-Reply-To: References: Message-ID: On Mon, Jun 8, 2009 at 4:10 PM, Henry Laxen wrote: > Lets suppose I have a file that has encoded things of different > types as integers, and now I would like to convert them back > into specific instances of a data type. For example, I have a > file that contains 1,1,2,3 and I would like the output to be > [Red, Red, Green, Blue]. I also would like to do this > generically, so that if I wanted to convert the same list of > integers into say Sizes, I would get [Small, Small, Medium, > Large] Now please have a look at the following code: > > {-# LANGUAGE DeriveDataTypeable #-} > import Data.Generics > data Color = Red | Green | Blue deriving (Eq,Ord,Read,Show,Typeable,Data) > data Size = Small | Mediaum | Large deriving > (Eq,Ord,Read,Show,Typeable,Data) What about making both of these instances of Enum instead of using Data and Typeable? You'd get fromEnum and toEnum. Which I think, would give you the int mapping that you are after. fromEnum :: Enum a => a -> Int toEnum :: Enum a => Int -> a Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090608/50574287/attachment.html From toby.hutton at gmail.com Mon Jun 8 20:57:21 2009 From: toby.hutton at gmail.com (Toby Hutton) Date: Mon Jun 8 20:41:24 2009 Subject: [Haskell-cafe] Applying Data.Map In-Reply-To: <781453.33760.qm@web31106.mail.mud.yahoo.com> References: <781453.33760.qm@web31106.mail.mud.yahoo.com> Message-ID: <711894390906081757x67dca8c5o54f1a9cbd86a0b2e@mail.gmail.com> Although in this example using Data.Map is overkill, if the alphabet was very large then Data.Map probably would be the way to go. In that case I'd use: map head . group . sort instead of nub . sort since it's noticeably quicker for large lists. This is because nub needs to preserve the order of input, removing redundancies, but you're sorting it anyway. Also, in map (\c -> m Map.! c) s you can use the 'section' (m Map.!)instead. e.g., map (m Map.!) s The Map.! is ugly though. As you're only using fromList and (!) from Data.Map, I'd just import those explicitly since they don't clash with Prelude. Then you'd have map (m !) s Toby. On Tue, Jun 9, 2009 at 4:59 AM, michael rice wrote: > I wrote a Haskell solution for the Prolog problem stated below. I had > written a function SQUISH before discovering that NUB does the same thing. > While the solution works, I thought maybe I could apply some functions in > the Data.Map module, and so wrote a second version of SERIALIZE, one no > longer needing TRANSLATE. Using the Data.Map module is probably overkill for > this particular problem, but wanted to familiarize myself with Map type. > Suggestions welcome. Prolog code also included below for those interested. > > Michael > > =========== > > {- > From "Prolog By Example", Coelho, Cotta, Problem 42, pg. 63 > > Verbal statement: > Generate a list of serial numbers for the items of a given list, > the members of which are to be numbered in alphabetical order. > > For example, the list [p,r,o,l,o,g] must generate [4,5,3,2,3,1] > -} > > {- > Prelude> :l serialize > [1 of 1] Compiling Main ( serialize.hs, interpreted ) > Ok, modules loaded: Main. > *Main> serialize "prolog" > [4,5,3,2,3,1] > *Main> > -} > > ===========Haskell code========== > > import Data.Char > import Data.List > import Data.Map (Map) > import qualified Data.Map as Map > > {- > translate :: [Char] -> [(Char,Int)] -> [Int] > translate [] _ = [] > translate (x:xs) m = (fromJust (lookup x m)) : (translate xs m ) > -} > > {- > serialize :: [Char] -> [Int] > serialize s = let c = nub $ sort s > n = [1..(length c)] > in translate s (zip c n) > -} > > serialize :: [Char] -> [Int] > serialize s = let c = nub $ sort s > n = [1..(length c)] > m = Map.fromList $ zip c n > in map (\c -> m Map.! c) s > > ============Prolog code============ > > serialize(L,R) :- pairlists(L,R,A),arrange(A,T), > numbered(T,1,N). > ? <- typo? > pairlists([X|L],[Y|R],[pair(X,Y)|A]) :- pairlist(L,R,A). > pairlists([],[],[]). > > arrange([X|L],tree(T1,X,T2)) :- partition(L,X,L1,L2), > arrange(L1,T1), > arrange(L2,T2). > arrange([],_). > > partition([X|L],X,L1,L2) :- partition(L,X,L1,L2). > partition([X|L],Y,[X|L1],L2) :- before(X,Y), > partition(L,Y,L1,L2). > partition([X|L],Y,L1,[X|L2]) :- before(Y,X), > partition(L,Y,L1,L2). > partition([],_,[],[]). > > before(pair(X1,Y1),pair(X2,Y2)) :- X1 > numbered(tree(T1,pair(X,N1),T2),N0,N) :- numbered(T1,N0,N1), > N2 is N1+1, > numbered(T2,N2,N). > numbered(void,N,N). > > ============Prolog examples======== > Execution: > > ?- serialize([p,r,o,l,o,g]). > [4,5,3,2,3,1] > ?- serialize ([i,n,t,.,a,r,t,i,f,i,c,i,a,l]). > [5,7,9,1,2,8,9,5,4,5,3,5,2,6] > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090608/a2d06c72/attachment.html From jmillikin at gmail.com Mon Jun 8 23:00:03 2009 From: jmillikin at gmail.com (John Millikin) Date: Mon Jun 8 22:43:47 2009 Subject: [Haskell-cafe] Incremental XML parsing with namespaces? In-Reply-To: <4A2D9304.2040209@henning-thielemann.de> References: <3283f7fe0906081139t1b9475d1sa9dba2c2a17ff4fe@mail.gmail.com> <4BB426D6-B5C5-4625-B541-098F3628B135@cs.york.ac.uk> <3283f7fe0906081504q608cc96ftfb1eba7bf176acb@mail.gmail.com> <4A2D9304.2040209@henning-thielemann.de> Message-ID: <3283f7fe0906082000y48cf4f9flfb23a10458ee669d@mail.gmail.com> On Mon, Jun 8, 2009 at 3:39 PM, Henning Thielemann wrote: > I think you could use the parser as it is and do the name parsing later. > Due to lazy evaluation both parsers would run in an interleaved way. > I've been trying to figure out how to get this to work with lazy evaluation, but haven't made much headway. Tips? The only way I can think of to get incremental parsing working is to maintain explicit state, but I also can't figure out how to achieve this with the parsers I've tested (HaXml, HXT, hexpat). Here's a working example of what I'm trying to do, in Python. It reads XML from stdin, prints events as they are parsed, and will terminate when the document ends: ########################## from xml.sax import handler, saxutils, expatreader class ContentHandler (handler.ContentHandler): def __init__ (self): self.events = [] self.level = 0 def startElementNS (self, ns_name, lname, attrs): self.events.append (("BEGIN", ns_name, lname, dict (attrs))) self.level += 1 def endElementNS (self, ns_name, lname): self.events.append (("END", ns_name, lname)) self.level -= 1 def characters (self, content): self.events.append (("TEXT", content)) def main (): parser = expatreader.ExpatParser () content = ContentHandler () parser.setFeature (handler.feature_namespaces, True) parser.setContentHandler (content) got_events = False while content.level > 0 or (not got_events): text = raw_input ("Enter XML:\n") parser.feed (text) print content.events content.events = [] got_events = True if __name__ == "__main__": main() ############################### $ python incremental.py Enter XML: [('BEGIN', (u'urn:test', u'test'), u'test', {}), ('BEGIN', (u'urn:test', u'test2'), u'test2', {}), ('BEGIN', (u'urn:test', u'test3'), u'test3', {})] Enter XML: text content goes here [('END', (u'urn:test', u'test3'), None), ('END', (u'urn:test', u'test2'), None), ('BEGIN', (u'urn:test', u'test2'), u'test2', {(None, u'a'): u'b'}), ('END', (u'urn:test', u'test2'), None), ('TEXT', u'text content goes here')] Enter XML: [('END', (u'urn:test', u'test'), None)] ############################# As demonstrated, the parser retains state (namespaces, nesting) between text inputs. Are there any XML parsers for Haskell that support this incremental behavior? From s.clover at gmail.com Mon Jun 8 23:18:54 2009 From: s.clover at gmail.com (Sterling Clover) Date: Mon Jun 8 23:01:33 2009 Subject: [Haskell-cafe] A generics question In-Reply-To: References: Message-ID: <8C41809E-BE80-4CFF-BF6A-1D8A4A156653@gmail.com> On Jun 8, 2009, at 7:10 PM, Henry Laxen wrote: > > convert :: (Data a, Data b) =Int -a -b > convert i x = > let c = dataTypeConstrs (dataTypeOf x) !! (i-1) > in fromConstr c > > I would like to be able to say: x = convert 1 c and have it > assign Red to x then I would like to say: y = convert 1 s and > have it assign Small to y, however, when I try that I get: > > Ambiguous type variable `b' in the constraint: > `Data b' arising from a use of `convert' at :1:8-18 > Probable fix: add a type signature that fixes these type > variable(s) > > Of course if I say x :: Color = convert 1 c, it works, but I > would like to avoid that if possible, as all of the information > is already contained in the parameter c. Is there any way to do > this? Thanks in advance for your wise counsel. > > Best wishes, > Henry Laxen The type signature for 'convert' is throwing away the information you want. Try it with the following type signature and it should work fine: convert :: (Data a) => Int -> a -> a Of course, as has been noted, SYB is a rather big sledgehammer for the insect in question. Cheers, S. From s.clover at gmail.com Mon Jun 8 23:29:54 2009 From: s.clover at gmail.com (Sterling Clover) Date: Mon Jun 8 23:12:32 2009 Subject: [Haskell-cafe] ANNOUNCE: StrictBench 0.1 - Benchmarking code through strict evaluation In-Reply-To: References: <20090607183022.1793932467A@www.haskell.org> <9BEB5EF43B5A4042B60C0D8179782DB3D69443DB27@EXCHANGE10.campus.tue.nl> Message-ID: <87E7EF8E-0AB9-42D7-8BBB-F2B8AA6CF8B9@gmail.com> On Jun 8, 2009, at 6:58 AM, Magnus Therning wrote: > Is there no way to force repeated evaluation of a pure value? (It'd > be nice to be able to perform time measurements on pure code so that > it's possible to compare Haskell implementations of algorithms to > implementations in other languages, without running into confounding > factors.) This perhaps introduces too much inefficiency, but one trick is to pack the computation into an existential. i.e. calculate :: Floating b => (forall c. Floating c => c) -> b calculate = id This method is used to evaluate the same numeric formula with different rounding modes in ieee-utils. http://hackage.haskell.org/packages/archive/ieee-utils/0.4.0/doc/html/ src/Numeric-IEEE-Monad.html#perturb Cheers, S. From mle+hs at mega-nerd.com Mon Jun 8 23:34:18 2009 From: mle+hs at mega-nerd.com (Erik de Castro Lopo) Date: Mon Jun 8 23:18:01 2009 Subject: [Haskell-cafe] Deprecated packages on Hackage? In-Reply-To: <20090608234146.GA11030@soi.city.ac.uk> References: <20090609085417.d8000776.mle+hs@mega-nerd.com> <20090608234146.GA11030@soi.city.ac.uk> Message-ID: <20090609133418.42c2c533.mle+hs@mega-nerd.com> Ross Paterson wrote: > On Tue, Jun 09, 2009 at 08:54:17AM +1000, Erik de Castro Lopo wrote: > > Is there a way to list all the deprecated packages on hackage? > > Not unless you have an account on that machine. They're hiding, because > their maintainers wanted them withdrawn. Well there is at least one package (network-dns) where the maintainter doesn't want to maintain it any more but would be happy for someone else to take it over. It would be nice if something like this could be represented in the package metadata. Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/ From stefan at cs.uu.nl Mon Jun 8 23:46:52 2009 From: stefan at cs.uu.nl (Stefan Holdermans) Date: Mon Jun 8 23:30:34 2009 Subject: [Haskell-cafe] A generics question In-Reply-To: References: Message-ID: Henry, Jason pointed out: > You'd get fromEnum and toEnum. Which I think, would give you the > int mapping that you are after. > > fromEnum :: Enum a => a -> Int > toEnum :: Enum a => Int -> a To me, this would indeed seem the way to go for your particular example. Moreover, as for generic producer functions in general, the pattern suggested by the Prelude would be to have c :: Color c = undefined convert :: Data a => Int -> a convert i x = let c = dataTypeConstrs (dataTypeOf x) !! (i-1) in fromConstr c and then use it as in convert 1 `asTypeOf` c You'll find out that in most cases the (pseudo) "type annotation" isn't really needed and the type of the value to produce can be determined automatically by the context. Cheers, Stefan From stefan at cs.uu.nl Mon Jun 8 23:50:20 2009 From: stefan at cs.uu.nl (Stefan Holdermans) Date: Mon Jun 8 23:34:01 2009 Subject: [Haskell-cafe] A generics question In-Reply-To: References: Message-ID: Henry, Ah, pressed send way to early. Of course, the definition should change a little as well: convert :: Data a => Int -> a convert i = x where x = fromConstr ( dataTypeConstrs (dataTypeOf x) !! (i - 1) ) Cheers, Stefan From iavor.diatchki at gmail.com Tue Jun 9 01:18:55 2009 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Tue Jun 9 01:02:37 2009 Subject: [Haskell-cafe] Re: Building network package on Windows In-Reply-To: <5ab17e790906081648i2d9e11f6ic189667c6d6d470a@mail.gmail.com> References: <5ab17e790906062143h3968488bg577cdbe0de796bd9@mail.gmail.com> <5ab17e790906071704h19255d38oa82b48ef842764f9@mail.gmail.com> <5ab17e790906081648i2d9e11f6ic189667c6d6d470a@mail.gmail.com> Message-ID: <5ab17e790906082218h55b4680ayc9a2b3c5ee679e70@mail.gmail.com> Hi, OK, I think that I found and fixed the problem. As Thomas pointed out, the configure script is not wrong. The problem turned out to be the foreign import for "getnameinfo" (this was the missing symbol). Attached to this e-mail should be a darcs patch that fixes the problem. -Iavor On Mon, Jun 8, 2009 at 4:48 PM, Iavor Diatchki wrote: > Hi, > As Thomas pointed out, it is not clear if this is a bug, or if there > is something confused between the different versions of Windows and > MinGW (or I just did something wrong) but I'll make a ticket so that > we can track the issue. ?I am by no means a Windows developer but I > would be happy to try out fixes/ideas on my Windows machine as I think > that it is important that we have as good support for Windows as we do > on the various Unix-like systems. > -Iavor > > On Mon, Jun 8, 2009 at 1:23 PM, Bryan O'Sullivan wrote: >> On Sun, Jun 7, 2009 at 5:04 PM, Iavor Diatchki >> wrote: >>> >>> Here is an update, in case anyone else runs into the same problem. >> >> Thanks for following up. I wrote the code that performs that check, but >> unfortunately I don't have access to all of the permutations of Windows that >> are out there, so my ability to test is rather limited. I'm sorry for the >> trouble it caused you. Perhaps Vista Home Basic doesn't have IPv6 support? >> If that conjecture is true, I'm not sure how I'd have found it out :-( More >> likely, the name mangling is going wrong. >> >> As for your point that the network package exhibits different APIs depending >> on the underlying system, that's true, but it's hard to avoid. Writing a >> compatibility API for systems that don't have functioning IPv6 APIs is a >> chunk of boring work, and I had thought that such systems were rare. >> >> Anyway, please do file a bug, and we'll take the discussion of how to >> reproduce and fix your problem there. >> >> Thanks, >> Bryan. >> > -------------- next part -------------- A non-text attachment was scrubbed... Name: patch Type: application/octet-stream Size: 1337 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090609/7d6d0fe0/patch.obj From ninegua at gmail.com Tue Jun 9 01:24:53 2009 From: ninegua at gmail.com (Paul L) Date: Tue Jun 9 01:08:33 2009 Subject: [Haskell-cafe] Re: I love purity, but it's killing me. In-Reply-To: <20090607014853.GA30135@mantle.rutgers.edu> References: <594c1e830802072233n2b36ca82wd3c778f22edd4564@mail.gmail.com> <4cka85-223.ln1@mantle.rutgers.edu> <856033f20905270058q493a254ah4623fbc354096574@mail.gmail.com> <20090607014853.GA30135@mantle.rutgers.edu> Message-ID: <856033f20906082224s2b7d5391gdc7a4ed913004639@mail.gmail.com> Interpreting lambda calculus is neither cheap or efficient, otherwise we wouldn't all be using compilers :-) By "interpretive overhead" of adding Let/Rec/LetRec to an object language I mean the need to introduce variables, scoping, and environment (mapping variables to either values or structures they bind to) during interpretations, which are otherwise not needed in the object language. I can't show you how I can do better because I don't have a solution. The open question is whether there exists such a solution that's both elegant and efficient at maintain proper sharing in the object language. We certainly can get rid of all interpretive overheads by either having a "tagless" interpreter (as in Oleg and Shan's paper), or by direct compilation. But so far I don't see how a tagless interpreter could handle sharing when it can't be distinguished in the host language. One would argue that the overhead of variables (and the environment associated with them) can be avoided by having a higher order syntax, but that has its own problem. Let me illustrate with a data structure that uses higher order Rec. data C a = Val a | ... | Rec (C a -> C a) val :: C a -> a val (Val x) = x val ... val (Rec f) = val (fix f) where fix f = f (fix f) update :: C a -> C a update (val x) = ... update ... update (Rec f) = Rec (\x -> ...) The problem is right there in the creation of a new closure during update (Rec f). Haskell would not evaluate under lambda, and repeated updates will inevitably result in space and time leaks. -- Regards, Paul Liu Yale Haskell Group http://www.haskell.org/yale On 6/6/09, Chung-chieh Shan wrote: > On 2009-05-27T03:58:58-0400, Paul L wrote: >> One possible solution is to further introduce a fixed point data >> constructor, a Rec or even LetRec to explicitly capture cycles. But >> then you still incur much overheads interpreting them, > > I don't understand this criticism -- what interpretive overhead do you > mean? Certainly the Rec/LetRec encoding is pretty efficient for one > object language with cycles, namely the lambda calculus with Rec or > LetRec. :) > > One concrete way for you to explain what interpretive overhead you mean, > if it's not too much trouble, might be to compare a Rec/LetRec encoding > of a particular object language to another encoding that does not have > the interpretive overhead you mean and is therefore more efficient. > > -- > Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig > We want our revolution, and we want it now! -- Marat/Sade > We want our revolution, and we'll take it at such time as > you've gotten around to delivering it -- Haskell programmer > From oleg at okmij.org Tue Jun 9 02:47:23 2009 From: oleg at okmij.org (oleg@okmij.org) Date: Tue Jun 9 02:32:23 2009 Subject: [Haskell-cafe] Re: Question on rank-N polymorphism Message-ID: <20090609064723.E999F176F6@Adric.metnet.navy.mil> Ryan Ingram discussed a question of writing > fs f g = (f fst, g snd) so that fs ($ (1, "2")) type checks. This is not that difficult: > {-# LANGUAGE RankNTypes, MultiParamTypeClasses -#} > {-# LANGUAGE FunctionalDependencies, FlexibleInstances #-} > > class Apply f x y | f x -> y where > apply :: f -> x -> y > > instance Apply (x->y) x y where > apply = ($) > > data Fst = Fst > data Snd = Snd > > instance Apply Fst (x,y) x where > apply _ = fst > > instance Apply Snd (x,y) y where > apply _ = snd The function in question: > fs3 f = (apply f Fst, apply f Snd) -- One of Wouter Swierstra's examples -- examples = (fs id, fs repeat, fs (\x -> [x]), fs ((,)id)) > data Id a = Id > instance Apply (Id a) Fst ((a,a) -> a) where > apply _ _ = fst > instance Apply (Id a) Snd ((a,a) -> a) where > apply _ _ = snd > ex1 = fs3 Id Now, Ryan's main example > newtype Pair a b = Pair (forall w. (((a,b) -> w) -> w)) > instance Apply (Pair a b) Fst a where > apply (Pair f) _ = f fst > instance Apply (Pair a b) Snd b where > apply (Pair f) _ = f snd > ex4 = fs3 (Pair ($ (1, "2"))) > -- (1,"2") Incidentally, a different variation of this example is discussed in http://okmij.org/ftp/Computation/extra-polymorphism.html Indeed, such a selection from a pair occurs quite often... From ketil at malde.org Tue Jun 9 03:50:31 2009 From: ketil at malde.org (Ketil Malde) Date: Tue Jun 9 03:33:47 2009 Subject: [Haskell-cafe] Deprecated packages on Hackage? In-Reply-To: <20090609133418.42c2c533.mle+hs@mega-nerd.com> (Erik de Castro Lopo's message of "Tue\, 9 Jun 2009 13\:34\:18 +1000") References: <20090609085417.d8000776.mle+hs@mega-nerd.com> <20090608234146.GA11030@soi.city.ac.uk> <20090609133418.42c2c533.mle+hs@mega-nerd.com> Message-ID: <87my8hn8vs.fsf@malde.org> Erik de Castro Lopo writes: > Finally, if a package is deprecated it might be usefult to have > a reason as well so the hackage entry might say: > > Deprecated : true (replaced by package XXX) > > or > > Deprecated : true (needs maintainer) Or just Deprecated: (reason)?. Couldn't the presence of a Deprecated field be sufficient - the "true" seems gratuitious to me. One could also have something like Superseeds and Superseeded-by, of course, if that turns out to be the usual reasons for deprecation. And in a later post: > Well there is at least one package (network-dns) where the maintainter > doesn't want to maintain it any more but would be happy for someone > else to take it over. > It would be nice if something like this could be represented in the > package metadata. Absence of a "Maintainer" field? One problem is that the last uploaded package is likely to have an active maintainer, and when the maintainer disappears, he or she is unlikely to do a last update changing the status. Perhaps we could have automated emails to maintainers twice a year or so? -k -- If I haven't seen further, it is by standing in the footprints of giants From jochem at functor.nl Tue Jun 9 03:54:24 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Tue Jun 9 03:38:11 2009 Subject: [Haskell-cafe] How to compile base? In-Reply-To: References: Message-ID: <4A2E1530.6070504@functor.nl> Henk-Jan van Tuyl wrote: > I tried to compile base-4.0.0.0 (on Windows XP) as follows: > [...]\base\4.0.0.0>runhaskell Setup configure > : module `Prelude' is not loaded > It seems that Base needs another way to compile, how? > AFAIK base is shipped with GHC, and cannot be compiled separately. GHC 6.10.1 ships with base-4.0.0.0, later versions in the 6.10.x series may have a somewhat later version. Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From gtener at gmail.com Tue Jun 9 04:21:24 2009 From: gtener at gmail.com (=?UTF-8?Q?Krzysztof_Skrz=C4=99tnicki?=) Date: Tue Jun 9 04:05:05 2009 Subject: [Haskell-cafe] Incremental XML parsing with namespaces? In-Reply-To: <3283f7fe0906081139t1b9475d1sa9dba2c2a17ff4fe@mail.gmail.com> References: <3283f7fe0906081139t1b9475d1sa9dba2c2a17ff4fe@mail.gmail.com> Message-ID: <220e47b40906090121y1baadde5ldcf9fe7d78a26075@mail.gmail.com> On Mon, Jun 8, 2009 at 20:39, John Millikin wrote: > I'm trying to convert an XML document, incrementally, into a sequence > of XML events. A simple example XML document: > > > ? ?Doc title > ? ?abc1234 > ? ?Hello world! > > > The document can be very large, and arrives in chunks over a socket, > so I need to be able to "feed" the text data into a parser and receive > a list of XML events per chunk. Chunks can be separated in time by > intervals of several minutes to an hour, so pausing processing for the > arrival of the entire document is not an option. The type signatures > would be something like: > > type Namespace = String > type LocalName = String > > data Attribute = Attribute Namespace LocalName String > > data XMLEvent = > ? ?EventElementBegin Namespace LocalName [Attribute] | > ? ?EventElementEnd Namespace LocalName | > ? ?EventContent String | > ? EventError String > > parse :: Parser -> String -> (Parser, [XMLEvent]) > > I've looked at HaXml, HXT, and hexpat, and unless I'm missing > something, none of them can achieve this: > > + HaXml and hexpat seem to disregard namespaces entirely -- that is, > the root element is parsed to "doc" instead of > ("org:myproject:mainns", "doc"), and the second child is "x:ref" > instead of ("org:myproject:otherns", "ref"). Obviously, this makes > parsing mixed-namespace documents effectively impossible. I found an > email from 2004[1] that mentions a "filter" for namespace support in > HaXml, but no further information and no working code. I would recommend hexpat to do the job. Contrary to what you are saying, hexpat does offer namespace handling: http://hackage.haskell.org/packages/archive/hexpat/0.8/doc/html/Text-XML-Expat-Namespaced.html Perhaps you need more than that? Personally I found hexpat to be fast, space efficient and easy to use. Here is the representation I got for your example. Please note the namespaces in right places. * > (toNamespaced ( toQualified t')) Element {eName = NName {nnNamespace = Just "org:myproject:mainns", nnLocalPart = "doc"}, eAttrs = [(NName {nnNamespace = Just "http://www.w3.org/2000/xmlns/", nnLocalPart = "x"},"org:myproject:otherns"),(NName {nnNamespace = Just "org:myproject:mainns", nnLocalPart = "xmlns"},"org:myproject:mainns")], eChildren = [Text "\n",Text " ",Element {eName = NName {nnNamespace = Just "org:myproject:mainns", nnLocalPart = "title"}, eAttrs = [], eChildren = [Text "Doc title"]},Text "\n",Text " ",Element {eName = NName {nnNamespace = Just "org:myproject:otherns", nnLocalPart = "ref"}, eAttrs = [], eChildren = [Text "abc1234"]},Text "\n",Text " ",Element {eName = NName {nnNamespace = Just "http://www.w3.org/1999/xhtml", nnLocalPart = "html"}, eAttrs = [(NName {nnNamespace = Just "http://www.w3.org/1999/xhtml", nnLocalPart = "xmlns"},"http://www.w3.org/1999/xhtml")], eChildren = [Element {eName = NName {nnNamespace = Just "http://www.w3.org/1999/xhtml", nnLocalPart = "body"}, eAttrs = [], eChildren = [Text "Hello world!"]}]},Text "\n"]} Best regards Krzysztof Skrz?tnicki From chris at eidhof.nl Tue Jun 9 04:30:32 2009 From: chris at eidhof.nl (Chris Eidhof) Date: Tue Jun 9 04:14:17 2009 Subject: [Haskell-cafe] Dutch HUG meeting tonight in Amsterdam Message-ID: Hi everyone, Tonight there will be another meeting of the Dutch Haskell Users' Group! This time we'll meet in Amsterdam, in the library. On the wiki [1] you can find the details of how to reach it. We'll be at the top floor and shouldn't be hard to recognize. The meeting is set to begin at 19:30. Everybody's welcome, from beginners to advanced haskellers. Even if you never programmed in Haskell before it'll probably be a lot of fun. See you tonight! There are a lot of international people joining, so no knowledge of Dutch is necessary. If you're joining, also be sure to subscribe to our mailinglist [2]. See you tonight! -chris [1]: http://www.haskell.org/haskellwiki/Dutch_HUG [2]: http://groups.google.com/group/dutch-hug From gtener at gmail.com Tue Jun 9 04:33:53 2009 From: gtener at gmail.com (=?UTF-8?Q?Krzysztof_Skrz=C4=99tnicki?=) Date: Tue Jun 9 04:17:37 2009 Subject: [Haskell-cafe] Incremental XML parsing with namespaces? In-Reply-To: <220e47b40906090121y1baadde5ldcf9fe7d78a26075@mail.gmail.com> References: <3283f7fe0906081139t1b9475d1sa9dba2c2a17ff4fe@mail.gmail.com> <220e47b40906090121y1baadde5ldcf9fe7d78a26075@mail.gmail.com> Message-ID: <220e47b40906090133j642ee25dqa4539da9e01a1f21@mail.gmail.com> And just to provide an example of working program: --- module Main where import Text.XML.Expat.Qualified import Text.XML.Expat.Namespaced import Text.XML.Expat.Tree import qualified Data.ByteString.Lazy as BSL main = do f <- BSL.readFile "doc1.xml" let (tree,error) = parseTree Nothing f case error of Nothing -> putStrLn "Here you are: " >> (print . toNamespaced . toQualified $ (tree :: Node String String)) Just err -> putStrLn "Error!" >> print err --- $ ./hexpat-test Here you are: Element {eName = NName {nnNamespace = Just "org:myproject:mainns", nnLocalPart = "doc"}, eAttrs = [(NName {nnNamespace = Just "http://www.w3.org/2000/xmlns/", nnLocalPart = "x"},"org:myproject:otherns"),(NName {nnNamespace = Just "org:myproject:mainns", nnLocalPart = "xmlns"},"org:myproject:mainns")], eChildren = [Text "\n",Text " ",Element {eName = NName {nnNamespace = Just "org:myproject:mainns", nnLocalPart = "title"}, eAttrs = [], eChildren = [Text "Doc title"]},Text "\n",Text " ",Element {eName = NName {nnNamespace = Just "org:myproject:otherns", nnLocalPart = "ref"}, eAttrs = [], eChildren = [Text "abc1234"]},Text "\n",Text " ",Element {eName = NName {nnNamespace = Just "http://www.w3.org/1999/xhtml", nnLocalPart = "html"}, eAttrs = [(NName {nnNamespace = Just "http://www.w3.org/1999/xhtml", nnLocalPart = "xmlns"},"http://www.w3.org/1999/xhtml")], eChildren = [Element {eName = NName {nnNamespace = Just "http://www.w3.org/1999/xhtml", nnLocalPart = "body"}, eAttrs = [], eChildren = [Text "Hello world!"]}]},Text "\n"]} # we mess with doc1.xml and exchange for $ ./hexpat-test Error! XMLParseError "mismatched tag" (XMLParseLocation {xmlLineNumber = 5, xmlColumnNumber = 2, xmlByteIndex = 205, xmlByteCount = 0}) Best regards Krzysztof Skrz?tnicki 2009/6/9 Krzysztof Skrz?tnicki : > On Mon, Jun 8, 2009 at 20:39, John Millikin wrote: >> I'm trying to convert an XML document, incrementally, into a sequence >> of XML events. A simple example XML document: >> >> >> ? ?Doc title >> ? ?abc1234 >> ? ?Hello world! >> >> >> The document can be very large, and arrives in chunks over a socket, >> so I need to be able to "feed" the text data into a parser and receive >> a list of XML events per chunk. Chunks can be separated in time by >> intervals of several minutes to an hour, so pausing processing for the >> arrival of the entire document is not an option. The type signatures >> would be something like: >> >> type Namespace = String >> type LocalName = String >> >> data Attribute = Attribute Namespace LocalName String >> >> data XMLEvent = >> ? ?EventElementBegin Namespace LocalName [Attribute] | >> ? ?EventElementEnd Namespace LocalName | >> ? ?EventContent String | >> ? EventError String >> >> parse :: Parser -> String -> (Parser, [XMLEvent]) >> >> I've looked at HaXml, HXT, and hexpat, and unless I'm missing >> something, none of them can achieve this: >> >> + HaXml and hexpat seem to disregard namespaces entirely -- that is, >> the root element is parsed to "doc" instead of >> ("org:myproject:mainns", "doc"), and the second child is "x:ref" >> instead of ("org:myproject:otherns", "ref"). Obviously, this makes >> parsing mixed-namespace documents effectively impossible. I found an >> email from 2004[1] that mentions a "filter" for namespace support in >> HaXml, but no further information and no working code. > > I would recommend hexpat to do the job. Contrary to what you are > saying, hexpat does offer namespace handling: > http://hackage.haskell.org/packages/archive/hexpat/0.8/doc/html/Text-XML-Expat-Namespaced.html > Perhaps you need more than that? > > Personally I found hexpat to be fast, space efficient and easy to use. > > Here is the representation I got for your example. Please note the > namespaces in right places. > * > (toNamespaced ( toQualified t')) > Element {eName = NName {nnNamespace = Just "org:myproject:mainns", > nnLocalPart = "doc"}, eAttrs = [(NName {nnNamespace = Just > "http://www.w3.org/2000/xmlns/", nnLocalPart = > "x"},"org:myproject:otherns"),(NName {nnNamespace = Just > "org:myproject:mainns", nnLocalPart = > "xmlns"},"org:myproject:mainns")], eChildren = [Text "\n",Text " > ",Element {eName = NName {nnNamespace = Just "org:myproject:mainns", > nnLocalPart = "title"}, eAttrs = [], eChildren = [Text "Doc > title"]},Text "\n",Text " ? ?",Element {eName = NName {nnNamespace = > Just "org:myproject:otherns", nnLocalPart = "ref"}, eAttrs = [], > eChildren = [Text "abc1234"]},Text "\n",Text " ? ?",Element {eName = > NName {nnNamespace = Just "http://www.w3.org/1999/xhtml", nnLocalPart > = "html"}, eAttrs = [(NName {nnNamespace = Just > "http://www.w3.org/1999/xhtml", nnLocalPart = > "xmlns"},"http://www.w3.org/1999/xhtml")], eChildren = [Element {eName > = NName {nnNamespace = Just "http://www.w3.org/1999/xhtml", > nnLocalPart = "body"}, eAttrs = [], eChildren = [Text "Hello > world!"]}]},Text "\n"]} > > Best regards > > Krzysztof Skrz?tnicki > From v.reshetnikov at gmail.com Tue Jun 9 05:54:34 2009 From: v.reshetnikov at gmail.com (Vladimir Reshetnikov) Date: Tue Jun 9 05:38:14 2009 Subject: [Haskell-cafe] Unification for rank-N types Message-ID: <4770d2590906090254lce74a8endc05f2d69b33004d@mail.gmail.com> Hi, I have the following code: ------------------------------------------------------- {-# LANGUAGE RankNTypes #-} f :: ((forall a. a -> a) -> b) -> b f x = x id g :: (forall c. Eq c => [c] -> [c]) -> ([Bool],[Int]) g y = (y [True], y [1]) h :: ([Bool],[Int]) h = f g ------------------------------------------------------- GHC rejects it: Couldn't match expected type `forall a. a -> a' against inferred type `forall c. (Eq c) => [c] -> [c]' Expected type: forall a. a -> a Inferred type: forall c. (Eq c) => [c] -> [c] In the first argument of `f', namely `g' In the expression: f g But, intuitively, this code is type-safe, and actually I can convince the typechecker in it with the following workaround: ------------------------------------------------------- h :: ([Bool],[Int]) h = let g' = (\(x :: forall a. a -> a) -> g x) in f g' ------------------------------------------------------- So, is the current behavior of GHC correct ot it is a bug? How unification for rank-N types should proceed? Thanks, Vladimir From ptrash at web.de Tue Jun 9 06:28:59 2009 From: ptrash at web.de (ptrash) Date: Tue Jun 9 06:12:39 2009 Subject: [Haskell-cafe] Convert IO Int to Int Message-ID: <23940249.post@talk.nabble.com> Hi, I am using the System.Random method randomRIO. How can I convert its output to an Int? Thanks... -- View this message in context: http://www.nabble.com/Convert-IO-Int-to-Int-tp23940249p23940249.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From tobsan at gmail.com Tue Jun 9 06:33:09 2009 From: tobsan at gmail.com (Tobias Olausson) Date: Tue Jun 9 06:16:49 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <23940249.post@talk.nabble.com> References: <23940249.post@talk.nabble.com> Message-ID: <65c9dbea0906090333v42497017n132a886e77c3e276@mail.gmail.com> You can not convert an IO Int to Int, or at least, you shouldn't. However, you can do as follows: test :: IO () test = do int <- randomRIO -- or whatever it is called print $ useInt int useInt :: Int -> Int useInt x = x+10 //Tobias 2009/6/9 ptrash : > > Hi, > > I am using the System.Random method randomRIO. How can I convert its output > to an Int? > > Thanks... > -- > View this message in context: http://www.nabble.com/Convert-IO-Int-to-Int-tp23940249p23940249.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 > -- Tobias Olausson tobsan@gmail.com From jochem at functor.nl Tue Jun 9 06:33:52 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Tue Jun 9 06:17:31 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <23940249.post@talk.nabble.com> References: <23940249.post@talk.nabble.com> Message-ID: <4A2E3A90.5040208@functor.nl> ptrash wrote: > Hi, > > I am using the System.Random method randomRIO. How can I convert its output > to an Int? > > Thanks... You cannot [1], you should read up on monads and I/O in Haskell, for example http://haskell.org/haskellwiki/IO_inside [1] Yes, you can, but no, you don't want to. Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From nonowarn at gmail.com Tue Jun 9 07:20:51 2009 From: nonowarn at gmail.com (Yusaku Hashimoto) Date: Tue Jun 9 07:04:38 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <65c9dbea0906090333v42497017n132a886e77c3e276@mail.gmail.com> References: <23940249.post@talk.nabble.com> <65c9dbea0906090333v42497017n132a886e77c3e276@mail.gmail.com> Message-ID: <78513612-610F-4695-B7AA-F3D0413BE2DA@gmail.com> On 2009/06/09, at 19:33, Tobias Olausson wrote: > You can not convert an IO Int to Int, or at least, you shouldn't. > However, you can do as follows: > > test :: IO () > test = do > int <- randomRIO -- or whatever it is called > print $ useInt int > > useInt :: Int -> Int > useInt x = x+10 Or, you can lift pure function into IO. the below test' function almost same as above test function. (But I used randomIO instead of randomRIO because it seemed to be a typo :-) test' = print =<< fmap useInt randomIO I think it is more handy than using do notation, when you want to do something simple with monads. And converting IO Int to IO anything is much easier and safer than converting IO Int to Int. ghci> :m +System.Random Data.Char ghci> :t fmap (+1) randomIO fmap (+1) randomIO :: (Num a, Random a) => IO a ghci> :t fmap show randomIO fmap show randomIO :: IO String ghci> :t fmap chr randomIO fmap Data.Char.chr randomIO :: IO Char ghci> :t fmap (+) randomIO fmap (+) randomIO :: (Num a, Random a) => IO (a -> a) Thanks, Hashimoto > //Tobias > > 2009/6/9 ptrash : >> >> Hi, >> >> I am using the System.Random method randomRIO. How can I convert >> its output >> to an Int? >> >> Thanks... >> -- >> View this message in context: http://www.nabble.com/Convert-IO-Int- >> to-Int-tp23940249p23940249.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 >> > > > > -- > Tobias Olausson > tobsan@gmail.com > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From v.reshetnikov at gmail.com Tue Jun 9 07:51:59 2009 From: v.reshetnikov at gmail.com (Vladimir Reshetnikov) Date: Tue Jun 9 07:35:39 2009 Subject: [Haskell-cafe] Re: Unification for rank-N types In-Reply-To: <4770d2590906090254lce74a8endc05f2d69b33004d@mail.gmail.com> References: <4770d2590906090254lce74a8endc05f2d69b33004d@mail.gmail.com> Message-ID: <4770d2590906090451p54c1359evbebfe7814ca39ceb@mail.gmail.com> One more example: This does not type-check: ------------------------------------------------------- {-# LANGUAGE RankNTypes, ImpredicativeTypes #-} f :: [forall a. t a -> t a] -> t b -> t b f = foldr (.) id ------------------------------------------------------- Couldn't match expected type `forall a. f a -> f a' against inferred type `b -> c' In the first argument of `foldr', namely `(.)' But this, very similar, does type-check: ------------------------------------------------------- {-# LANGUAGE RankNTypes, ImpredicativeTypes #-} f :: [forall a. t a -> t a] -> t b -> t b f = foldr (\g -> (.) g) id ------------------------------------------------------- What is the reason for this? Thanks, Vladimir On 6/9/09, Vladimir Reshetnikov wrote: > Hi, > > I have the following code: > ------------------------------------------------------- > {-# LANGUAGE RankNTypes #-} > > f :: ((forall a. a -> a) -> b) -> b > f x = x id > > g :: (forall c. Eq c => [c] -> [c]) -> ([Bool],[Int]) > g y = (y [True], y [1]) > > h :: ([Bool],[Int]) > h = f g > ------------------------------------------------------- > > GHC rejects it: > Couldn't match expected type `forall a. a -> a' > against inferred type `forall c. (Eq c) => [c] -> [c]' > Expected type: forall a. a -> a > Inferred type: forall c. (Eq c) => [c] -> [c] > In the first argument of `f', namely `g' > In the expression: f g > > But, intuitively, this code is type-safe, and actually I can convince > the typechecker in it with the following workaround: > ------------------------------------------------------- > h :: ([Bool],[Int]) > h = let g' = (\(x :: forall a. a -> a) -> g x) in f g' > ------------------------------------------------------- > > So, is the current behavior of GHC correct ot it is a bug? > How unification for rank-N types should proceed? > > Thanks, > Vladimir > From nadine.and.henry at pobox.com Tue Jun 9 08:25:22 2009 From: nadine.and.henry at pobox.com (Henry Laxen) Date: Tue Jun 9 08:09:13 2009 Subject: [Haskell-cafe] Re: A generics question References: <8C41809E-BE80-4CFF-BF6A-1D8A4A156653@gmail.com> Message-ID: Sterling Clover gmail.com> writes: > > Try it with the following type signature and it should work fine: > > convert :: (Data a) => Int -> a -> a > > Of course, as has been noted, SYB is a rather big sledgehammer for > the insect in question. > > Cheers, > S. > Thank you Sterling. That is the answer I was looking for. I was trying out things from the various Scrap your Boilerplate papers, and got stuck doing something that I thought should be easy. Now it makes sense. Thanks again. Best wishes, Henry Laxen From ptrash at web.de Tue Jun 9 09:00:06 2009 From: ptrash at web.de (ptrash) Date: Tue Jun 9 08:43:47 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <23940249.post@talk.nabble.com> References: <23940249.post@talk.nabble.com> Message-ID: <23942344.post@talk.nabble.com> Ok, thanks for the information. -- View this message in context: http://www.nabble.com/Convert-IO-Int-to-Int-tp23940249p23942344.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From ptrash at web.de Tue Jun 9 09:05:57 2009 From: ptrash at web.de (ptrash) Date: Tue Jun 9 08:49:35 2009 Subject: [Haskell-cafe] Combine to List to a new List Message-ID: <23942440.post@talk.nabble.com> Hi, I have the following two lists: a = [1,2,3] b = ["A","B","C"] I want a combination of the to lists: c = [(1,"A"), (2, "B"), (3, "C")] How can I do this? I have tried c = [(x,y) | x <- a, y <- b] But this just returns me a list with every possible combination of the 2 lists. Thanks... -- View this message in context: http://www.nabble.com/Combine-to-List-to-a-new-List-tp23942440p23942440.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From wagner.andrew at gmail.com Tue Jun 9 09:08:24 2009 From: wagner.andrew at gmail.com (Andrew Wagner) Date: Tue Jun 9 08:52:03 2009 Subject: [Haskell-cafe] Combine to List to a new List In-Reply-To: <23942440.post@talk.nabble.com> References: <23942440.post@talk.nabble.com> Message-ID: Try c = zip a b On Tue, Jun 9, 2009 at 9:05 AM, ptrash wrote: > > Hi, > > I have the following two lists: > > a = [1,2,3] > b = ["A","B","C"] > > I want a combination of the to lists: > > c = [(1,"A"), (2, "B"), (3, "C")] > > How can I do this? > > I have tried > > c = [(x,y) | x <- a, y <- b] > > But this just returns me a list with every possible combination of the 2 > lists. > > Thanks... > > > -- > View this message in context: > http://www.nabble.com/Combine-to-List-to-a-new-List-tp23942440p23942440.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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090609/a4086bf3/attachment.html From dvekris at hotmail.com Tue Jun 9 09:08:48 2009 From: dvekris at hotmail.com (Dimitris Vekris) Date: Tue Jun 9 08:52:28 2009 Subject: [Haskell-cafe] Combine to List to a new List In-Reply-To: <23942440.post@talk.nabble.com> References: <23942440.post@talk.nabble.com> Message-ID: Probably you might need the "zip" function.Check here:http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:zip > Date: Tue, 9 Jun 2009 06:05:57 -0700 > From: ptrash@web.de > To: haskell-cafe@haskell.org > Subject: [Haskell-cafe] Combine to List to a new List > > > Hi, > > I have the following two lists: > > a = [1,2,3] > b = ["A","B","C"] > > I want a combination of the to lists: > > c = [(1,"A"), (2, "B"), (3, "C")] > > How can I do this? > > I have tried > > c = [(x,y) | x <- a, y <- b] > > But this just returns me a list with every possible combination of the 2 > lists. > > Thanks... > > > -- > View this message in context: http://www.nabble.com/Combine-to-List-to-a-new-List-tp23942440p23942440.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 _________________________________________________________________ Windows Live?: Keep your life in sync. Check it out! http://windowslive.com/explore?ocid=TXT_TAGLM_WL_t1_allup_explore_012009 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090609/a95d7c73/attachment.html From ptrash at web.de Tue Jun 9 09:16:48 2009 From: ptrash at web.de (ptrash) Date: Tue Jun 9 09:00:27 2009 Subject: [Haskell-cafe] Combine to List to a new List In-Reply-To: <23942440.post@talk.nabble.com> References: <23942440.post@talk.nabble.com> Message-ID: <23942633.post@talk.nabble.com> Hey, cool. Thanks! -- View this message in context: http://www.nabble.com/Combine-to-List-to-a-new-List-tp23942440p23942633.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From nowgate at yahoo.com Tue Jun 9 09:23:57 2009 From: nowgate at yahoo.com (michael rice) Date: Tue Jun 9 09:07:36 2009 Subject: [Haskell-cafe] Applying Data.Map Message-ID: <687224.10958.qm@web31103.mail.mud.yahoo.com> Hi Toby, Thanks for the helpful comments. I'd gotten used to arithmetic operator sections (+2), (*2), etc. but hadn't picked up on the generality of using them with *any* infix function. I can also see the benefit of using List.Group. However, I'm uncertain about how to import just fromList and ! from with the imports I'm using import Data.Map (Map)?? (fromList,!)? ??? import qualified Data.Map as Map? (fromList,!) ??? Michael --- On Mon, 6/8/09, Toby Hutton wrote: From: Toby Hutton Subject: Re: [Haskell-cafe] Applying Data.Map To: "michael rice" Cc: haskell-cafe@haskell.org Date: Monday, June 8, 2009, 8:57 PM Although in this example using Data.Map is overkill, if the alphabet was very large then Data.Map probably would be the way to go. In that case I'd use: map head . group . sort instead of nub . sort since it's noticeably quicker for large lists. ?This is because nub needs to preserve the order of input, removing redundancies, but you're sorting it anyway. Also, in?map (\c -> m Map.! c) s?you can use the 'section'?(m Map.!) instead. ?e.g., map (m Map.!) s The Map.! is ugly though. ?As you're only using fromList and (!) from Data.Map, I'd just import those explicitly since they don't clash with Prelude. ?Then you'd have map (m !) s Toby. On Tue, Jun 9, 2009 at 4:59 AM, michael rice wrote: I wrote a Haskell solution for the Prolog problem stated below. I had written a function SQUISH before discovering that NUB does the same thing. While the solution works, I thought maybe I could apply some functions in the Data.Map module, and so wrote a second version of SERIALIZE, one no longer needing TRANSLATE. Using the Data.Map module is probably overkill for this particular problem, but wanted to familiarize myself with Map type. Suggestions welcome. Prolog code also included below for those interested. Michael =========== {- ?From "Prolog By Example", Coelho, Cotta, Problem 42, pg. 63 ?? Verbal statement: ?? Generate a list of serial numbers for the items of a given list, ?? the members of which are to be numbered in alphabetical order. ?? For example, the list [p,r,o,l,o,g] must generate [4,5,3,2,3,1] -} {- Prelude> :l serialize [1 of 1] Compiling Main???????????? ( serialize.hs, interpreted ) Ok, modules loaded: Main. *Main> serialize "prolog" [4,5,3,2,3,1] *Main> -} ===========Haskell code========== import Data.Char import Data.List import Data.Map (Map) import qualified Data.Map as Map {- translate :: [Char] -> [(Char,Int)] -> [Int] translate [] _ = [] translate (x:xs) m = (fromJust (lookup x m)) : (translate xs m ) -} {- serialize :: [Char] -> [Int] serialize s = let c = nub $ sort s ????????????????? n = [1..(length c)] ????????????? in translate s (zip c n) -} serialize :: [Char] -> [Int] serialize s = let c = nub $ sort s ????????????????? n = [1..(length c)] ????????????????? m = Map.fromList $ zip c n ????????????? in map (\c -> m Map.! c) s ============Prolog code============ serialize(L,R) :- pairlists(L,R,A),arrange(A,T), ????????????????? numbered(T,1,N). ??????????????????????????????????????????????? ?? <- typo? pairlists([X|L],[Y|R],[pair(X,Y)|A]) :- pairlist(L,R,A). pairlists([],[],[]). arrange([X|L],tree(T1,X,T2)) :- partition(L,X,L1,L2), ??????????????????????????????? arrange(L1,T1), ??????????????????????????????? arrange(L2,T2). arrange([],_). partition([X|L],X,L1,L2) :- partition(L,X,L1,L2). partition([X|L],Y,[X|L1],L2) :- before(X,Y), ??????????????????????????????? partition(L,Y,L1,L2). partition([X|L],Y,L1,[X|L2]) :- before(Y,X), ??????????????????????????????? partition(L,Y,L1,L2). partition([],_,[],[]). before(pair(X1,Y1),pair(X2,Y2)) :- X1 References: <23942440.post@talk.nabble.com> Message-ID: <1244554770.6102.14.camel@moonlite> On Tue, 2009-06-09 at 06:05 -0700, ptrash wrote: > Hi, > > I have the following two lists: > > a = [1,2,3] > b = ["A","B","C"] > > I want a combination of the to lists: > > c = [(1,"A"), (2, "B"), (3, "C")] > > How can I do this? What you want is a function with the following type signature: [t1] -> [t2] -> [(t1,t2)] Search for that in hoogle[1] and you get the function "zip" as a result[2] (as already told in this thread). Hoogle is your friend (and helps you help yourself)! :) 1: http://haskell.org/hoogle/ 2: http://haskell.org/hoogle/?hoogle=%5Ba%5D+-%3E+%5Bb%5D+-%3E+%5B%28a% 2Cb%29%5D From ttencate at gmail.com Tue Jun 9 09:40:54 2009 From: ttencate at gmail.com (Thomas ten Cate) Date: Tue Jun 9 09:24:35 2009 Subject: [Haskell-cafe] Applying Data.Map In-Reply-To: <687224.10958.qm@web31103.mail.mud.yahoo.com> References: <687224.10958.qm@web31103.mail.mud.yahoo.com> Message-ID: On Tue, Jun 9, 2009 at 15:23, michael rice wrote: > import Data.Map (Map)?? (fromList,!)? ??? > import qualified Data.Map as Map? (fromList,!) ??? Because ! is an operator, you need to enclose it in parentheses. Also, the (Map) in the import is already the list of things you are importing; you can just add to that. So do the following: Import these without qualification: > import Data.Map (Map, fromList, (!)) Import everything else (actually including Map, fromList and (!)) with qualification "Map": > import qualified Data.Map as Map Cheers, Thomas From ptrash at web.de Tue Jun 9 09:52:29 2009 From: ptrash at web.de (ptrash) Date: Tue Jun 9 09:36:08 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <23940249.post@talk.nabble.com> References: <23940249.post@talk.nabble.com> Message-ID: <23943301.post@talk.nabble.com> Hmm...it am not getting through it. I just want to generate a random number and then compare it with other numbers. Something like r = randomRIO (1, 10) if (r > 5) then... else ... -- View this message in context: http://www.nabble.com/Convert-IO-Int-to-Int-tp23940249p23943301.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From magnus at therning.org Tue Jun 9 09:57:24 2009 From: magnus at therning.org (Magnus Therning) Date: Tue Jun 9 09:41:06 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <23943301.post@talk.nabble.com> References: <23940249.post@talk.nabble.com> <23943301.post@talk.nabble.com> Message-ID: On Tue, Jun 9, 2009 at 2:52 PM, ptrash wrote: > > Hmm...it am not getting through it. I just want to generate a random number > and then compare it with other numbers. Something like > > r = randomRIO (1, 10) > if (r > 5) then... else ... You have to do it inside the IO monad, something like myFunc = do r <- randomRIO (1, 10 if r > 5 then ... else ... /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe From lemming at henning-thielemann.de Tue Jun 9 10:06:01 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Tue Jun 9 09:49:41 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <23940249.post@talk.nabble.com> References: <23940249.post@talk.nabble.com> Message-ID: On Tue, 9 Jun 2009, ptrash wrote: > I am using the System.Random method randomRIO. How can I convert its output > to an Int? in general: http://haskell.org/haskellwiki/How_to_get_rid_of_IO about randomIO: http://haskell.org/haskellwiki/Avoiding_IO#State_monad From lazycat.manatee at gmail.com Tue Jun 9 09:59:58 2009 From: lazycat.manatee at gmail.com (Andy Stewart) Date: Tue Jun 9 09:53:42 2009 Subject: [Haskell-cafe] How to improve below code? Message-ID: <87bpoxa4o1.fsf@ubuntu.domain> Hi all, I have below source code, i use Dynamic for `pageBuffer`. In implement of function `pageClone`, after `case pt of`, i need write like this, and this code looks ugly, if `PageTyep` have 100 type, i need write those ugly code 100 times. case pt of TStringBuffer -> pageBufferClone (x :: StringBuffer) TImageBuffer -> pageBufferClone (x :: ImageBuffer) TVideoBuffer -> pageBufferClone (x :: TVideoBuffer) TMixBuffer -> pageBufferClone (x :: TMixBuffer) So have a better solution to avoid write above ugly code? Someone suggestion me use GADTs instead, but i don't know how to write correct GADTs code replace current version, if GADTs is best way, someone can explain it detail? It's better if someone give me demo code. ------------------------------> Source Code start <------------------------------ data PageType = TStringBuffer | TImageBuffer | TVideoBuffer | TMixBuffer deriving (Eq, Show, Read) data Page = Page {pageName :: IORef String ,pageId :: Int ,pageType :: PageType ,pageBuffer :: Dynamic ,pageBox :: VBox } class PageBuffer a where pageBufferClone :: a -> IO (Dynamic, VBox) -- | Page clone interface. pageClone :: Page -> IO Page pageClone page = do -- Get common information for clone page. name <- pageGetName page let id = pageId page pt = pageType page pb = pageBuffer page -- Get clone information for dynamic interface. (pBuffer, pBox) <- case fromDynamic pb of Just x -> case pt of TStringBuffer -> pageBufferClone (x :: StringBuffer) TImageBuffer -> pageBufferClone (x :: ImageBuffer) TVideoBuffer -> pageBufferClone (x :: TVideoBuffer) TMixBuffer -> pageBufferClone (x :: TMixBuffer) Nothing -> pageCloneEmpty -- Return clone page. pageNewInternal name id pt pBuffer pBox ------------------------------> Source Code end <------------------------------ Thanks! -- Andy From daniel.is.fischer at web.de Tue Jun 9 10:14:44 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Tue Jun 9 09:59:11 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: References: <23940249.post@talk.nabble.com> <23943301.post@talk.nabble.com> Message-ID: <200906091614.45131.daniel.is.fischer@web.de> Am Dienstag 09 Juni 2009 15:57:24 schrieb Magnus Therning: > On Tue, Jun 9, 2009 at 2:52 PM, ptrash wrote: > > Hmm...it am not getting through it. I just want to generate a random > > number and then compare it with other numbers. Something like > > > > r = randomRIO (1, 10) > > if (r > 5) then... else ... > > You have to do it inside the IO monad, something like > > myFunc = do > r <- randomRIO (1, 10 > if r > 5 > then ... > else ... > > /M Or make the source of the pseudo-random numbers explicit: import System.Random function :: (RandomGen g, Random a) => g -> other args -> result function gen whatever | r > 5 = blah newgen something | r < 3 = blub newgen somethingElse | otherwise = bling where (r,newgen) = randomR (lo,hi) gen and finally, when the programme is run: main = do args <- getArgs sg <- getStdGen foo <- thisNThat print $ function sg foo If you're doing much with random generators, wrap it in a State monad. From lemming at henning-thielemann.de Tue Jun 9 10:16:58 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Tue Jun 9 10:01:28 2009 Subject: [Haskell-cafe] Incremental XML parsing with namespaces? In-Reply-To: <3283f7fe0906082000y48cf4f9flfb23a10458ee669d@mail.gmail.com> References: <3283f7fe0906081139t1b9475d1sa9dba2c2a17ff4fe@mail.gmail.com> <4BB426D6-B5C5-4625-B541-098F3628B135@cs.york.ac.uk> <3283f7fe0906081504q608cc96ftfb1eba7bf176acb@mail.gmail.com> <4A2D9304.2040209@henning-thielemann.de> <3283f7fe0906082000y48cf4f9flfb23a10458ee669d@mail.gmail.com> Message-ID: <4A2E6EDA.2090308@henning-thielemann.de> John Millikin wrote: > On Mon, Jun 8, 2009 at 3:39 PM, Henning > Thielemann wrote: >> I think you could use the parser as it is and do the name parsing later. >> Due to lazy evaluation both parsers would run in an interleaved way. >> > I've been trying to figure out how to get this to work with lazy > evaluation, but haven't made much headway. Tips? The only way I can > think of to get incremental parsing working is to maintain explicit > state, but I also can't figure out how to achieve this with the > parsers I've tested (HaXml, HXT, hexpat). Can you please look at http://code.haskell.org/~thielema/tagchup/example/Escape.hs http://code.haskell.org/~thielema/tagchup/example/Strip.hs You just have to replace Text.XML.Basic.Name.LowerCase by Text.XML.Basic.Name.Qualified for use of qualified names. -- Mit freundlichen Gruessen Henning Thielemann Viele Gruesse Henning Martin-Luther-Universitaet Halle-Wittenberg, Institut fuer Informatik Tel. +49 - 345 - 55 24773 Fax +49 - 345 - 55 27333 From nowgate at yahoo.com Tue Jun 9 10:18:13 2009 From: nowgate at yahoo.com (michael rice) Date: Tue Jun 9 10:01:53 2009 Subject: [Haskell-cafe] Applying Data.Map Message-ID: <807738.96206.qm@web31105.mail.mud.yahoo.com> In the import statements, it wasn't clear to me that I could import types as well as functions, and Map is a type. All clear now. Thanks. Michael --- On Tue, 6/9/09, Thomas ten Cate wrote: From: Thomas ten Cate Subject: Re: [Haskell-cafe] Applying Data.Map To: "michael rice" Cc: haskell-cafe@haskell.org Date: Tuesday, June 9, 2009, 9:40 AM On Tue, Jun 9, 2009 at 15:23, michael rice wrote: > import Data.Map (Map)?? (fromList,!)? ??? > import qualified Data.Map as Map? (fromList,!) ??? Because ! is an operator, you need to enclose it in parentheses. Also, the (Map) in the import is already the list of things you are importing; you can just add to that. So do the following: Import these without qualification: > import Data.Map (Map, fromList, (!)) Import everything else (actually including Map, fromList and (!)) with qualification "Map": > import qualified Data.Map as Map Cheers, Thomas -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090609/5ae316cc/attachment.html From nccb2 at kent.ac.uk Tue Jun 9 10:21:05 2009 From: nccb2 at kent.ac.uk (Neil Brown) Date: Tue Jun 9 10:04:44 2009 Subject: [Haskell-cafe] How to improve below code? In-Reply-To: <87bpoxa4o1.fsf@ubuntu.domain> References: <87bpoxa4o1.fsf@ubuntu.domain> Message-ID: <4A2E6FD1.6010607@kent.ac.uk> Andy Stewart wrote: > So have a better solution to avoid write above ugly code How about: ==== data Page a = Page {pageName :: IORef String ,pageId :: Int ,pageBuffer :: a ,pageBox :: VBox } class PageBuffer a where pageBufferClone :: a -> IO (a, VBox) pageClone :: PageBuffer a => Page a -> IO (Page a) pageClone page = do -- Get common information for clone page. name <- pageGetName page let id = pageId page pb = pageBuffer page -- Get clone information for dynamic interface. (pBuffer, pBox) <- pageBufferClone pb -- Return clone page. pageNewInternal name id pBuffer pBox ==== I'm not totally sure if that will work without seeing the rest of your code. But it seems neater, and no GADTs in sight. If you need to store Page StringBuffer in a list with Page ImageBuffer you will have a problem, so perhaps you could spell out what else you need to do with these Page items in your application? Thanks, Neil. From gtener at gmail.com Tue Jun 9 12:04:49 2009 From: gtener at gmail.com (=?UTF-8?Q?Krzysztof_Skrz=C4=99tnicki?=) Date: Tue Jun 9 11:48:30 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <200906091614.45131.daniel.is.fischer@web.de> References: <23940249.post@talk.nabble.com> <23943301.post@talk.nabble.com> <200906091614.45131.daniel.is.fischer@web.de> Message-ID: <220e47b40906090904q2d725977ge942835428c6e4b8@mail.gmail.com> On Tue, Jun 9, 2009 at 16:14, Daniel Fischer wrote: > Am Dienstag 09 Juni 2009 15:57:24 schrieb Magnus Therning: >> On Tue, Jun 9, 2009 at 2:52 PM, ptrash wrote: >> > Hmm...it am not getting through it. I just want to generate a random >> > number and then compare it with other numbers. Something like >> > >> > r = randomRIO (1, 10) >> > if (r > 5) then... else ... >> >> You have to do it inside the IO monad, something like >> >> ? ? myFunc ?= do >> ? ? ? ? r <- randomRIO (1, 10 >> ? ? ? ? if r > 5 >> ? ? ? ? ? ? then ... >> ? ? ? ? ? ? else ... >> >> /M > > Or make the source of the pseudo-random numbers explicit: > > import System.Random > > function :: (RandomGen g, Random a) => g -> other args -> result > function gen whatever > ? ?| r > 5 ? ? = blah newgen something > ? ?| r < 3 ? ? = blub newgen somethingElse > ? ?| otherwise = bling > ? ? ?where > ? ? ? ?(r,newgen) = randomR (lo,hi) gen > > and finally, when the programme is run: > > main = do > ? ?args <- getArgs > ? ?sg <- getStdGen > ? ?foo <- thisNThat > ? ?print $ function sg foo > > If you're doing much with random generators, wrap it in a State monad. To avoid reinventing the wheel one can use excellent package available on Hackage: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/MonadRandom > The die function simulates the roll of a die, picking a number between 1 and 6, inclusive, and returning it in the Rand monad. > Notice that this code will work with any source of random numbers g. > > die :: (RandomGen g) => Rand g Int > die = getRandomR (1,6) > > The dice function uses replicate and sequence to simulate the roll of n dice. > > dice :: (RandomGen g) => Int -> Rand g [Int] > dice n = sequence (replicate n die) > > To extract a value from the Rand monad, we can can use evalRandIO. > > main = do > values <- evalRandIO (dice 2) > putStrLn (show values) Best regards Krzysztof Skrz?tnicki From jerzy.karczmarczuk at info.unicaen.fr Tue Jun 9 12:23:04 2009 From: jerzy.karczmarczuk at info.unicaen.fr (jerzy.karczmarczuk@info.unicaen.fr) Date: Tue Jun 9 12:06:44 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: References: <23940249.post@talk.nabble.com> <23943301.post@talk.nabble.com> Message-ID: Magnus Therning writes: > ptrash wrote: >> ...am not getting through it. I just want to generate a random number >> and then compare it with other numbers. Something like >> >> r = randomRIO (1, 10) >> if (r > 5) then... else ... > > You have to do it inside the IO monad, something like > > myFunc = do > r <- randomRIO (1, 10 This may continue forever... With nice references to monads, to Unsafe@#*!, etc. ... We may say, as many tutorials do : "this is not what you want!" (which I hate ; you are not my conscience, whoever you are...), or just give some code, not always readable... Perhaps I belong to a minority here, but I strongly believe that at THIS level, the first thing to do - unless I am dead wrong - is to explain to our friend ptrash (who could find a less gothic pseudo) that in a pure functional programming, the construction r = whatEver(par1,par2) being a function call, cannot give "just a random number", something which is not (intuitively) determined, and changes with every call, despite the constancy of the arguments. For most of us, acquainted with the stuff, it becomes trivial, but if somebody doesn't know that a classical pseudo-random generator modifies a "seed", and in such a way involves a "side effect", then sending him to the monadic heaven is dangerous. Please, tell him first about random streams, which he can handle without IO. Or, about ergodic functions (hashing contraptions which transform ANY parameter into something unrecognizable). When he says : "I know all that", THEN hurt him badly with monads. Jerzy Karczmarczuk From bulat.ziganshin at gmail.com Tue Jun 9 13:36:12 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Tue Jun 9 13:20:57 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: References: <23940249.post@talk.nabble.com> <23943301.post@talk.nabble.com> Message-ID: <14115408.20090609213612@gmail.com> Hello jerzy, Tuesday, June 9, 2009, 8:23:04 PM, you wrote: > Please, tell him first about random streams, which he can handle without > IO. Or, about ergodic functions (hashing contraptions which transform ANY > parameter into something unrecognizable). When he says : "I know all that", > THEN hurt him badly with monads. i think that for someone coming from imperative programming teeling about IO monad is the easiest way. and then he will learn how to do it FP way -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From tphyahoo at gmail.com Tue Jun 9 14:29:09 2009 From: tphyahoo at gmail.com (Thomas Hartman) Date: Tue Jun 9 14:12:56 2009 Subject: [Haskell-cafe] please comment on my parser, can I do this cleaner? Message-ID: <910ddf450906091129p2c2d14f2sfb654eb09d7b0773@mail.gmail.com> All I want to do is split on commas, but not the commas inside () or <> tags. I have been wanting to master parsec for a long time and this simple exercise looked like a good place to start. The code below does the right thing. Am I missing any tricks to make this simpler/neater? Thanks, thomas. thartman@ubuntu:~/perlArena>cat splitEm. splitEm.hs splitEm.hs~ splitEm.pl splitEm.pl~ thartman@ubuntu:~/perlArena>cat splitEm.hs {-# LANGUAGE ScopedTypeVariables #-} import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec.Char import Text.PrettyPrint (vcat, render, text) import Data.List.Split hiding (sepBy, chunk) import Text.ParserCombinators.Parsec.Token import Debug.Trace import Debug.Trace.Helpers -- this works, but is there a neater/cleaner way? main = ripInputsXs (toEof splitter) "splitter" [ goodS, badS ] -- I need a way to split on commas, but not the commas inside '<>' or '()' characters goodS = "<*2>FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,7,6,5,0>" badS = "<*2)FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,7,6,5,0>" -- the first < matches a ), so reject this splitter = do chunks :: [String] <- toEof (many chunk) let pieces = map concat $ splitOn [","] chunks return pieces -- chunks where atom = string "," <|> ( many1 $ noneOf "()<>" ) chunk = parenExpr <|> atom parenExpr :: GenParser Char st [Char] parenExpr = let paren p = betweenInc (char '(' ) (char ')' ) p <|> betweenInc (char '<' ) (char '>' ) p in paren $ option "" $ do ps <- many1 $ parenExpr <|> atom return . concat $ ps betweenInc o' c' p' = do o <- o' p <- p' c <- c' return $ [o] ++ p ++ [c] toEof p' = do r <- p' eof return r ripInputs prs prsName xs = mapM_ (putStrLn . show . parse prs prsName ) xs ripInputsXs prs prsName xs = mapM_ (putStrLn . showXs . parse prs prsName ) xs where showXs v = case v of Left e -> show e Right xs -> render . vcat . map text $ xs From cgibbard at gmail.com Tue Jun 9 15:03:18 2009 From: cgibbard at gmail.com (Cale Gibbard) Date: Tue Jun 9 14:46:59 2009 Subject: [Haskell-cafe] nubBy seems broken in recent GHCs In-Reply-To: <4a2a9bd9.12115e0a.77d5.5b0d@mx.google.com> References: <89ca3d1f0906052221k62c12d44ha92bcab4ede4d2f2@mail.gmail.com> <4a2a9bd9.12115e0a.77d5.5b0d@mx.google.com> Message-ID: <89ca3d1f0906091203p164735f4s1d37fb5dc127b0a9@mail.gmail.com> 2009/6/6 Bertram Felgenhauer : > Interesting. This was changed in response to > > ? ?http://hackage.haskell.org/trac/ghc/ticket/2528 > > | Tue Sep ?2 11:29:50 CEST 2008 ?Simon Marlow > | ? * #2528: reverse the order of args to (==) in nubBy to match nub > | ? This only makes a difference when the (==) definition is not > | ? reflexive, but strictly speaking it does violate the report definition > | ? of nubBy, so we should fix it. > > It turns out that 'elem' differs from the report version and should > have its comparison reversed. Of course that would only ever matter > for broken Eq instances. > > However, the report also states that the nubBy function may assume that > the given predicate defines an equivalence relation. > > ? ?http://haskell.org/onlinereport/list.html#sect17.6 > > So I'm not sure there's anything to be fixed here - although backing > out the above patch probably won't hurt anybody. > > Bertram Yeah, while most Eq instances really do define an equivalence relation (at least extensionally), and the Report authors probably thought in terms of an equivalence relation (even going so far as to say that nubBy can assume its parameter is one, which I think was a mistake), I think nubBy has a much more general use. It does a generalised kind of sieving, specifically, nubBy f xs is the unique subsequence of xs that: 1) Has the property that if x and y are elements such that x occurs before y in it, then f x y is False. 2) The sequence of indices of selected elements is lexicographically minimum for all subsequences satisfying condition 1. (That is, it always picks the earliest elements possible.) I think this is how it ought to be specified. Similarly, groupBy f xs is (and should be) the unique list of contiguous sublists of xs such that: 1) concat (groupBy f xs) = xs 2) If x is the head of any of the sublists and y is any other element of that sublist, then f x y 3) The sequence of lengths of the sublists is lexicographically maximum for all lists satisfying the first two properties (That is, it always prefers adding elements to an earlier group to starting a new group.) - Cale From jadrian at mat.uc.pt Tue Jun 9 15:15:33 2009 From: jadrian at mat.uc.pt (Jorge Branco Branco Aires) Date: Tue Jun 9 14:59:16 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <14115408.20090609213612@gmail.com> References: <23940249.post@talk.nabble.com> <23943301.post@talk.nabble.com> <14115408.20090609213612@gmail.com> Message-ID: <4A2EB4D5.5020309@mat.uc.pt> Bulat Ziganshin wrote: > Hello jerzy, > > Tuesday, June 9, 2009, 8:23:04 PM, you wrote: > > >> Please, tell him first about random streams, which he can handle without >> IO. Or, about ergodic functions (hashing contraptions which transform ANY >> parameter into something unrecognizable). When he says : "I know all that", >> THEN hurt him badly with monads. >> > > i think that for someone coming from imperative programming teeling > about IO monad is the easiest way. and then he will learn how to do it > FP way > I came from a imperative programming background. I didn't feel like this help me at all back then. At least in the beginning you want to detach yourself from an imperative style, not try to simulate it with some weird structure that you don't really understand. More generally I really wish IO hadn't been the first Monad I played with. It's so close to a Functor, yet in my mind Functors were simple, just structures that could be mapped, and Monads were these mysterious things that allowed you to get away with side effects and that once you were inside you could never get out. Jorge From daniel.is.fischer at web.de Tue Jun 9 15:43:26 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Tue Jun 9 15:27:50 2009 Subject: [Haskell-cafe] please comment on my parser, can I do this cleaner? In-Reply-To: <910ddf450906091129p2c2d14f2sfb654eb09d7b0773@mail.gmail.com> References: <910ddf450906091129p2c2d14f2sfb654eb09d7b0773@mail.gmail.com> Message-ID: <200906092143.26241.daniel.is.fischer@web.de> Am Dienstag 09 Juni 2009 20:29:09 schrieb Thomas Hartman: > All I want to do is split on commas, but not the commas inside () or <> > tags. > > I have been wanting to master parsec for a long time and this simple > exercise looked like a good place to start. > > The code below does the right thing. Am I missing any tricks to make > this simpler/neater? > > Thanks, thomas. > > thartman@ubuntu:~/perlArena>cat splitEm. > splitEm.hs splitEm.hs~ splitEm.pl splitEm.pl~ > thartman@ubuntu:~/perlArena>cat splitEm.hs > {-# LANGUAGE ScopedTypeVariables #-} > import Text.ParserCombinators.Parsec > import Text.ParserCombinators.Parsec.Char > import Text.PrettyPrint (vcat, render, text) > import Data.List.Split hiding (sepBy, chunk) > import Text.ParserCombinators.Parsec.Token > > import Debug.Trace > import Debug.Trace.Helpers > > -- this works, but is there a neater/cleaner way? > main = ripInputsXs (toEof splitter) "splitter" [ goodS, badS ] > > -- I need a way to split on commas, but not the commas inside '<>' or > '()' characters > goodS = "<*2>FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,7,6,5,0>" > badS = "<*2)FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,7,6,5,0>" > -- the first < matches a ), so reject this > > > splitter = do > chunks :: [String] <- toEof (many chunk) > let pieces = map concat $ splitOn [","] chunks > return pieces -- chunks > where > atom = string "," > <|> ( many1 $ noneOf "()<>" ) > chunk = parenExpr <|> atom I think that does not do what you want. For input "FOO,BAR,BAZ", chunks is ["FOO,BAR,BAZ"], that won't be split; as far as I can see, it splits only on commas directly following a parenExpr (or at the beginning of the input or directly following another splitting comma). > parenExpr :: GenParser Char st [Char] > parenExpr = let paren p = betweenInc (char '(' ) (char ')' ) p > <|> betweenInc (char '<' ) (char '>' ) > p > in paren $ option "" $ do ps <- many1 $ parenExpr <|> atom > return . concat $ ps > > betweenInc o' c' p' = do > o <- o' > p <- p' > c <- c' > return $ [o] ++ p ++ [c] > > toEof p' = do > r <- p' > eof > return r > > > > > > > ripInputs prs prsName xs = mapM_ (putStrLn . show . parse prs prsName ) xs > ripInputsXs prs prsName xs = mapM_ (putStrLn . showXs . parse prs prsName ) > xs where showXs v = case v of > Left e -> show e > Right xs -> render . vcat . map text $ xs I can offer (sorry for the names, and I don't know if what that does is really what you want): keepSepBy :: Parser a -> Parser a -> Parser [a] keepSepBy p sep = (do r <- p (do s <- sep xs <- keepSepBy p sep return (r:s:xs)) <|> return [r]) <|> return [] twain :: Parser a -> Parser a -> Parser [a] -> Parser [a] twain open close list = do o <- open l <- list c <- close return (o:l++[c]) comma :: Parser String comma = string "," simpleChar :: Parser Char simpleChar = noneOf "<>()," suite :: Parser String suite = many1 simpleChar atom :: Parser String atom = fmap concat $ many1 (parenExp <|> suite) parenGroup :: Parser String parenGroup = fmap concat $ keepSepBy atom comma parenExp :: Parser String parenExp = twain (char '<') (char '>') parenGroup <|> twain (char '(') (char ')') parenGroup chunks :: Parser [String] chunks = sepBy atom comma splitter = do cs <- chunks eof return cs goodS = "<*2>FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,7,6,5,0>" badS = "<*2)FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,7,6,5,0>" goodRes = parse splitter "splitter" goodS badRes = parse splitter "splitter" badS From lrpalmer at gmail.com Tue Jun 9 15:46:33 2009 From: lrpalmer at gmail.com (Luke Palmer) Date: Tue Jun 9 15:30:13 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <220e47b40906090904q2d725977ge942835428c6e4b8@mail.gmail.com> References: <23940249.post@talk.nabble.com> <23943301.post@talk.nabble.com> <200906091614.45131.daniel.is.fischer@web.de> <220e47b40906090904q2d725977ge942835428c6e4b8@mail.gmail.com> Message-ID: <7ca3f0160906091246m714b6a8bg6469c3991513189c@mail.gmail.com> 2009/6/9 Krzysztof Skrz?tnicki > On Tue, Jun 9, 2009 at 16:14, Daniel Fischer > wrote: > > If you're doing much with random generators, wrap it in a State monad. > > To avoid reinventing the wheel one can use excellent package available > on Hackage: > http://hackage.haskell.org/cgi-bin/hackage-scripts/package/MonadRandom Please do! Prefer MonadRandom to explicit generator passing: http://lukepalmer.wordpress.com/2009/01/17/use-monadrandom/. Keep computations in MonadRandom, and pull them out with evalRandomIO at the last second. Luke > > > > The die function simulates the roll of a die, picking a number between 1 > and 6, inclusive, and returning it in the Rand monad. > > Notice that this code will work with any source of random numbers g. > > > > die :: (RandomGen g) => Rand g Int > > die = getRandomR (1,6) > > > > The dice function uses replicate and sequence to simulate the roll of n > dice. > > > > dice :: (RandomGen g) => Int -> Rand g [Int] > > dice n = sequence (replicate n die) > > > > To extract a value from the Rand monad, we can can use evalRandIO. > > > > main = do > > values <- evalRandIO (dice 2) > > putStrLn (show values) > > Best regards > > Krzysztof Skrz?tnicki > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090609/9fd21e1b/attachment.html From ryani.spam at gmail.com Tue Jun 9 16:23:17 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Tue Jun 9 16:07:12 2009 Subject: [Haskell-cafe] How to improve below code? In-Reply-To: <4A2E6FD1.6010607@kent.ac.uk> References: <87bpoxa4o1.fsf@ubuntu.domain> <4A2E6FD1.6010607@kent.ac.uk> Message-ID: <2f9b2d30906091323n51df0888od52e81f19488146c@mail.gmail.com> On Tue, Jun 9, 2009 at 7:21 AM, Neil Brown wrote: > data Page a = > ? Page {pageName ? ? ?:: IORef String > ? ? ? ?,pageId ? ? ? ?:: Int > ? ? ? ?,pageBuffer ? ?:: a > ? ? ? ?,pageBox ? ? ? :: VBox > ? ? ? ?} > > class PageBuffer a where > ?pageBufferClone :: a -> IO (a, VBox) > > pageClone :: PageBuffer a => Page a -> IO (Page a) > pageClone page = do > ?-- Get common information for clone page. > ?name <- pageGetName page > ?let id = pageId page > ? ? pb = pageBuffer page > > ?-- Get clone information for dynamic interface. ?(pBuffer, pBox) <- > pageBufferClone pb > > ?-- Return clone page. > ?pageNewInternal name id pBuffer pBox Actually you can avoid the type parameter on "a" using an existential: > {-# LANGUAGE ExistentialQuantification #-} > data Page = forall a. PageBuffer a => > Page {pageName :: IORef String > ,pageId :: Int > ,pageBuffer :: a > ,pageBox :: VBox > } Now you can still use [Page]. You can't do "pageBuffer p", though, you'll get this fun error message: Cannot use record selector `pageBuffer' as a function due to escaped type variables Probable fix: use pattern-matching syntax instead Instead you need to do case p of Page{pageBuffer = x} -> ...something with x... This will bring the PageBuffer context into scope, inside of the case statement. -- ryan From niklas.broberg at gmail.com Tue Jun 9 17:49:36 2009 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Tue Jun 9 17:33:17 2009 Subject: [Haskell-cafe] FlexibleContexts and FlexibleInstances Message-ID: Dear all, This post is partly a gripe about how poor the formal documentation for various GHC extensions is, partly a gripe about how GHC blurs the lines between syntactic and type-level issues as well as between various extensions, and partly a gripe about how the Haskell 98 report is sometimes similarly blurred where syntax is concerned (or not). All these things make the life of a poor parser implementor quite miserable at times. All in good jest of course, but with an edge of truth, especially regarding (lack of) formal documentation. The issue at hand which has caused my frustration is the FlexibleContexts [1] and FlexibleInstances [2] extensions, which lift restrictions imposed by Haskell 98 on the forms of contexts and instances that may be defined. Great extensions both of them - but what do they do, really really? The following toy program requires MultiParamTypeClasses OR FlexibleContexts in order to be accepted by GHC(i): > f :: (T a b) => a -> Int > f _ = 0 This of course assumes that we import the definition of T, we *must* have MultiParamTypeClasses enabled if we want to declare T. Both extensions thus enable classes with more than one argument to appear in contexts. Changing the program to > f :: (T a ()) => a -> Int > f _ = 0 i.e. changing the second argument to T to () instead, means we now *must* have FlexibleInstances, in order to allow the non-tyvar argument. This is nothing surprising, this is what FlexibleInstances are supposed to do. But the question is, is this a syntactic issue or a typing issue? In GHC proper this doesn't really matter much, as long as it is caught *somewhere* then all is dandy. GHC's parser lets everything pass, and it's the type checker that balks at this program. But for someone like me with *only* a parser, this is a question that needs a clear answer. Looking at the online report, the productions regarding contexts are context -> class | ( class1 , ... , classn ) (n>=0) class -> qtycls tyvar | qtycls ( tyvar atype1 ... atypen ) (n>=1) qtycls -> [ modid . ] tycls tycls -> conid tyvar -> varid Ok, so clearly the () is a syntactic extension enabled by FlexibleContexts, as it is not a tyvar nor a tyvar applied to a sequence of types. So this is something that a parser should handle. FlexibleContexts also enables similar parses of contexts in other places, for instance in class declarations, for which the Haskell 98 report says topdecl -> class [scontext =>] tycls tyvar [where cdecls] scontext -> simpleclass | ( simpleclass1 , ... , simpleclassn ) (n>=0) simpleclass -> qtycls tyvar The difference here is that the simpleclass doesn't allow the tyvar applied to a sequence of types bit. FlexibleContexts lifts that restriction too, so there should be no difference between the two kinds of contexts. So the new formal productions for flexible contexts should be something like fcontext -> fclass | ( fclass1 , ... , fclassn ) (n>=0) fclass -> qtycls type1 ... typen (n>=1) topdecl -> data [fcontext =>] simpletype = constrs [deriving] | newtype [fcontext =>] simpletype = newconstr [deriving] | class [fcontext =>] tycls tyvar [where cdecls] | instance [fcontext =>] qtycls inst [where idecls] gendecl -> vars :: [fcontext =>] type Does this seem correct? Now let's turn to FlexibleInstances, which similarly lifts restrictions, only to instance declarations instead of contexts. The Haskell 98 report says on instance declarations: topdecl -> instance [scontext =>] qtycls inst [where idecls] inst -> gtycon | ( gtycon tyvar1 ... tyvark ) (k>=0, tyvars distinct) | ( tyvar1 , ... , tyvark ) (k>=2, tyvars distinct) | [ tyvar ] | ( tyvar1 -> tyvar2 ) (tyvar1 and tyvar2 distinct) Note the re-appearance of scontext, which is the same as above. The instance head must be a type constructor, possibly applied to a number of type variables, or one of three built-in syntactic cases. This is where I consider the Haskell 98 report blurry - the fact that the tyvars must be distinct, is that truly a syntactic issue? It might be, it's certainly something that could be checked syntactically. But when you take into account that with the proper extensions, they no longer need to be distinct, at what level would we expect such a check to happen? My gut feeling is that this check for distinctness is something that a type checker might do better than a parser, though it's not clear cut by any means. But since I don't do any other kind of name resolution or checking in my parser even if it would be possible (e.g. multiple declarations of the same symbol), I would find it a bit anomalous to check this too. Turning on FlexibleInstances, we shouldn't need to follow any of the above restrictions on inst. In other words, the flexible production should simply be something like finst -> type Right? Now, FlexibleInstances *also* lifts the restriction on contexts, just like FlexibleContexts - but *only* for the contexts of instance declarations. This may seem like a reasonable thing, but it certainly gives me some headaches. It means I could not treat the contexts uniformly, but would need to have separate syntactic categories (or rather post-parse checks) that look different between instance contexts and other contexts (including class). So with FlexibleInstances on, there are *three* different kinds of contexts allowed: scontext for class declaration, fcontext for instance declarations, and context for all other uses of contexts (type signatures, data/newtype declarations). Just a small headache, since I already apparently needed two categories from Haskell 98, but still. I'm not sure I find it reasonable, that flexible instances are enabled just for instance declarations but not elsewhere, but I'm sure a lot of thought was given to that. If it was up to *me* though, I would leave the flexible contexts with FlexibleContexts entirely, which means you would have to use both flags if you wanted both in your instance declarations. Would that be a bad thing? Separation of concern seems desirable to me (and no, I'm not saying that just because it would be easier to implement in the parser)... At any rate, to make a long rant short: * Are my interpretations of the lifted restrictions by FlexibleContexts and FlexibleInstances correct? * Is it reasonable that the issue of checking that tyvars are distinct should not be considered syntactic? * Would it also be reasonable to make the separation of concern between FlexibleContexts and FlexibleInstances more clean? Thanks for reading, and please give me input! Cheers, /Niklas [1] http://www.haskell.org/ghc/docs/latest/html/users_guide/other-type-extensions.html#flexible-contexts [2] http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class-extensions.html#instance-rules From iavor.diatchki at gmail.com Tue Jun 9 18:12:04 2009 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Tue Jun 9 17:55:43 2009 Subject: [Haskell-cafe] Incremental XML parsing with namespaces? In-Reply-To: <3283f7fe0906081139t1b9475d1sa9dba2c2a17ff4fe@mail.gmail.com> References: <3283f7fe0906081139t1b9475d1sa9dba2c2a17ff4fe@mail.gmail.com> Message-ID: <5ab17e790906091512u556bf8d9q55c64be8405223b4@mail.gmail.com> Hi, you may also want to look at: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/xml It knows about namespaces and, also, it's parser is lazy. -Iavor On Mon, Jun 8, 2009 at 11:39 AM, John Millikin wrote: > I'm trying to convert an XML document, incrementally, into a sequence > of XML events. A simple example XML document: > > > ? ?Doc title > ? ?abc1234 > ? ?Hello world! > > > The document can be very large, and arrives in chunks over a socket, > so I need to be able to "feed" the text data into a parser and receive > a list of XML events per chunk. Chunks can be separated in time by > intervals of several minutes to an hour, so pausing processing for the > arrival of the entire document is not an option. The type signatures > would be something like: > > type Namespace = String > type LocalName = String > > data Attribute = Attribute Namespace LocalName String > > data XMLEvent = > ? ?EventElementBegin Namespace LocalName [Attribute] | > ? ?EventElementEnd Namespace LocalName | > ? ?EventContent String | > ? EventError String > > parse :: Parser -> String -> (Parser, [XMLEvent]) > > I've looked at HaXml, HXT, and hexpat, and unless I'm missing > something, none of them can achieve this: > > + HaXml and hexpat seem to disregard namespaces entirely -- that is, > the root element is parsed to "doc" instead of > ("org:myproject:mainns", "doc"), and the second child is "x:ref" > instead of ("org:myproject:otherns", "ref"). Obviously, this makes > parsing mixed-namespace documents effectively impossible. I found an > email from 2004[1] that mentions a "filter" for namespace support in > HaXml, but no further information and no working code. > > + HXT looks promising, because I see explicit mention in the > documentation of recording and propagating namespaces. However, I > can't figure out if there's an incremental mode. A page on the wiki[2] > suggests that SAX is supported in the "html tag soup" parser, but I > want incremental parsing of *valid* documents. If incremental parsing > is supported by the standard "arrow" interface, I don't see any > obvious way to pull events out into a list -- I'm a Haskell newbie, > and still haven't quite figured out monads yet, let alone Arrows. > > Are there any libraries that support namespace-aware incremental parsing? > > [1] http://www.haskell.org/pipermail/haskell-cafe/2004-June/006252.html > [2] http://www.haskell.org/haskellwiki/HXT/Conversion_of_Haskell_data_from/to_XML > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From tphyahoo at gmail.com Tue Jun 9 19:21:31 2009 From: tphyahoo at gmail.com (Thomas Hartman) Date: Tue Jun 9 19:05:10 2009 Subject: [Haskell-cafe] please comment on my parser, can I do this cleaner? In-Reply-To: <910ddf450906091620m60430d21k35e144f7b988635@mail.gmail.com> References: <910ddf450906091129p2c2d14f2sfb654eb09d7b0773@mail.gmail.com> <200906092143.26241.daniel.is.fischer@web.de> <910ddf450906091620m60430d21k35e144f7b988635@mail.gmail.com> Message-ID: <910ddf450906091621j7a69b3cer1fde1cbbc0b96646@mail.gmail.com> Thanks. It seems my original parser also works against FOO,BAR,BAZ if you only modify atom = string "," ? ? ? ? ? <|> ( many1 $ noneOf "()<>," ) -- add , Indeed, what to call the "thingies" in a parser is a source of some personal consternation. What is a token, what is an atom, what is an expr? It all seems to be somewhat ad hoc. > 2009/6/9 Daniel Fischer : >> Am Dienstag 09 Juni 2009 20:29:09 schrieb Thomas Hartman: >>> All I want to do is split on commas, but not the commas inside () or <> >>> tags. >>> >>> I have been wanting to master parsec for a long time and this simple >>> exercise looked like a good place to start. >>> >>> The code below does the right thing. Am I missing any tricks to make >>> this simpler/neater? >>> >>> Thanks, thomas. >>> >>> thartman@ubuntu:~/perlArena>cat splitEm. >>> splitEm.hs ? splitEm.hs~ ?splitEm.pl ? splitEm.pl~ >>> thartman@ubuntu:~/perlArena>cat splitEm.hs >>> {-# LANGUAGE ScopedTypeVariables #-} >>> import Text.ParserCombinators.Parsec >>> import Text.ParserCombinators.Parsec.Char >>> import Text.PrettyPrint (vcat, render, text) >>> import Data.List.Split hiding (sepBy, chunk) >>> import Text.ParserCombinators.Parsec.Token >>> >>> import Debug.Trace >>> import Debug.Trace.Helpers >>> >>> -- this works, but is there a neater/cleaner way? >>> main = ripInputsXs (toEof splitter) "splitter" [ goodS, badS ] >>> >>> -- I need a way to split on commas, but not the commas inside '<>' or >>> '()' characters >>> goodS = "<*2>FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,7,6,5,0>" >>> badS = "<*2)FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,7,6,5,0>" >>> -- the first < matches a ), so reject this >>> >>> >>> splitter = do >>> ? chunks :: [String] <- toEof (many chunk) >>> ? let pieces = map concat $ splitOn [","] chunks >>> ? return pieces -- chunks >>> ? where >>> ? ? atom = string "," >>> ? ? ? ? ? ?<|> ( many1 $ noneOf "()<>" ) >>> ? ? chunk = parenExpr <|> ?atom >> >> I think that does not do what you want. >> >> For input "FOO,BAR,BAZ", chunks is ["FOO,BAR,BAZ"], that won't be split; as far as I can >> see, it splits only on commas directly following a parenExpr (or at the beginning of the >> input or directly following another splitting comma). >> >>> ? ? parenExpr :: GenParser Char st [Char] >>> ? ? parenExpr = let paren p = betweenInc (char '(' ) (char ')' ) p >>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <|> betweenInc (char '<' ) (char '>' ) >>> p >>> ? ? ? ? ? ? ? ? in paren $ option "" $ do ps <- many1 $ parenExpr <|> atom >>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return . concat $ ps >>> >>> betweenInc o' c' p' = do >>> ? o <- o' >>> ? p <- p' >>> ? c <- c' >>> ? return $ [o] ++ p ++ [c] >>> >>> toEof p' = do >>> ? ? ? ? r <- p' >>> ? ? ? ? eof >>> ? ? ? ? return r >>> >>> >>> >>> >>> >>> >>> ripInputs prs prsName xs = mapM_ (putStrLn . show . parse prs prsName ) xs >>> ripInputsXs prs prsName xs = mapM_ (putStrLn . showXs . parse prs prsName ) >>> xs where showXs v = case v of >>> ? ? ? ? ? Left e -> show e >>> ? ? ? ? ? Right xs -> render . vcat . map text $ xs >> >> I can offer (sorry for the names, and I don't know if what that does is really what you >> want): >> >> >> keepSepBy :: Parser a -> Parser a -> Parser [a] >> keepSepBy p sep = (do >> ? ?r <- p >> ? ?(do s <- sep >> ? ? ? ?xs <- keepSepBy p sep >> ? ? ? ?return (r:s:xs)) <|> return [r]) >> ? ?<|> return [] >> >> twain :: Parser a -> Parser a -> Parser [a] -> Parser [a] >> twain open close list = do >> ? ?o <- open >> ? ?l <- list >> ? ?c <- close >> ? ?return (o:l++[c]) >> >> comma :: Parser String >> comma = string "," >> >> simpleChar :: Parser Char >> simpleChar = noneOf "<>()," >> >> suite :: Parser String >> suite = many1 simpleChar >> >> atom :: Parser String >> atom = fmap concat $ many1 (parenExp <|> suite) >> >> parenGroup :: Parser String >> parenGroup = fmap concat $ keepSepBy atom comma >> >> parenExp :: Parser String >> parenExp = twain (char '<') (char '>') parenGroup >> ? ? ? ? ? ?<|> twain (char '(') (char ')') parenGroup >> >> chunks :: Parser [String] >> chunks = sepBy atom comma >> >> splitter = do >> ? ?cs <- chunks >> ? ?eof >> ? ?return cs >> >> goodS = "<*2>FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,7,6,5,0>" >> badS = "<*2)FOO<2,1>,<*3>(SigB<8:0:2>,BAR),<*2>Siga<2:0>,Sigb<8,7,6,5,0>" >> >> goodRes = parse splitter "splitter" goodS >> badRes = parse splitter "splitter" badS >> >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > From ccshan at post.harvard.edu Tue Jun 9 19:56:08 2009 From: ccshan at post.harvard.edu (Chung-chieh Shan) Date: Tue Jun 9 19:44:57 2009 Subject: [Haskell-cafe] Re: I love purity, but it's killing me. References: <594c1e830802072233n2b36ca82wd3c778f22edd4564@mail.gmail.com> <4cka85-223.ln1@mantle.rutgers.edu> <856033f20905270058q493a254ah4623fbc354096574@mail.gmail.com> <20090607014853.GA30135@mantle.rutgers.edu> <856033f20906082224s2b7d5391gdc7a4ed913004639@mail.gmail.com> Message-ID: Paul L wrote in article <856033f20906082224s2b7d5391gdc7a4ed913004639@mail.gmail.com> in gmane.comp.lang.haskell.cafe: > The open question is whether there exists such a > solution that's both elegant and efficient at maintain proper sharing > in the object language. What is your criterion for "efficient"? > We certainly can get rid of all interpretive overheads by either > having a "tagless" interpreter (as in Oleg and Shan's paper), or by > direct compilation. (BTW, the paper is by Jacques Carette, Oleg Kiselyov, and Chung-chieh Shan.) > But so far I don't see how a tagless interpreter > could handle sharing when it can't be distinguished in the host > language. Indeed, I would agree with those on this thread who have stated that sharing should be distinguished in the host language. -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig We want our revolution, and we want it now! -- Marat/Sade We want our revolution, and we'll take it at such time as you've gotten around to delivering it -- Haskell programmer From heyitsjeremy at gmail.com Tue Jun 9 20:13:57 2009 From: heyitsjeremy at gmail.com (haonan21) Date: Tue Jun 9 19:57:35 2009 Subject: [Haskell-cafe] help with a question Message-ID: <23946402.post@talk.nabble.com> I'm very new to haskell hugs and would appreciate it if someone could help me out here. I've been giving 2 questions. 1.) A and B are two sets of integers. Implement a function to obtain the integers that belong to both sets. Test your function fully. 2.) Define and test a function f, which, if A is a set of {x, y, z} then f(A) = {{},{x}, {y}, {z}, {x, y}, {x,z}, {y,z}, {x, y, z}} Manage to get the first one. interset::[Int]->[Int]->[Int] interset x [] = [] interset [] y = [] interset x@(xs:xt) y@(ys:yt) = if xs == ys then as:(interset at yt) else interset at y Totally have no clue for the 2nd question. could someone help me out ? Many thanks! -- View this message in context: http://www.nabble.com/help-with-a-question-tp23946402p23946402.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From mvanier42 at gmail.com Tue Jun 9 20:53:02 2009 From: mvanier42 at gmail.com (Michael Vanier) Date: Tue Jun 9 20:36:44 2009 Subject: [Haskell-cafe] help with a question In-Reply-To: <23946402.post@talk.nabble.com> References: <23946402.post@talk.nabble.com> Message-ID: <4A2F03EE.5020006@cs.caltech.edu> haonan21 wrote: > I'm very new to haskell hugs and would appreciate it if someone could help me > out here. I've been giving 2 questions. > > 1.) A and B are two sets of integers. Implement a function to obtain the > integers that belong to both sets. > Test your function fully. > > 2.) Define and test a function f, which, if A is a set of {x, y, z} then > f(A) = {{},{x}, {y}, {z}, {x, y}, {x,z}, {y,z}, {x, y, z}} > > Manage to get the first one. > interset::[Int]->[Int]->[Int] > > interset x [] = [] > > interset [] y = [] > > interset x@(xs:xt) y@(ys:yt) = > if xs == ys > then as:(interset at yt) > else interset at y > > Totally have no clue for the 2nd question. could someone help me out ? > > Many thanks! > Haonan, This looks like homework, but I can offer a few suggestions. Your "interset" function uses "as" and "at" where I think you mean "xs" and "xt" and the else case is wrong (you need to test the code!). Anyway, it looks like you're assuming that the lists are in ascending order, and I don't see that in the problem specification -- it won't work if that isn't the case. More interestingly, you should look at the List (or Data.List) library; it contains a library function which can solve your problem in one line. As for the second function, that's a classic problem used for teaching recursion: find all subsets of a given list. The way to solve it is to first ask what the solution is for the empty set (which should be obvious). Then assume that you have the solution for the tail of the list ({y, z}). How would you use this and the head of the list (x) to generate the full solution? HTH, Mike From bos at serpentine.com Tue Jun 9 23:38:28 2009 From: bos at serpentine.com (Bryan O'Sullivan) Date: Tue Jun 9 23:22:08 2009 Subject: [Haskell-cafe] Re: Building network package on Windows In-Reply-To: <5ab17e790906082218h55b4680ayc9a2b3c5ee679e70@mail.gmail.com> References: <5ab17e790906062143h3968488bg577cdbe0de796bd9@mail.gmail.com> <5ab17e790906071704h19255d38oa82b48ef842764f9@mail.gmail.com> <5ab17e790906081648i2d9e11f6ic189667c6d6d470a@mail.gmail.com> <5ab17e790906082218h55b4680ayc9a2b3c5ee679e70@mail.gmail.com> Message-ID: On Mon, Jun 8, 2009 at 10:18 PM, Iavor Diatchki wrote: > > OK, I think that I found and fixed the problem. As Thomas pointed > out, the configure script is not wrong. The problem turned out to be > the foreign import for "getnameinfo" (this was the missing symbol). > So it was the name mangling! Great, thanks for the patch. It's applied. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090609/2032b133/attachment.html From duncan.coutts at worc.ox.ac.uk Wed Jun 10 04:58:49 2009 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Wed Jun 10 04:42:34 2009 Subject: [Haskell-cafe] nubBy seems broken in recent GHCs In-Reply-To: <4a2a9bd9.12115e0a.77d5.5b0d@mx.google.com> References: <89ca3d1f0906052221k62c12d44ha92bcab4ede4d2f2@mail.gmail.com> <4a2a9bd9.12115e0a.77d5.5b0d@mx.google.com> Message-ID: <1244624329.26313.60.camel@localhost> On Sat, 2009-06-06 at 18:39 +0200, Bertram Felgenhauer wrote: > Interesting. This was changed in response to > > http://hackage.haskell.org/trac/ghc/ticket/2528 > > | Tue Sep 2 11:29:50 CEST 2008 Simon Marlow > | * #2528: reverse the order of args to (==) in nubBy to match nub > | This only makes a difference when the (==) definition is not > | reflexive, but strictly speaking it does violate the report definition > | of nubBy, so we should fix it. > > It turns out that 'elem' differs from the report version and should > have its comparison reversed. Of course that would only ever matter > for broken Eq instances. > > However, the report also states that the nubBy function may assume that > the given predicate defines an equivalence relation. > > http://haskell.org/onlinereport/list.html#sect17.6 > > So I'm not sure there's anything to be fixed here - although backing > out the above patch probably won't hurt anybody. Seems to me the obvious solution is to revert the nubBy change and then fix nub so that so that we still get nub = nubBy (==) (which is what ticket #2528 was complaining about in the first place). We need more SmallCheck properties for the List module! When Don and I were testing our stream versions of the List module we uncovered several of these little weirdnesses which were underspecified in the report, or different between the report and common implementations. For example I seem to recall that genericTake and take do not coincide when their types coincide. Duncan From lemming at henning-thielemann.de Wed Jun 10 05:11:08 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Wed Jun 10 04:55:24 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <14115408.20090609213612@gmail.com> References: <23940249.post@talk.nabble.com> <23943301.post@talk.nabble.com> <14115408.20090609213612@gmail.com> Message-ID: On Tue, 9 Jun 2009, Bulat Ziganshin wrote: > Hello jerzy, > > Tuesday, June 9, 2009, 8:23:04 PM, you wrote: > >> Please, tell him first about random streams, which he can handle without >> IO. Or, about ergodic functions (hashing contraptions which transform ANY >> parameter into something unrecognizable). When he says : "I know all that", >> THEN hurt him badly with monads. > > i think that for someone coming from imperative programming teeling > about IO monad is the easiest way. and then he will learn how to do it > FP way I came from imperative programming and never wanted to use randomIO, because it forces you to IO and randomsIO is not lazy. From paravinicius at yahoo.com.br Wed Jun 10 05:11:38 2009 From: paravinicius at yahoo.com.br (paravinicius@yahoo.com.br) Date: Wed Jun 10 04:57:51 2009 Subject: [Haskell-cafe] How To Make It Faster? Message-ID: <20090610091138.GA3992@mephisto.bitforest.org> Hi, I come up with the following solution for this spoj problem (warning!): problem: https://www.spoj.pl/problems/ARITH2/ solution: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5720#a5720 I'd like to make it run faster, if possible. What should I do to identify the bottlenecks and once I find them, a few guidelines to actually fix them. Thanks in advance, -- ~dsouza yahoo!im: paravinicius gpg key fingerprint: 71B8 CE21 3A6E F894 5B1B 9ECE F88E 067F E891 651E From lemming at henning-thielemann.de Wed Jun 10 05:16:57 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Wed Jun 10 05:00:34 2009 Subject: [Haskell-cafe] nubBy seems broken in recent GHCs In-Reply-To: <89ca3d1f0906091203p164735f4s1d37fb5dc127b0a9@mail.gmail.com> References: <89ca3d1f0906052221k62c12d44ha92bcab4ede4d2f2@mail.gmail.com> <4a2a9bd9.12115e0a.77d5.5b0d@mx.google.com> <89ca3d1f0906091203p164735f4s1d37fb5dc127b0a9@mail.gmail.com> Message-ID: On Tue, 9 Jun 2009, Cale Gibbard wrote: > Similarly, groupBy f xs is (and should be) the unique list of > contiguous sublists of xs such that: > 1) concat (groupBy f xs) = xs > 2) If x is the head of any of the sublists and y is any other element > of that sublist, then f x y > 3) The sequence of lengths of the sublists is lexicographically > maximum for all lists satisfying the first two properties (That is, it > always prefers adding elements to an earlier group to starting a new > group.) groupBy defined this way was found to be inappropriate for many cases, like grouping a list into increasing sequences using groupBy (<=). Other cases can be found in Haskell-Cafe or Libraries@haskell.org. From dsouza at bitforest.org Wed Jun 10 05:20:08 2009 From: dsouza at bitforest.org (Diego Souza) Date: Wed Jun 10 05:06:20 2009 Subject: [Haskell-cafe] How To Make It Faster? Message-ID: <20090610092008.GA4265@mephisto.bitforest.org> Hi, I come up with the following solution for this easy spoj problem (warning!): problem: https://www.spoj.pl/problems/ARITH2/ solution: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5720#a5720 I'd like to make it run faster, if possible. What should I do to identify the bottlenecks and once I find them, a few guidelines to actually fix them. Thanks in advance, -- ~dsouza yahoo!im: paravinicius gpg key fingerprint: 71B8 CE21 3A6E F894 5B1B 9ECE F88E 067F E891 651E From ketil at malde.org Wed Jun 10 05:38:31 2009 From: ketil at malde.org (Ketil Malde) Date: Wed Jun 10 05:21:42 2009 Subject: [Haskell-cafe] How To Make It Faster? In-Reply-To: <20090610092008.GA4265@mephisto.bitforest.org> (Diego Souza's message of "Wed\, 10 Jun 2009 06\:20\:08 -0300") References: <20090610092008.GA4265@mephisto.bitforest.org> Message-ID: <87prdcjunc.fsf@malde.org> Diego Souza writes: > I'd like to make it run faster, if possible. What should I do to > identify the bottlenecks and once I find them, a few guidelines to > actually fix them. The usual approach is to compile with profiling (ghc -prof -auto-all, don't forget to optimize!), and run with time profiling enabled (./my-program -my-options +RTS -p). You can then examine the resulting profiling output (my-program.prof) to identify hotspots, and try to improve them. -k -- If I haven't seen further, it is by standing in the footprints of giants From magnus at therning.org Wed Jun 10 06:24:01 2009 From: magnus at therning.org (Magnus Therning) Date: Wed Jun 10 06:07:39 2009 Subject: [Haskell-cafe] How To Make It Faster? In-Reply-To: <20090610091138.GA3992@mephisto.bitforest.org> References: <20090610091138.GA3992@mephisto.bitforest.org> Message-ID: On Wed, Jun 10, 2009 at 10:11 AM, wrote: > Hi, > > I come up with the following solution for this spoj problem (warning!): > > problem: ?https://www.spoj.pl/problems/ARITH2/ > solution: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5720#a5720 > > I'd like to make it run faster, if possible. What should I do to > identify the bottlenecks and once I find them, a few guidelines to > actually fix them. > > Thanks in advance, My profiling-fu is rather weak, but I think about 40% of the time is spent on reading from stdin, about 17% on splitting that into lines and then words. Only about 10% is spent in arith_expression and 8% in the lambda you pass into forM. I don't have any suggestions for actually speeding it up, but profiling helps in concentrating your efforts. :-) /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe From ptrash at web.de Wed Jun 10 07:55:59 2009 From: ptrash at web.de (ptrash) Date: Wed Jun 10 07:39:37 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <23940249.post@talk.nabble.com> References: <23940249.post@talk.nabble.com> Message-ID: <23960652.post@talk.nabble.com> Hi, I have tried on the console to write x <- randomRIO(1,10) :t x Everythings fine and the type of x is x :: Integer Now I have tried to write a Method which gives me a Number of random numbers the same way but it doesn't work. randomList :: Int -> [Integer] randomList 0 = [] randomList n = do r <- randomRIO (1, 10) r:randomList(n-1) It says Couldn't match expected type `IO t' against inferred type `[t]' r <- randomRIO (1,10) causes an error. But why does it work on the console? Is there a way to solve it another way? -- View this message in context: http://www.nabble.com/Convert-IO-Int-to-Int-tp23940249p23960652.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From miguelimo38 at yandex.ru Wed Jun 10 07:58:29 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Wed Jun 10 07:42:54 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <23960652.post@talk.nabble.com> References: <23940249.post@talk.nabble.com> <23960652.post@talk.nabble.com> Message-ID: <4A2F9FE5.7080509@yandex.ru> "r <- randomRIO (1,10)" is NOT the source of error. Why do you think it is? ptrash wrote on 10.06.2009 15:55: > Hi, > > I have tried on the console to write > > x <- randomRIO(1,10) > :t x > > Everythings fine and the type of x is > x :: Integer > > Now I have tried to write a Method which gives me a Number of random numbers > the same way but it doesn't work. > > randomList :: Int -> [Integer] > randomList 0 = [] > randomList n = do > r <- randomRIO (1, 10) > r:randomList(n-1) > > It says Couldn't match expected type `IO t' against inferred type `[t]' > r <- randomRIO (1,10) causes an error. But why does it work on the console? > Is there a way to solve it another way? From ptrash at web.de Wed Jun 10 08:05:09 2009 From: ptrash at web.de (ptrash) Date: Wed Jun 10 07:48:46 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <23960652.post@talk.nabble.com> References: <23940249.post@talk.nabble.com> <23960652.post@talk.nabble.com> Message-ID: <23960827.post@talk.nabble.com> Hmm...I use the Eclipse Plugin. And this row is marked as error. Then where is the error? -- View this message in context: http://www.nabble.com/Convert-IO-Int-to-Int-tp23940249p23960827.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From iainspeed at gmail.com Wed Jun 10 08:08:32 2009 From: iainspeed at gmail.com (Iain Barnett) Date: Wed Jun 10 07:52:12 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <23960652.post@talk.nabble.com> References: <23940249.post@talk.nabble.com> <23960652.post@talk.nabble.com> Message-ID: <5320F3DF-1539-4DFC-A000-547BD3B79C6D@gmail.com> On 10 Jun 2009, at 12:55 pm, ptrash wrote: > > > Now I have tried to write a Method which gives me a Number of > random numbers > the same way but it doesn't work. > > randomList :: Int -> [Integer] > randomList 0 = [] > randomList n = do > r <- randomRIO (1, 10) > r:randomList(n-1) > > It says Couldn't match expected type `IO t' against inferred type > `[t]' > r <- randomRIO (1,10) causes an error. But why does it work on the > console? > Is there a way to solve it another way? > I had the same problem a while back, the thread is here http://www.mail-archive.com/haskell-cafe@haskell.org/msg46194.html the console uses IO already, so it's not a problem there. I ended up learning about the >>= operator, and that helped a lot. Anyway, lots of helpful links in that mail thread. Iain From sebastian.sylvan at gmail.com Wed Jun 10 09:08:15 2009 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Wed Jun 10 08:51:53 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <23960652.post@talk.nabble.com> References: <23940249.post@talk.nabble.com> <23960652.post@talk.nabble.com> Message-ID: <3d96ac180906100608i43d677dar82720e655c8c902d@mail.gmail.com> On Wed, Jun 10, 2009 at 12:55 PM, ptrash wrote: > > Hi, > > I have tried on the console to write > > x <- randomRIO(1,10) > :t x > > Everythings fine and the type of x is > x :: Integer > The type of x *in the context of an IO computation* is Integer. GHCi is basically an IO computation. Another example: foo :: Integer -> Integer foo x = x+1 main :: IO () main = do x <- randomRIO (1,10) print (foo x) This is fine. In the context of the IO computation "main", x is bound to the result of "randomRIO (1,10)", and you can pass it to functions expecting Integer values (not IO Integer!). So in this way, and this way only, you can access the Integer returned by an IO action. You can *not* access the Integer returned by an IO action from within a normal function, *only* by by binding it to a variable (with "<-") inside *another IO action*. I'm not sure what text you're using to learn Haskell, but a very basic and fundamental property of Haskell (and indeed 99% of why it's cool, IMO) is that code which does side effects (like reading from a global random number seed), and code which does not do side effects (i.e. functions which always return the same result given the same input) are kept extremely separate. This appears to be the source of your confusion. It's simply not possible to do side effect inside a normal function, just like it's not possible to cast an arbitrary integer to a pointer in Java - the language is designed to not require it, and the benefits of being able to trust that your program obeys certain properties are worth it. >randomList :: Int -> [Integer] >randomList 0 = [] >randomList n = do > r <- randomRIO (1, 10) > r:randomList(n-1) In this code you're trying to do side effects from within a pure function. This is *not* allowed. You must either make randomList an IO action (i.e returning IO [Integer]), or remove any impurities from its implementation. For example you can make randomList take a randon number generator and use the random number generator to produce random values: randomList :: (RandomGen g) -> Int -> g -> [Integer] randomList 0 _ = [] randomList n generator = r : randomList (n-1) newGenerator where (r, newGenerator) = randomR (1,10) generator This is totally pure, since if you pass in the same random number generator multiple times, you'll get the exact same result. Note that randomR returns a random values and a new random number generator (you wouldn't want to pass along the same one in the recursive call to randomList as that would give you an identical random number each time you use it!). So where do you get the random number generator from? Well one way is to make your own using "mkStdGen", which produces one from a seed (it will give you an identical one given an identical seed). Another way is to use "newStdGen" to generate one from within an IO action: main :: IO () main = do generator <- newStdGen print ( randomList 10 generator ) The point, though, is that things having side effects (such as newStdGen) can only be used in the context of something else having side effects. So the "IO" type is "contagious", as soon as you use it in a function, then that function must also return IO, and so on for anything using *that* function and son. -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090610/aeae6c6f/attachment-0001.html From sebastian.sylvan at gmail.com Wed Jun 10 09:10:28 2009 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Wed Jun 10 08:54:05 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <3d96ac180906100608i43d677dar82720e655c8c902d@mail.gmail.com> References: <23940249.post@talk.nabble.com> <23960652.post@talk.nabble.com> <3d96ac180906100608i43d677dar82720e655c8c902d@mail.gmail.com> Message-ID: <3d96ac180906100610x2751760w3b401d82138654f0@mail.gmail.com> On Wed, Jun 10, 2009 at 2:08 PM, Sebastian Sylvan < sebastian.sylvan@gmail.com> wrote: > > > randomList :: (RandomGen g) -> Int -> g -> [Integer] > Just spotted this typo, it should be: randomList :: (RandomGen g) = Int -> g -> [Integer] There may be other minor typos as I don't have a compiler handy. -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090610/b4090722/attachment.html From sebastian.sylvan at gmail.com Wed Jun 10 09:11:17 2009 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Wed Jun 10 08:54:54 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <3d96ac180906100610x2751760w3b401d82138654f0@mail.gmail.com> References: <23940249.post@talk.nabble.com> <23960652.post@talk.nabble.com> <3d96ac180906100608i43d677dar82720e655c8c902d@mail.gmail.com> <3d96ac180906100610x2751760w3b401d82138654f0@mail.gmail.com> Message-ID: <3d96ac180906100611n6a88a6eayb118811b9bdb0262@mail.gmail.com> On Wed, Jun 10, 2009 at 2:10 PM, Sebastian Sylvan < sebastian.sylvan@gmail.com> wrote: > > > On Wed, Jun 10, 2009 at 2:08 PM, Sebastian Sylvan < > sebastian.sylvan@gmail.com> wrote: > >> >> >> randomList :: (RandomGen g) -> Int -> g -> [Integer] >> > > Just spotted this typo, it should be: > > randomList :: (RandomGen g) = Int -> g -> [Integer] > > There may be other minor typos as I don't have a compiler handy. > Oh come on! randomList :: (RandomGen g) => Int -> g -> [Integer] -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090610/7365292e/attachment.html From leimy2k at gmail.com Wed Jun 10 10:57:33 2009 From: leimy2k at gmail.com (David Leimbach) Date: Wed Jun 10 10:41:10 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <23960652.post@talk.nabble.com> References: <23940249.post@talk.nabble.com> <23960652.post@talk.nabble.com> Message-ID: <3e1162e60906100757r9c0a85u8d0672baf8f16436@mail.gmail.com> This stuff is tricky for most newcomers I suspect (it was for me) x <- randomRIO(1,10) is "temporarilly" pulling the Integer you've named "x" out of the IO Integer it came from. You can think of the console as being an input/output stream inside the IO monad, which is why it is allowed there. The fact is these are equivalent do x <- randomRIO(1,10) x : and randomRIO(1,10) >>= (\x -> x:>=) is the "bind" operator for Monads and it allows you to do things like sequence an IO operation or action, then examine the contents returned by that IO action, possibly performing some transformation on it with another function. x: is the function that takes a value "x" and applies the cons function (:) to build a list with . The problem is that the type system of Haskell will not allow this because the bind function (which is used by the "do" syntax behind the scenes) is of type: (>>=) :: (Monad m) => m a -> (a -> m b) -> m b Which states that the first argument to (>>=) is a Monad a, or in your case "randomRIO(1,10)" which is of type "IO Integer" IO being the "m" part of "m a" and "Integer" being the "a" part of "m a". What comes next is your consing function of (x : ). This is of type [Integer]. So you failed to give it a function of type (a -> m b). (a -> m b) says that the input type to that function must be the same as the "contained" value of the first argument to (>>=) (because they're both of type 'a'). The "m b" part says that you must use the *same Monad* you used in the first parameter to (>>=) which is IO, not []. However the 'b' part says you can convert things of one type 'a' to things of another type 'b'. This is legal: randomRIO(1,10) >>= return (x : ) However what you've got now is not a List of Integers ([Integer]) but an IO [Integer]. Because of the type of (>>=), you are not going to ever permanently escape that IO "wrapper" around your values you're interested in. The "return" is a function of the class Monad, that takes a value, and "wraps it up" in a monad. Based on the (>>=) function's type, the system can infer that you meant the IO monad here. You can even test this at the console: Prelude System.Random> randomRIO(1,10) >>= (\x -> return (x:[99])) [7,99] Prelude System.Random> randomRIO(1,10) >>= (\x -> return (x:[99])) [6,99] Prelude System.Random> randomRIO(1,10) >>= (\x -> return (x:[99])) [2,99] Prelude System.Random> :t randomRIO(1,10) >>= (\x -> return (x:[99])) randomRIO(1,10) >>= (\x -> return (x:[99])) :: (Num t, Random t) => IO [t] vs "randomRIO(1,10) >>= (\x -> x:[99])" Which doesn't pass the type checking of the system because [] is not the same monad as IO. Perhaps you'd do well for yourself by reading "Learn You A Haskell"? I've found it to be pretty darned good at explaining lots of haskell to newcomers. Dave On Wed, Jun 10, 2009 at 4:55 AM, ptrash wrote: > > Hi, > > I have tried on the console to write > > x <- randomRIO(1,10) > :t x > > Everythings fine and the type of x is > x :: Integer > > Now I have tried to write a Method which gives me a Number of random > numbers > the same way but it doesn't work. > > randomList :: Int -> [Integer] > randomList 0 = [] > randomList n = do > r <- randomRIO (1, 10) > r:randomList(n-1) > > It says Couldn't match expected type `IO t' against inferred type `[t]' > r <- randomRIO (1,10) causes an error. But why does it work on the console? > Is there a way to solve it another way? > -- > View this message in context: > http://www.nabble.com/Convert-IO-Int-to-Int-tp23940249p23960652.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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090610/172070d9/attachment.html From ptrash at web.de Wed Jun 10 11:08:39 2009 From: ptrash at web.de (ptrash) Date: Wed Jun 10 10:52:17 2009 Subject: [Haskell-cafe] Convert IO Int to Int In-Reply-To: <3d96ac180906100608i43d677dar82720e655c8c902d@mail.gmail.com> References: <23940249.post@talk.nabble.com> <23960652.post@talk.nabble.com> <3d96ac180906100608i43d677dar82720e655c8c902d@mail.gmail.com> Message-ID: <23964365.post@talk.nabble.com> Thanks a lot. I have put now everything into the main method and it works. -- View this message in context: http://www.nabble.com/Convert-IO-Int-to-Int-tp23940249p23964365.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From kowey at darcs.net Wed Jun 10 11:43:57 2009 From: kowey at darcs.net (Eric Kow) Date: Wed Jun 10 11:27:36 2009 Subject: [Haskell-cafe] who's up for a hackathon? (ICFP, late Aug, early Sept) Message-ID: <20090610154356.GK29325@brighton.ac.uk> Dear Haskellers, ICFP 2009 takes place from Monday 31 August to Wednesday 2 September, with the Haskell Symposium following it on 3 September. Would anybody be interested having a Haskell Hackathon during this? My thinking is that to catch people who are only going to the Haskell Symposium, the best time is the following weekend (4-6 September). Otherwise, the weekend before (29-30 August) is also an option and has the benefit of catching people before they get tired :-) Rah, rah, hackathon! 1. If possible, I'd like get a idea if there is any interest in attending such a Hackathon if it were to take place. 2. For rah-rah Hackathon to work, we need people! Could I get one kind (and local) soul to act as an organiser for this? Thanks! -- Eric Kow PGP Key ID: 08AC04F9 -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: Digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090610/86e47450/attachment.bin From jefferson.r.heard at gmail.com Wed Jun 10 12:29:19 2009 From: jefferson.r.heard at gmail.com (Jeff Heard) Date: Wed Jun 10 12:12:55 2009 Subject: [Haskell-cafe] Weird and entirely random problem... Message-ID: <4165d3a70906100929x11b7a758sec44618785fd32@mail.gmail.com> The code that causes it is here: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5731#a5731 This is the strangest thing. Occasionally, using nothing but gets and puts and frees on a non-full Cache will result in this: Cache { store = fromList [("(\"icons/addBookmark.png\",False)",TextureObject {textureID = 4}) ,("(\"icons/addCircle.png\",False)",TextureObject {textureID = 1}) ,("(\"icons/addContent.png\",False)",TextureObject {textureID = 2}) ,("(\"icons/addElsewhereLink.png\",False)",TextureObject {textureID = 3})] , times = fromList [(61314,"(\"294.0\",AlignLeft,Nothing,WrapWholeWords,False,0.0,0.0)") ,(61316,"(\"icons/addBookmark.png\",False)"),(61318,"(\"icons/addCircle.png\",False)") ,(61320,"(\"icons/addContent.png\",False)"),(61322,"(\"icons/addElsewhereLink.png\",False)")] , now = 61323 , maxsize = 1024768000 , size = 4 , decimation = 0 } Sometimes the problem is self-correcting. Sometimes it is most certainly not. But I don't understand how my code can possibly allow for this. From nccb2 at kent.ac.uk Wed Jun 10 12:58:36 2009 From: nccb2 at kent.ac.uk (Neil Brown) Date: Wed Jun 10 12:42:09 2009 Subject: [Haskell-cafe] Weird and entirely random problem... In-Reply-To: <4165d3a70906100929x11b7a758sec44618785fd32@mail.gmail.com> References: <4165d3a70906100929x11b7a758sec44618785fd32@mail.gmail.com> Message-ID: <4A2FE63C.4050302@kent.ac.uk> Hi, I'm presuming the problem with your result is that the " The code that causes it is here: > > http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5731#a5731 > > This is the strangest thing. Occasionally, using nothing but gets and > puts and frees on a non-full Cache will result in this: > > Cache { > store = fromList > [("(\"icons/addBookmark.png\",False)",TextureObject {textureID = 4}) > ,("(\"icons/addCircle.png\",False)",TextureObject {textureID = 1}) > ,("(\"icons/addContent.png\",False)",TextureObject {textureID = 2}) > ,("(\"icons/addElsewhereLink.png\",False)",TextureObject > {textureID = 3})] > , times = fromList > [(61314,"(\"294.0\",AlignLeft,Nothing,WrapWholeWords,False,0.0,0.0)") > ,(61316,"(\"icons/addBookmark.png\",False)"),(61318,"(\"icons/addCircle.png\",False)") > ,(61320,"(\"icons/addContent.png\",False)"),(61322,"(\"icons/addElsewhereLink.png\",False)")] > > , now = 61323 > , maxsize = 1024768000 > , size = 4 > , decimation = 0 > } > > > Sometimes the problem is self-correcting. Sometimes it is most > certainly not. But I don't understand how my code can possibly allow > for this. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From jefferson.r.heard at gmail.com Wed Jun 10 13:26:33 2009 From: jefferson.r.heard at gmail.com (Jeff Heard) Date: Wed Jun 10 13:10:26 2009 Subject: [Haskell-cafe] Weird and entirely random problem... In-Reply-To: <4A2FE63C.4050302@kent.ac.uk> References: <4165d3a70906100929x11b7a758sec44618785fd32@mail.gmail.com> <4A2FE63C.4050302@kent.ac.uk> Message-ID: <4165d3a70906101026g20125bf7xe634bdaf6b57a615@mail.gmail.com> That works, yes... thanks! On Wed, Jun 10, 2009 at 12:58 PM, Neil Brown wrote: > Hi, > > I'm presuming the problem with your result is that the " in the times map, and not in the store map (you weren't clear on the exact > problem). > > I took a look at the code, here's my thoughts on why this occurs. ?If you > start by putting something in the cache with key "foo", an entry is created > in the times map, say: fromList [(0, "foo")]. ?If you then get the item from > the cache, you add another item to the times map, giving you: fromList [(0, > "foo"), (1, "foo")]. ?Another get operation, and you'll have fromList [(0, > "foo"), (1, "foo"), (2, "foo")]. ?If you now call free on the cache, it > finds the value associated with the minimum key: "foo". ?But it only deletes > the minimum key in the times map, leaving: fromList [(1, "foo"), (2, > "foo")]. ?Thus you can have entries in the times map without them being in > the store. ?put would clear them out (perhaps this was the self-correction > you saw), but get adds one each item, and free only clears one. ?So you > either need to fix get, or free. > > Does that help, or was your question something else entirely? :-) > > BTW, IntMap.fromList . filter (f . snd) . IntMap.toList is more concisely > (and efficiently) written as: IntMap.filter f > > Thanks, > > Neil. > > Jeff Heard wrote: >> >> The code that causes it is here: >> >> http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5731#a5731 >> >> This is the strangest thing. ?Occasionally, using nothing but gets and >> puts and frees on a non-full Cache will result in this: >> >> Cache { >> ? ? ?store = fromList >> ? ? ? ?[("(\"icons/addBookmark.png\",False)",TextureObject {textureID = >> 4}) >> ? ? ? ?,("(\"icons/addCircle.png\",False)",TextureObject {textureID = 1}) >> ? ? ? ?,("(\"icons/addContent.png\",False)",TextureObject {textureID = 2}) >> ? ? ? ?,("(\"icons/addElsewhereLink.png\",False)",TextureObject >> {textureID = 3})] >> ? ?, times = fromList >> ? ? ? ?[(61314,"(\"294.0\",AlignLeft,Nothing,WrapWholeWords,False,0.0,0.0)") >> >> ?,(61316,"(\"icons/addBookmark.png\",False)"),(61318,"(\"icons/addCircle.png\",False)") >> >> ?,(61320,"(\"icons/addContent.png\",False)"),(61322,"(\"icons/addElsewhereLink.png\",False)")] >> >> ? ?, now = 61323 >> ? ?, maxsize = 1024768000 >> ? ?, size = 4 >> ? ?, decimation = 0 >> } >> >> >> Sometimes the problem is self-correcting. ?Sometimes it is most >> certainly not. ?But I don't understand how my code can possibly allow >> for this. >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > From byorgey at seas.upenn.edu Wed Jun 10 17:32:51 2009 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Wed Jun 10 17:16:26 2009 Subject: [Haskell-cafe] Hac phi accommodation: register by June 15 for reduced rate! Message-ID: <20090610213251.GA20651@seas.upenn.edu> Hi all, This is a quick reminder for people interested in attending Hac phi who have not yet reserved a hotel room: if you'd like to reserve a room at Club Quarters at the reduced rate ($114/night single, $129/night double), we ask that you send a note to Daniel Wagner (daniel@wagner-home.com) by this Monday, June 15th. To register, or for more infomation about Hac phi, visit the wiki page [1]. Thanks, and we look forward to seeing you at the hackathon! The Hac phi Team [1] http://haskell.org/haskellwiki/Hac_%CF%86 From rodprice at raytheon.com Wed Jun 10 18:14:53 2009 From: rodprice at raytheon.com (Rodney Price) Date: Wed Jun 10 18:00:11 2009 Subject: [Haskell-cafe] Re: [Haskell] ANNOUNCE: testrunner-0.9 In-Reply-To: <9d4d38820906081107h4d379959v2be0af1dd56abac1@mail.gmail.com> References: <200906081224.36779.tux_rocker@reinier.de> <9d4d38820906080603x9acf62dm32474012c451981a@mail.gmail.com> <200906081546.13437.tux_rocker@reinier.de> <9d4d38820906081107h4d379959v2be0af1dd56abac1@mail.gmail.com> Message-ID: <20090610161453.6461ed82@jabber.aur.us.ray.com> When I run Example.lhs for test-framework I get [0] [1] in the test results, just as you show on your web page. If I run Example.lhs under ghci rather than compiled, I find the [0] [1] mingled with the test results in random ways. This leads me to believe that whatever is printing out [0] [1] is running is a separate thread. Does this [0] [1] have any meaning? If not, how do I get rid of it? Thanks, -Rod On Mon, 8 Jun 2009 19:07:52 +0100 Max Bolingbroke wrote: > 2009/6/8 Reinier Lamers : > > I checked out testpack and that did not meet my requirements. I > > don't know if I considered test-framework. If I did, it may be that > > I was turned off by the fact that the 'home page' link on cabal > > just goes to a web presentation of the source tree on github. > > Reinier, > > You are quite right that this is a weakness. I've been meaning to put > a site together for a while, and your comment gave me the impetus to > do it: > > http://batterseapower.github.com/test-framework/ > > That's much friendlier! > > All the best, > Max > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > The following line is added for your protection and will be used for > analysis if this message is reported as spam: > > (Raytheon Analysis: IP=128.36.229.215; > e-from=haskell-cafe-bounces@haskell.org; > from=batterseapower@hotmail.com; date=Jun 8, 2009 6:08:07 PM; > subject=[Haskell-cafe] Re: [Haskell] ANNOUNCE: testrunner-0.9) From nowgate at yahoo.com Wed Jun 10 20:05:11 2009 From: nowgate at yahoo.com (michael rice) Date: Wed Jun 10 19:48:47 2009 Subject: [Haskell-cafe] Building a tree? Message-ID: <565459.78504.qm@web31105.mail.mud.yahoo.com> Here's a function from Data.Tree: unfoldTree :: (b -> (a, [b])) -> b -> Tree a Build a tree from a seed value Could someone please give me a brief example of usage. Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090610/938ca5f7/attachment.html From lemming at henning-thielemann.de Wed Jun 10 20:11:34 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Wed Jun 10 19:55:11 2009 Subject: [Haskell-cafe] Building a tree? In-Reply-To: <565459.78504.qm@web31105.mail.mud.yahoo.com> References: <565459.78504.qm@web31105.mail.mud.yahoo.com> Message-ID: On Wed, 10 Jun 2009, michael rice wrote: > Here's a function from Data.Tree: > > unfoldTree :: (b -> (a, [b])) -> b -> Tree a > Build a tree from a seed value > > Could someone please give me a brief example of usage. unfoldTree (\n -> (chr (n + ord 'a'), replicate n (n-1))) 3 Or did you expect a "real world" example? :-) From wren at freegeek.org Wed Jun 10 20:13:20 2009 From: wren at freegeek.org (wren ng thornton) Date: Wed Jun 10 19:56:57 2009 Subject: [Haskell-cafe] Building a tree? In-Reply-To: <565459.78504.qm@web31105.mail.mud.yahoo.com> References: <565459.78504.qm@web31105.mail.mud.yahoo.com> Message-ID: <4A304C20.4020807@freegeek.org> michael rice wrote: > Here's a function from Data.Tree: > > unfoldTree :: (b -> (a, [b])) -> b -> Tree a > Build a tree from a seed value > > Could someone please give me a brief example of usage. Data.Tree> let t = unfoldTree (\i -> (show i, [i`div`2..i-1])) Data.Tree> putStr . drawTree $ t 8 -- Live well, ~wren From wren at freegeek.org Wed Jun 10 20:23:08 2009 From: wren at freegeek.org (wren ng thornton) Date: Wed Jun 10 20:06:43 2009 Subject: [Haskell-cafe] Building a tree? In-Reply-To: <565459.78504.qm@web31105.mail.mud.yahoo.com> References: <565459.78504.qm@web31105.mail.mud.yahoo.com> Message-ID: <4A304E6C.6010207@freegeek.org> michael rice wrote: > Here's a function from Data.Tree: > > unfoldTree :: (b -> (a, [b])) -> b -> Tree a > Build a tree from a seed value > > Could someone please give me a brief example of usage. In as far as understanding it, it may be easier if you look at the generalized version of the anamorphism: newtype Fix f = Fix { unFix :: f (Fix f) } type Tree a = Fix (Node a) data Node a b = Node a [b] instance Functor (Node a) where fmap f (Node a bs) = Node a (map f bs) unfoldTree f = Fix . fmap (unfoldTree f) . f -- Live well, ~wren From niklas.broberg at gmail.com Wed Jun 10 20:29:18 2009 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Wed Jun 10 20:12:54 2009 Subject: [Haskell-cafe] Re: FlexibleContexts and FlexibleInstances In-Reply-To: References: Message-ID: Hi Claus, What you describe is exactly how I would *want* things to work. It's nice to hear my wishes echoed from a user perspective. :-) On Wed, Jun 10, 2009 at 4:43 PM, Claus Reinke wrote: > just a few comments from a user (who would really, really, like to be > able to define pragma collections, so that he doesn't have to switch > on half a dozen separate extensions every time;-). > >> The following toy program requires MultiParamTypeClasses OR >> FlexibleContexts in order to be accepted by GHC(i): >> >>> f :: (T a b) => a -> Int >>> f _ = 0 >> >> This of course assumes that we import the definition of T, we *must* >> have MultiParamTypeClasses enabled if we want to declare T. Both >> extensions thus enable classes with more than one argument to appear >> in contexts. > > Only MultiParamTypeClasses does (and neither extension is needed in the > module defining 'f', if 'T' is imported, which suggests that > MultiParamTypeClasses is propagated to importers - this isn't true for > most other extensions). The documentation still points to -fglasgow-exts, so > it doesn't seem to answer these questions.. Right you are - which seems very strange to me. GHC accepts the module defining 'f' with no flags at all, even though it is clearly not Haskell 98. I'd go so far as to say that's a bug (as opposed to just unwanted/unexpected behavior). >>> f :: (T a ()) => a -> Int >>> f _ = 0 >> >> i.e. changing the second argument to T to () instead, means we now >> *must* have FlexibleInstances, in order to allow the non-tyvar >> argument. This is nothing surprising, this is what FlexibleInstances >> are supposed to do. > > You mean FlexibleContexts. Indeed I do. >> Now, FlexibleInstances *also* lifts the restriction on contexts, just >> like FlexibleContexts - but *only* for the contexts of instance >> declarations. > > No. FlexibleInstances is about instance *heads*, FlexibleContexts is about > contexts everywhere (in practice, there are some bugs;-). Right, this is exactly what I *want* should happen, both as a user and as an implementor, but that's not how GHC does it. FlexibleInstances do enable FlexibleContexts for contexts in instance declarations - which I think is a wart. > ? class T a b -- requires MultiParamTypeClasses ? instance T a a -- requires > FlexibleInstances ? instance Eq () => T a [b] -- requires FlexibleContexts > instance Eq [a] => T a b -- requires UndecidableInstances Agreed - but here you avoid the tricky cases like my 'f' above. ;-) What I would want, and what I believe you want as well, is the following: ======================================== ** MultiParamTypeClasses: Enables more than one parameter in class declarations, instance heads and more than one argument to class assertions in contexts everywhere. Formally, it would mean the following changes to the Haskell 98 syntax: topdecl -> class [scontext =>] tycls tyvar1 ... tyvarn [where cdecls] (n >=1) | instance [scontext =>] qtycls inst1 ... instn [where idecls] (n >=1) context -> class | ( class1 , ... , classn ) (n>=0) class -> qtycls cls1 ... clsn (n>=1) cls -> tyvar | ( tyvar atype1 ... atypen ) (n>=1) scontext -> simpleclass | ( simpleclass1 , ... , simpleclassn ) (n>=0) simpleclass -> qtycls scls1 ... sclsn (n>=1) scls -> tyvar ** FlexibleContexts: Enables the use of non-tyvar (or tyvar applied to types) arguments to class assertions in contexts everywhere (orthogonal to whether there can be several arguments or just one). Formally it means the following syntactic changes to Haskell 98: fcontext -> fclass | ( fclass1 , ... , fclassn ) (n>=0) fclass -> qtycls atype1 ... atypen (n>=1) topdecl -> data [fcontext =>] simpletype = constrs [deriving] | newtype [fcontext =>] simpletype = newconstr [deriving] | class [fcontext =>] tycls tyvar [where cdecls] | instance [fcontext =>] qtycls inst [where idecls] gendecl -> vars :: [fcontext =>] type for the single-argument case. (Note that I wrote type in my proposal in the OP, but it should of course be atype.) ** FlexibleInstances: Enables the use of arguments other than type constructors (possibly applied to tyvars) in instances *heads* (orthogonal to whether there can be one or more arguments, and what the context may look like). Formally it means the following syntactic changes to Haskell 98: topdecl -> instance [scontext =>] qtycls inst [where idecls] inst -> atype for the single-parameter standard-context case. (Note again that it should be atype and not type as I wrote in the OP.) ======================================== This of course only touches the syntactic part. It doesn't attempt to track things like 'instance (T a a) => R a b' that would be enabled by FlexibleContexts, nor does it attempt to track things like the Paterson conditions, but the syntax is all I'm interested in at the moment. This is the stance I will use for haskell-src-exts, unless someone protests wildly. If there is any interest, I can also propose these cases as bug reports to GHC. I hesitate to make formal proposals (e.g. for Haskell') regarding these extensions since I'm not sure I have the full story regarding the non-syntactic parts. But if there is a particular interest in that then I might go the extra mile there too. Cheers, /Niklas From vigalchin at gmail.com Wed Jun 10 21:22:23 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Wed Jun 10 21:05:57 2009 Subject: [Haskell-cafe] a cool paper (.pdf) on Cabal? Message-ID: <5ae4f2ba0906101822t41ce0c2dic17d41f9636acdb6@mail.gmail.com> Hello, Before I found a really cool paper on Cabal motivation and architecture. I can no longer find this paper. Any ideas/suggestions? Kind regards, Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090610/d7712406/attachment.html From ryani.spam at gmail.com Wed Jun 10 23:01:07 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Wed Jun 10 22:44:42 2009 Subject: [Haskell-cafe] Lightweight type-level dependent programming in Haskell Message-ID: <2f9b2d30906102001l502a8920oc864bfc4d5db7f9@mail.gmail.com> (Literate Haskell post) > {-# LANGUAGE GADTs, RankNTypes, TypeFamilies, ScopedTypeVariables, FlexibleContexts #-} > module Dependent where I recently discovered an interesting way of closing typeclasses while playing with type-level peano naturals: First we build peano integers at the type level: > data Z = Z > newtype S n = S n And a couple of generally useful type-level combinators: > newtype I x = I { unI :: x } > newtype K x y = K { unK :: x } (We could also include the S combinator, under a different name, but I haven't needed it yet...) This representation isn't "closed"; there's nothing forcing the "n" in S n to be Z or S n. But we can make a typeclass easily: class Nat n instance Nat Z where ... instance Nat n => Nat (S n) where ... But again, this typeclass is open. What I recently realized is that it's easy to close the typeclass by requiring instances to provide a simple implementation of "typecase": > class Nat n where > caseNat :: forall r. n -> (n ~ Z => r) -> (forall p. (n ~ S p, Nat p) => p -> r) -> r By parametricity, any non _|_ implementation of caseNat has to prove either (n ~ Z), to call the first branch, or (n ~ S p) for some other natural p, to call the second. > instance Nat Z where > caseNat _ z _ = z > instance Nat n => Nat (S n) where > caseNat (S n) _ s = s n (Interesting side note: the S n pattern match is automatically lazy, since S is a newtype) Somewhat surprisingly, caseNat is sufficient to prove *dependent* induction: > induction :: forall p n. Nat n => n -> p Z -> (forall x. Nat x => p x -> p (S x)) -> p n > induction n z s = caseNat n isZ isS where > isZ :: n ~ Z => p n > isZ = z > isS :: forall x. (n ~ S x, Nat x) => x -> p n > isS x = s (induction x z s) What does this function mean? Through the Curry-Howard lens, it says: If we have a proof of P 0, and a proof of (P x -> P (x+1)) for any natural x, then we can prove P n for any natural n! The proof simply proceeds by case analysis on n; we know that the proof terminates since the recursive step works at a strictly smaller type, and Haskell types are all finite in size. Now, of course, this isn't any different from case analysis on this GADT: > data Peano a where > Pz :: Peano Z > Ps :: Peano n -> Peano (S n) > inductP :: forall n p. Peano n -> p Z -> (forall x. Peano x -> p x -> p (S x)) -> p n > inductP Pz z s = z > inductP (Ps n) z s = s n (inductP n z s) In fact, the whole point of GADT case analysis is to introduce the type-level coercions that caseNat makes explicit. So there's not a huge gain here. There is one interesting benefit that the typeclass answer gives you, however; you can let the compiler derive the proof for you: > witnessNat :: forall n. Nat n => n > witnessNat = theWitness where > theWitness = unI $ induction (undefined `asTypeOf` theWitness) (I Z) (I . S . unI) Then we can optimize the implementation of witness to "unsafeCoerce Z" after the typechecker agrees with our proof. Another useful tool is existentials and witnesses; existentials allow you to do value-level calculation on "Nat"; witnesses allow you to construct a proof of Nat n and return it from a proof; there's no other way to return that something is a member of a typeclass. > data AnyNat where AnyNat :: Nat n => n -> AnyNat > data IsNat n where IsNat :: Nat n => IsNat n > mkNat :: Integer -> AnyNat > mkNat x | x < 0 = error "Nat must be >= 0" > mkNat 0 = AnyNat Z > mkNat x = case (mkNat (x-1)) of (AnyNat n) -> AnyNat (S n) > natToInteger :: Nat n => n -> Integer > natToInteger n = unK $ induction n (K 0) (K . (+1) . unK) > prec_app = 11 > instance Show AnyNat where > showsPrec p (AnyNat n) = showParen (p > prec_app) (showString "mkNat " . shows (natToInteger n)) Fun exercises: > data TEq a b where TEq :: (a ~ b) => TEq a b 1) Write a sized list GADT, and build some lists using combinators on Nat. Here's an example: myReplicate a = induction witnessNat Nil (Cons a) For me, ghc correctly infers this function to have the type myReplicate :: (Nat n) => a -> List a n. It's nice that I don't have to specify n anywhere! Try implementing fold :: Nat n => (forall x. Nat x => a -> p x -> p (S x)) -> List a n -> p n 2) (Easy) Prove that all sized lists have a length that is a natural number: lengthIsNat :: SizedList a n -> IsNat n 3) Prove that equality is decidable on naturals: natEqDec :: forall x y. (Nat x, Nat y) => x -> y -> Maybe (TEq x y) 4) Write the standard "plus" type family, then prove: plusIsNat :: forall x y. (Nat x, Nat y) => IsNat (Plus x y) plusIsComm :: forall x y. (Nat x, Nat y) => TEq (Plus x y) (Plus y x) (While doing this exercise, I was impressed at how good the type coercion prover is) 5) (Challenge) Write definitions for "instance Eq AnyNat" and "instance Num AnyNat" From evan at eklitzke.org Thu Jun 11 00:40:56 2009 From: evan at eklitzke.org (Evan Klitzke) Date: Thu Jun 11 00:24:29 2009 Subject: [Haskell-cafe] Debugging misbehaving multi-threaded programs Message-ID: I've written a multi-threaded Haskell program that I'm trying to debug. Basically what's happening is the program runs for a while, and then at some point one of the threads goes crazy and spins the CPU while allocating memory; this proceeds until the system runs out of available memory. I can't fix this without figuring out what code is being executed in the loop (or at least which thread is misbehaving, which would narrow things down a lot). I was hopeful that I could compile the program with profiling support and then use +RTS -M100M along with some of the RTS profiling options and get profiling information on CPU and memory usage at the time that my program runs out of memory. The thinking here is that nearly all of the CPU time and heap space will be from the misbehaving thread, so at that point I could do more investigation into exactly what is happening. Unfortunately, this doesn't seem to work; whenever the program terminates due to running out of heap space, the generated .prof file is empty. Another strategy I tried was running the program in ghci and use -fbreak-on-exception and :trace; by hitting Ctrl-C I was hopeful I'd stop the program in whatever is looping (this is all described and suggested in the ghc docs). Unfortunately, this also didn't seem to work, because the Ctrl-C only stops the main thread. Does anyone have any tips for dealing this? Have other people run into similar problems? I'm out of ideas, so I'm open to any suggestions. -- Evan Klitzke :wq From miguelimo38 at yandex.ru Thu Jun 11 00:45:02 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Thu Jun 11 00:28:45 2009 Subject: [Haskell-cafe] Lightweight type-level dependent programming in Haskell In-Reply-To: <2f9b2d30906102001l502a8920oc864bfc4d5db7f9@mail.gmail.com> References: <2f9b2d30906102001l502a8920oc864bfc4d5db7f9@mail.gmail.com> Message-ID: <46483C38-0661-4A6E-86D7-C716D97B6B6B@yandex.ru> > I recently discovered an interesting way of closing typeclasses while > playing with type-level peano naturals: >> class Nat n where >> caseNat :: forall r. n -> (n ~ Z => r) -> (forall p. (n ~ S p, >> Nat p) => p -> r) -> r I usually use this one: class Nat n where caseNat :: p Z -> (forall m. Nat m => p (S m)) -> p n instance Nat Z where caseNat pz _ = pz instance Nat n => Nat (S n) where caseNat _ psm = psm From DekuDekuplex at Yahoo.com Thu Jun 11 00:48:27 2009 From: DekuDekuplex at Yahoo.com (Benjamin L.Russell) Date: Thu Jun 11 00:32:13 2009 Subject: [Haskell-cafe] Re: a cool paper (.pdf) on Cabal? References: <5ae4f2ba0906101822t41ce0c2dic17d41f9636acdb6@mail.gmail.com> Message-ID: On Wed, 10 Jun 2009 20:22:23 -0500, "Vasili I. Galchin" wrote: >Hello, > > Before I found a really cool paper on Cabal motivation and architecture. >I can no longer find this paper. Any ideas/suggestions? Is this what you are looking for? The Haskell Cabal: A Common Architecture for Building Applications and Tools by Isaac Jones, Simon Peyton Jones, Simon Marlow, Malcolm Wallace, and Ross Patterson http://www.haskell.org/cabal/proposal/ -- Benjamin L. Russell -- Benjamin L. Russell / DekuDekuplex at Yahoo dot com http://dekudekuplex.wordpress.com/ Translator/Interpreter / Mobile: +011 81 80-3603-6725 "Furuike ya, kawazu tobikomu mizu no oto." -- Matsuo Basho^ From DekuDekuplex at Yahoo.com Thu Jun 11 00:57:47 2009 From: DekuDekuplex at Yahoo.com (Benjamin L.Russell) Date: Thu Jun 11 00:41:36 2009 Subject: [Haskell-cafe] Re: a cool paper (.pdf) on Cabal? References: <5ae4f2ba0906101822t41ce0c2dic17d41f9636acdb6@mail.gmail.com> Message-ID: On Thu, 11 Jun 2009 13:48:27 +0900, Benjamin L.Russell wrote: >On Wed, 10 Jun 2009 20:22:23 -0500, "Vasili I. Galchin" > wrote: > >>Hello, >> >> Before I found a really cool paper on Cabal motivation and architecture. >>I can no longer find this paper. Any ideas/suggestions? > >Is this what you are looking for? > >The Haskell Cabal: A Common Architecture for Building Applications and >Tools >by Isaac Jones, Simon Peyton Jones, Simon Marlow, Malcolm Wallace, and >Ross Patterson >http://www.haskell.org/cabal/proposal/ Sorry, I forgot that you had specified a .pdf paper in the title. Then perhaps the following paper is what you are really looking for: Haskell: Batteries Included by Duncan Coutts, Isaac Potoczny-Jones, and Don Stewart http://www.cse.unsw.edu.au/~dons/papers/haskell31-coutts.pdf -- Benjamin L. Russell -- Benjamin L. Russell / DekuDekuplex at Yahoo dot com http://dekudekuplex.wordpress.com/ Translator/Interpreter / Mobile: +011 81 80-3603-6725 "Furuike ya, kawazu tobikomu mizu no oto." -- Matsuo Basho^ From moonpatio at gmail.com Thu Jun 11 03:00:42 2009 From: moonpatio at gmail.com (Matt Morrow) Date: Thu Jun 11 02:44:18 2009 Subject: [Haskell-cafe] Lightweight type-level dependent programming in Haskell In-Reply-To: <2f9b2d30906102001l502a8920oc864bfc4d5db7f9@mail.gmail.com> References: <2f9b2d30906102001l502a8920oc864bfc4d5db7f9@mail.gmail.com> Message-ID: <1bc51a990906110000s1af9812aq48db4f241469ef89@mail.gmail.com> I like this one: ----------------------------------------------------------------------------- data N a where Z :: N () N :: N a -> N (N a) type family Nest n (f :: * -> *) a nest :: N n -> (forall a. a -> f a) -> a -> Nest n f a type instance Nest () f a = f a nest Z f a = f a nest (N n) f a = f (nest n f a) type instance Nest (N n) f a = f (Nest n f a) ----------------------------------------------------------------------------- import Language.Haskell.TH.Lib(ExpQ) {- ghci> nest $(nat 18) (:[]) 42 [[[[[[[[[[[[[[[[[[[42]]]]]]]]]]]]]]]]]]] -} -- ghci> toInt $(nat 1000) -- 1000 toInt :: N a -> Int toInt = go 0 where go :: Int -> N a -> Int go n Z = n go n (N a) = go (n+1) a -- TH, since no dep types nat :: Int -> ExpQ nat n | n < 1 = [|Z|] | otherwise = [|N $(nat (n-1))|] instance Show (N a) where showsPrec _ Z = showString "Z" showsPrec p (N x_1) = showParen (p > 10) (showString "N" . (showChar ' ' . (showsPrec 11 x_1 . id))) ----------------------------------------------------------------------------- -- :( {- ghci> nest $(nat 19) (:[]) 42 Top level: Context reduction stack overflow; size = 20 Use -fcontext-stack=N to increase stack size to N `$dShow{a1Wy} :: {Show [t_a1U3]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wx} :: {Show [[t_a1U3]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Ww} :: {Show [[[t_a1U3]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wv} :: {Show [[[[t_a1U3]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wu} :: {Show [[[[[t_a1U3]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wt} :: {Show [[[[[[t_a1U3]]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Ws} :: {Show [[[[[[[t_a1U3]]]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wr} :: {Show [[[[[[[[t_a1U3]]]]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wq} :: {Show [[[[[[[[[t_a1U3]]]]]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wp} :: {Show [[[[[[[[[[t_a1U3]]]]]]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wo} :: {Show [[[[[[[[[[[t_a1U3]]]]]]]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wn} :: {Show [[[[[[[[[[[[t_a1U3]]]]]]]]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wm} :: {Show [[[[[[[[[[[[[t_a1U3]]]]]]]]]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wl} :: {Show [[[[[[[[[[[[[[t_a1U3]]]]]]]]]]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wk} :: {Show [[[[[[[[[[[[[[[t_a1U3]]]]]]]]]]]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wj} :: {Show [[[[[[[[[[[[[[[[t_a1U3]]]]]]]]]]]]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wi} :: {Show [[[[[[[[[[[[[[[[[t_a1U3]]]]]]]]]]]]]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wh} :: {Show [[[[[[[[[[[[[[[[[[t_a1U3]]]]]]]]]]]]]]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Wg} :: {Show [[[[[[[[[[[[[[[[[[[t_a1U3]]]]]]]]]]]]]]]]]]]}' arising from a use of `print' at :1:0-22 `$dShow{a1Um} :: {Show [[[[[[[[[[[[[[[[[[[[t_a1U3]]]]]]]]]]]]]]]]]]]]}' arising from a use of `print' at :1:0-22 -} ----------------------------------------------------------------------------- Also, Dan Doel wrote an Agda version of `nest' which eliminates the duplication, but interestingly requires '--type-in-type': http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2429 Matt On Wed, Jun 10, 2009 at 10:01 PM, Ryan Ingram wrote: > > induction :: forall p n. Nat n => n -> p Z -> (forall x. Nat x => p x -> > p (S x)) -> p n > > induction n z s = caseNat n isZ isS where > > isZ :: n ~ Z => p n > > isZ = z > > isS :: forall x. (n ~ S x, Nat x) => x -> p n > > isS x = s (induction x z s) > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090611/0e881229/attachment.html From noteed at gmail.com Thu Jun 11 03:11:52 2009 From: noteed at gmail.com (minh thu) Date: Thu Jun 11 02:55:47 2009 Subject: [Haskell-cafe] Re: [Haskell] ANNOUNCE: testrunner-0.9 In-Reply-To: <20090610161453.6461ed82@jabber.aur.us.ray.com> References: <200906081224.36779.tux_rocker@reinier.de> <9d4d38820906080603x9acf62dm32474012c451981a@mail.gmail.com> <200906081546.13437.tux_rocker@reinier.de> <9d4d38820906081107h4d379959v2be0af1dd56abac1@mail.gmail.com> <20090610161453.6461ed82@jabber.aur.us.ray.com> Message-ID: <40a414c20906110011k388b4956ifb515da951e8dd30@mail.gmail.com> Hi, Have a look at http://projects.haskell.org/testrunner/using-testrunner.html, specifically the last paragraph. Also, http://batterseapower.github.com/test-framework/ says results are reported in deterministic order... Cheers, Thu 2009/6/11 Rodney Price : > When I run Example.lhs for test-framework I get > > [0] > [1] > > in the test results, just as you show on your web page. If I run > Example.lhs under ghci rather than compiled, I find the [0] [1] mingled > with the test results in random ways. This leads me to believe that > whatever is printing out [0] [1] is running is a separate thread. > > Does this [0] [1] have any meaning? If not, how do I get rid of it? > > Thanks, > -Rod > > > > On Mon, 8 Jun 2009 19:07:52 +0100 > Max Bolingbroke wrote: > >> 2009/6/8 Reinier Lamers : >> > I checked out testpack and that did not meet my requirements. I >> > don't know if I considered test-framework. If I did, it may be that >> > I was turned off by the fact that the 'home page' link on cabal >> > just goes to a web presentation of the source tree on github. >> >> Reinier, >> >> You are quite right that this is a weakness. I've been meaning to put >> a site together for a while, and your comment gave me the impetus to >> do it: >> >> http://batterseapower.github.com/test-framework/ >> >> That's much friendlier! >> >> All the best, >> Max >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> >> The following line is added for your protection and will be used for >> analysis if this message is reported as spam: >> >> (Raytheon Analysis: IP=128.36.229.215; >> e-from=haskell-cafe-bounces@haskell.org; >> from=batterseapower@hotmail.com; date=Jun 8, 2009 6:08:07 PM; >> subject=[Haskell-cafe] Re: [Haskell] ANNOUNCE: testrunner-0.9) > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From dons at galois.com Thu Jun 11 03:15:41 2009 From: dons at galois.com (Don Stewart) Date: Thu Jun 11 03:01:04 2009 Subject: [Haskell-cafe] ANNOUNCE: Galois is hiring functional programmers Message-ID: <20090611071541.GA12524@whirlpool.galois.com> Galois is hiring. Bringing together mathematicians, researchers and technologists, Galois, based in Portland, Oregon, was founded in 1999 with the mission to apply functional languages and formal methods to solve real world problems. Today, over 30 members strong, we?re living the vision, designing and developing advanced technologies for safety and security-critical systems, networks, and applications. Galois technical staff members play a pivotal role in developing advanced software technology. Members work on one or more projects, and are expected to perform in a variety of roles based upon their talents and organizational needs. Technical staff may be called upon to write proposals, gather requirements, and work in all stages of the software development process, from requirements gathering to testing and validation. Additional duties may include project management, technology research and development, and technical infrastructure development. We?re looking for people who can invent, learn, think, and inspire. We reward creativity and thrive on collaboration. We offer great benefits and perks, including a 401K plan, stock options, paid vacation, family health plan, flexible work schedule, a casual work environment, snacks, espresso and foosball. Galois technical staff members usually work in a small team setting (2-5 members), and must successfully interact with clients, partners, and other employees in a highly cooperative, collaborative, and intellectually challenging environment. A Masters or Ph.D. degree in Computer Science is desirable but not required. Additionally, a strong programming background and experience with Haskell or other functional programming languages is preferred but not required. Must work well with customers, including building rapport, identifying needs, and communicating with strong written, verbal and presentation skills. Must be highly motivated and able to self-manage to deadlines and quality goals. To learn more about us, visit http://www.galois.com and http://www.galois.com/company/careers The types of technology we use are covered in our blog: http://www.galois.com/blog/ We?d like to hear from you! Send your cover letter and resume to us at jobs2009@galois.com. From batterseapower at hotmail.com Thu Jun 11 03:27:34 2009 From: batterseapower at hotmail.com (Max Bolingbroke) Date: Thu Jun 11 03:11:13 2009 Subject: [Haskell-cafe] Re: [Haskell] ANNOUNCE: testrunner-0.9 In-Reply-To: <20090610161453.6461ed82@jabber.aur.us.ray.com> References: <200906081224.36779.tux_rocker@reinier.de> <9d4d38820906080603x9acf62dm32474012c451981a@mail.gmail.com> <200906081546.13437.tux_rocker@reinier.de> <9d4d38820906081107h4d379959v2be0af1dd56abac1@mail.gmail.com> <20090610161453.6461ed82@jabber.aur.us.ray.com> Message-ID: <9d4d38820906110027w343fbebdi113f08f501952ad8@mail.gmail.com> Hi Rodney, The [0], [1] is a demonstration of failing arguments to QuickCheck. Now, generally test-framework is very careful to avoid printing from anything other than the main thread. That being said there is a known problem with the QuickCheck-2 provider that will cause it to print the failing arguments from the background thread. This is due to a technical limitation with the library (it insists on writing to stdout, so this is the best I could do without copying most of the code). QuickCheck-1 /shouldn't/ (to the best of my knowledge) have this problem, though. Is that what you were using? If so I'll investigate further. Cheers, Max 2009/6/10 Rodney Price : > When I run Example.lhs for test-framework I get > > [0] > [1] > > in the test results, just as you show on your web page. ?If I run > Example.lhs under ghci rather than compiled, I find the [0] [1] mingled > with the test results in random ways. ?This leads me to believe that > whatever is printing out [0] [1] is running is a separate thread. > > Does this [0] [1] have any meaning? ?If not, how do I get rid of it? > > Thanks, > -Rod > > > > On Mon, 8 Jun 2009 19:07:52 +0100 > Max Bolingbroke wrote: > >> 2009/6/8 Reinier Lamers : >> > I checked out testpack and that did not meet my requirements. I >> > don't know if I considered test-framework. If I did, it may be that >> > I was turned off by the fact that the 'home page' link on cabal >> > just goes to a web presentation of the source tree on github. >> >> Reinier, >> >> You are quite right that this is a weakness. I've been meaning to put >> a site together for a while, and your comment gave me the impetus to >> do it: >> >> http://batterseapower.github.com/test-framework/ >> >> That's much friendlier! >> >> All the best, >> Max >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> >> The following line is added for your protection and will be used for >> analysis if this message is reported as spam: >> >> (Raytheon Analysis: IP=128.36.229.215; >> e-from=haskell-cafe-bounces@haskell.org; >> from=batterseapower@hotmail.com; date=Jun 8, 2009 6:08:07 PM; >> subject=[Haskell-cafe] Re: [Haskell] ANNOUNCE: testrunner-0.9) > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From ketil at malde.org Thu Jun 11 03:40:42 2009 From: ketil at malde.org (Ketil Malde) Date: Thu Jun 11 03:25:11 2009 Subject: [Haskell-cafe] Debugging misbehaving multi-threaded programs In-Reply-To: (Evan Klitzke's message of "Wed\, 10 Jun 2009 21\:40\:56 -0700") References: Message-ID: <87fxe7fcat.fsf@malde.org> Evan Klitzke writes: > [...] Unfortunately, this doesn't seem to work; whenever the > program terminates due to running out of heap space, the generated > .prof file is empty. Unless there's some specific problem with profiling in combination with threading, you can get heap profiling from a crashing program. Not what you wanted, but you might at least be able to see what is allocated. Previously, you'd have to edit the profiling output (.hp file) by hand to chop off the last and partial profiling record, but I think this might have been fixed in later GHC's. -k -- If I haven't seen further, it is by standing in the footprints of giants From ketil at malde.org Thu Jun 11 04:30:45 2009 From: ketil at malde.org (Ketil Malde) Date: Thu Jun 11 04:13:53 2009 Subject: [Haskell-cafe] Software Transactional Memory and LWN Message-ID: <87ab4ff9ze.fsf@malde.org> Hi, Browsing LWN, I ran across this comment: http://lwn.net/Articles/336039/ The author makes a bunch of unsubstantiated claims about STM, namely that all implementations use locking under the hood, and that STM can live- and deadlock. I've seen a lot of similar sentiments in other places as well (comp.arch springs to mind). Now, I'm no expert on STM, but I was pretty sure these are incorrect, and I certainly had the impression that Haskell's STM guarantees some progress - which it couldn't in a deadlock situation. Am I wrong? -k -- If I haven't seen further, it is by standing in the footprints of giants From lrpalmer at gmail.com Thu Jun 11 04:35:33 2009 From: lrpalmer at gmail.com (Luke Palmer) Date: Thu Jun 11 04:19:09 2009 Subject: [Haskell-cafe] Software Transactional Memory and LWN In-Reply-To: <87ab4ff9ze.fsf@malde.org> References: <87ab4ff9ze.fsf@malde.org> Message-ID: <7ca3f0160906110135q1a99644ev7ae22e7fcb5bc72c@mail.gmail.com> On Thu, Jun 11, 2009 at 2:30 AM, Ketil Malde wrote: > > Hi, > > Browsing LWN, I ran across this comment: > > http://lwn.net/Articles/336039/ > > The author makes a bunch of unsubstantiated claims about STM, namely > that all implementations use locking under the hood, and that STM can > live- and deadlock. I've seen a lot of similar sentiments in other > places as well (comp.arch springs to mind). > > Now, I'm no expert on STM, but I was pretty sure these are incorrect, > and I certainly had the impression that Haskell's STM guarantees some > progress - which it couldn't in a deadlock situation. MVars can be simulated with STM, and MVars can semantically get in a deadlock situation, so STM can also deadlock. Admittedly, if you're using STM to simulate MVars, you're doing it wrong. Luke -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090611/fee66019/attachment.html From claus.reinke at talk21.com Thu Jun 11 04:43:09 2009 From: claus.reinke at talk21.com (Claus Reinke) Date: Thu Jun 11 04:26:47 2009 Subject: [Haskell-cafe] Debugging misbehaving multi-threaded programs References: Message-ID: > I've written a multi-threaded Haskell program that I'm trying to > debug. Basically what's happening is the program runs for a while, and > then at some point one of the threads goes crazy and spins the CPU > while allocating memory; this proceeds until the system runs out of > available memory. I can't fix this without figuring out what code is > being executed in the loop (or at least which thread is misbehaving, > which would narrow things down a lot). >.. > Does anyone have any tips for dealing this? Have other people run into > similar problems? I'm out of ideas, so I'm open to any suggestions. Don't know whether this still works, but there was a Concurrent Haskell Debugger here: http://www.informatik.uni-kiel.de/~fhu/chd/ The idea being that you put an indirection module between your code and the Concurrent Haskell imports, and then instrument the indirections to give you more information (they had built more tools on top of that idea). In a similar direction, I once suggested a shell-jobs-like thread interface for GHCi, in the context of this _|_-ed ticket: http://hackage.haskell.org/trac/ghc/ticket/1399#comment:3 Claus From nccb2 at kent.ac.uk Thu Jun 11 06:40:31 2009 From: nccb2 at kent.ac.uk (Neil Brown) Date: Thu Jun 11 06:24:01 2009 Subject: [Haskell-cafe] Software Transactional Memory and LWN In-Reply-To: <87ab4ff9ze.fsf@malde.org> References: <87ab4ff9ze.fsf@malde.org> Message-ID: <4A30DF1F.7050400@kent.ac.uk> Ketil Malde wrote: > Hi, > > Browsing LWN, I ran across this comment: > > http://lwn.net/Articles/336039/ > > The author makes a bunch of unsubstantiated claims about STM, namely > that all implementations use locking under the hood, and that STM can > live- and deadlock. I've seen a lot of similar sentiments in other > places as well (comp.arch springs to mind). > > Now, I'm no expert on STM, but I was pretty sure these are incorrect, > and I certainly had the impression that Haskell's STM guarantees some > progress - which it couldn't in a deadlock situation. > I think there needs to be some differentiation here between the implementation of STM, and the programmer's use of STM. The implementation of STM does effectively use locks (from memory, it's this paper that explains it: http://research.microsoft.com/en-us/um/people/tharris/papers/2007-tocs.pdf). I'm not sure how optimistic algorithms work, so maybe they can usually avoid locks -- but I suspect there are cases in every STM algorithm where locks are needed as a last resort. The implementation of STM cannot deadlock. There will always be at least one process making progress, but potentially at the expense of starving others indefinitely (a form of livelock). So the implementation has locks, can't deadlock, can sort of livelock. The use of STM does not involve locks, and one of STM's main advantages is that it hides explicit locks from the user. If you have retry in STM (as Haskell does, but not all other implementations do) then you can write deadlocking code with it, and indeed you can simulate mutexes and so on using retry, hence allowing you to use your own constructed locks with STM. So in using STM you can deadlock, and you can make some locks to use if you want, but it's not required. Neil. From tom.davie at gmail.com Thu Jun 11 06:46:06 2009 From: tom.davie at gmail.com (Thomas Davie) Date: Thu Jun 11 06:29:42 2009 Subject: [Haskell-cafe] Logo fun Message-ID: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> We had a lot of "fun" deciding Haskell's new logo, and while I don't agree with the final result, it would be nice if we could now start consistently using it. With that in mind, I realised that the Haskell Platform's logo is totally different, and did a quick mock up of a version reflecting the current Haskell logo. It needs someone with the original vector graphics to have a play and improve it a little bit, but hopefully you'll se a concept you like. Here's the logo, continuing on the batteries included theme: http://www.cs.kent.ac.uk/people/rpg/tatd2/HaskellBatteries.png I'd appreciate comments, suggestions, and possibly either access to the vector version of our current logo, or someone producing a nice version of this. Bob From duncan.coutts at worc.ox.ac.uk Thu Jun 11 07:09:10 2009 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Thu Jun 11 06:53:58 2009 Subject: [Haskell-cafe] Re: a cool paper (.pdf) on Cabal? In-Reply-To: References: <5ae4f2ba0906101822t41ce0c2dic17d41f9636acdb6@mail.gmail.com> Message-ID: <1244718550.26313.106.camel@localhost> On Thu, 2009-06-11 at 13:57 +0900, Benjamin L.Russell wrote: > On Thu, 11 Jun 2009 13:48:27 +0900, Benjamin L.Russell > wrote: > > >On Wed, 10 Jun 2009 20:22:23 -0500, "Vasili I. Galchin" > > wrote: > > > >>Hello, > >> > >> Before I found a really cool paper on Cabal motivation and architecture. > >>I can no longer find this paper. Any ideas/suggestions? > > > >Is this what you are looking for? > > > >The Haskell Cabal: A Common Architecture for Building Applications and > >Tools > >by Isaac Jones, Simon Peyton Jones, Simon Marlow, Malcolm Wallace, and > >Ross Patterson > >http://www.haskell.org/cabal/proposal/ > > Sorry, I forgot that you had specified a .pdf paper in the title. There's a pdf of the same: http://www.haskell.org/cabal/proposal/pkg-spec.pdf > Then perhaps the following paper is what you are really looking for: > > Haskell: Batteries Included > by Duncan Coutts, Isaac Potoczny-Jones, and Don Stewart > http://www.cse.unsw.edu.au/~dons/papers/haskell31-coutts.pdf And that paper refers to the earlier one by Isaac: http://www.cs.ioc.ee/tfp-icfp-gpce05/tfp-proc/24num.pdf I've linked these from the page on old Cabal stuff: http://www.haskell.org/cabal/old.html Duncan From deniz.a.m.dogan at gmail.com Thu Jun 11 07:20:16 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Thu Jun 11 07:03:50 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> Message-ID: <7b501d5c0906110420l1d5b842bu3103a7855973ac1f@mail.gmail.com> 2009/6/11 Thomas Davie : > We had a lot of "fun" deciding Haskell's new logo, and while I don't agree > with the final result, it would be nice if we could now start consistently > using it. ?With that in mind, I realised that the Haskell Platform's logo is > totally different, and did a quick mock up of a version reflecting the > current Haskell logo. ?It needs someone with the original vector graphics to > have a play and improve it a little bit, but hopefully you'll se a concept > you like. > > Here's the logo, continuing on the batteries included theme: > http://www.cs.kent.ac.uk/people/rpg/tatd2/HaskellBatteries.png > > I'd appreciate comments, suggestions, and possibly either access to the > vector version of our current logo, or someone producing a nice version of > this. > > Bob I love this suggestion! Maybe we should make the batteries look more battery-ish though. I think that especially the minus sign is a bit unclear, so maybe we could make the signs heavier? -- Deniz Dogan From ekirpichov at gmail.com Thu Jun 11 07:22:39 2009 From: ekirpichov at gmail.com (Eugene Kirpichov) Date: Thu Jun 11 07:06:13 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <7b501d5c0906110420l1d5b842bu3103a7855973ac1f@mail.gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <7b501d5c0906110420l1d5b842bu3103a7855973ac1f@mail.gmail.com> Message-ID: <5e0214850906110422v6528df4cg810d0aacecdd1fce@mail.gmail.com> The idea is pretty cool, but at first sight the batteries look like a graphical glitch. Probably some antialiasing or smoothening is needed.. 2009/6/11 Deniz Dogan : > 2009/6/11 Thomas Davie : >> We had a lot of "fun" deciding Haskell's new logo, and while I don't agree >> with the final result, it would be nice if we could now start consistently >> using it. ?With that in mind, I realised that the Haskell Platform's logo is >> totally different, and did a quick mock up of a version reflecting the >> current Haskell logo. ?It needs someone with the original vector graphics to >> have a play and improve it a little bit, but hopefully you'll se a concept >> you like. >> >> Here's the logo, continuing on the batteries included theme: >> http://www.cs.kent.ac.uk/people/rpg/tatd2/HaskellBatteries.png >> >> I'd appreciate comments, suggestions, and possibly either access to the >> vector version of our current logo, or someone producing a nice version of >> this. >> >> Bob > > I love this suggestion! Maybe we should make the batteries look more > battery-ish though. I think that especially the minus sign is a bit > unclear, so maybe we could make the signs heavier? > > -- > Deniz Dogan > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- Eugene Kirpichov Web IR developer, market.yandex.ru From ketil at malde.org Thu Jun 11 07:38:39 2009 From: ketil at malde.org (Ketil Malde) Date: Thu Jun 11 07:21:46 2009 Subject: [Haskell-cafe] Software Transactional Memory and LWN In-Reply-To: <4A30DF1F.7050400@kent.ac.uk> (Neil Brown's message of "Thu\, 11 Jun 2009 11\:40\:31 +0100") References: <87ab4ff9ze.fsf@malde.org> <4A30DF1F.7050400@kent.ac.uk> Message-ID: <8763f3f1a8.fsf@malde.org> Neil Brown writes: > I think there needs to be some differentiation here between the > implementation of STM, and the programmer's use of STM. > The implementation of STM does effectively use locks (from memory, > it's this paper that explains it: Ignoring the paper in the interest of laz...expedience, I guess the crucial part is committing the transactions - you'd either need locks or to single-thread the committing. > The use of STM does not involve locks, and one of STM's main > advantages is that it hides explicit locks from the user. If you have > retry in STM (as Haskell does, but not all other implementations do) > then you can write deadlocking code with it, and indeed you can > simulate mutexes and so on using retry, hence allowing you to use your > own constructed locks with STM. So in using STM you can deadlock, and > you can make some locks to use if you want, but it's not required. So the na?ve attempt at doing this would be something like: thread = do -- grab "lock 1" t <- readTVar lock when t retry writeTVar lock True -- grab "lock 2" t2 <- readTVar lock2 when t2 retry writeTVar writeTVar lock2 True -- do something writeTVar lock2 False writeTVar lock False and another one with the locks reversed. But that won't work of course, since the 'retry' will rollback the taking of lock 1 as well. So do I need to split this up into separate STM transactions and orchestrate the locking from the IO monad? -k -- If I haven't seen further, it is by standing in the footprints of giants From nccb2 at kent.ac.uk Thu Jun 11 08:01:45 2009 From: nccb2 at kent.ac.uk (Neil Brown) Date: Thu Jun 11 07:45:14 2009 Subject: [Haskell-cafe] Software Transactional Memory and LWN In-Reply-To: <8763f3f1a8.fsf@malde.org> References: <87ab4ff9ze.fsf@malde.org> <4A30DF1F.7050400@kent.ac.uk> <8763f3f1a8.fsf@malde.org> Message-ID: <4A30F229.9050803@kent.ac.uk> Ketil Malde wrote: > So the na?ve attempt at doing this would be something like: > > thread = do > -- grab "lock 1" > t <- readTVar lock > when t retry > writeTVar lock True > > -- grab "lock 2" > t2 <- readTVar lock2 > when t2 retry writeTVar > writeTVar lock2 True > > -- do something > writeTVar lock2 False > writeTVar lock False > > and another one with the locks reversed. But that won't work of > course, since the 'retry' will rollback the taking of lock 1 as well. > So do I need to split this up into separate STM transactions and > orchestrate the locking from the IO monad? > Indeed: type Lock = TVar Bool claim :: Lock -> IO () claim tv = atomically $ do b <- readTVar tv when b retry writeTVar tv True release :: Lock -> IO () release tv = atomically $ writeTVar tv False Writing a lock in STM is not useful for the purpose of doing some other STM stuff inbetween anyway, because that goes against the point of STM (you don't need locks for STM actions -- as you point out, the rollback from the locks is not useful in your example). So it only makes sense if you are doing some other IO action inbetween the claim and release. For example, you might want to write to a socket from several threads, and use locks to ensure exclusivity. Often, using STM for locks is pretty silly because there is some other way to do it (e.g. have the threads write their packets to an STM queue, and have a single thread reading from the queue and sending on the sockets) but they're a simple example of how you can create deadlock in STM, e.g. main = do tv1 <- newTVarIO False tv2 <- newTVarIO False forkIO $ claim tv2 >> claim tv1 >> release tv1 >> release tv2 claim tv1 >> claim tv2 >> release tv2 >> release tv1 is a possible source of deadlock, or even the more straightforward: main = newTVarIO True >>= claim What is particularly cool about Haskell's STM implementation is that in the second example (and possibly in the first one too) the run-time can detect straight-out deadlock and will throw you a deadlock exception. It does this via garbage collection -- if a thread is waiting on a TVar that no other thread has a reference to, the thread is technically ripe for garbage collection and the thread is instead woken up with an exception. At least, I think that's the principle. I don't think it can catch all cases (another thread may have the reference but may never use it) but it's still quite impressive. Thanks, Neil. From ttencate at gmail.com Thu Jun 11 08:47:21 2009 From: ttencate at gmail.com (Thomas ten Cate) Date: Thu Jun 11 08:30:55 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <5e0214850906110422v6528df4cg810d0aacecdd1fce@mail.gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <7b501d5c0906110420l1d5b842bu3103a7855973ac1f@mail.gmail.com> <5e0214850906110422v6528df4cg810d0aacecdd1fce@mail.gmail.com> Message-ID: I would like to have a go at it. Could you maybe upload the vector version somewhere? Thanks, Thomas On Thu, Jun 11, 2009 at 13:22, Eugene Kirpichov wrote: > The idea is pretty cool, but at first sight the batteries look like a > graphical glitch. Probably some antialiasing or smoothening is > needed.. > > 2009/6/11 Deniz Dogan : >> 2009/6/11 Thomas Davie : >>> We had a lot of "fun" deciding Haskell's new logo, and while I don't agree >>> with the final result, it would be nice if we could now start consistently >>> using it. ?With that in mind, I realised that the Haskell Platform's logo is >>> totally different, and did a quick mock up of a version reflecting the >>> current Haskell logo. ?It needs someone with the original vector graphics to >>> have a play and improve it a little bit, but hopefully you'll se a concept >>> you like. >>> >>> Here's the logo, continuing on the batteries included theme: >>> http://www.cs.kent.ac.uk/people/rpg/tatd2/HaskellBatteries.png >>> >>> I'd appreciate comments, suggestions, and possibly either access to the >>> vector version of our current logo, or someone producing a nice version of >>> this. >>> >>> Bob >> >> I love this suggestion! Maybe we should make the batteries look more >> battery-ish though. I think that especially the minus sign is a bit >> unclear, so maybe we could make the signs heavier? >> >> -- >> Deniz Dogan >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > > > -- > Eugene Kirpichov > Web IR developer, market.yandex.ru > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From nowgate at yahoo.com Thu Jun 11 09:37:25 2009 From: nowgate at yahoo.com (michael rice) Date: Thu Jun 11 09:20:59 2009 Subject: [Haskell-cafe] Building a tree? Message-ID: <508660.12108.qm@web31106.mail.mud.yahoo.com> Example understood. Thanks. Is there a module for binary trees? Michael --- On Wed, 6/10/09, wren ng thornton wrote: From: wren ng thornton Subject: Re: [Haskell-cafe] Building a tree? To: haskell-cafe@haskell.org Date: Wednesday, June 10, 2009, 8:13 PM michael rice wrote: > Here's a function from Data.Tree: > > unfoldTree :: (b -> (a, [b])) -> b -> Tree a > Build a tree from a seed value > > Could someone please give me a brief example of usage. ? ? Data.Tree> let t = unfoldTree (\i -> (show i, [i`div`2..i-1])) ? ? Data.Tree> putStr . drawTree $ t 8 -- Live well, ~wren _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090611/54c39698/attachment.html From byorgey at seas.upenn.edu Thu Jun 11 10:27:02 2009 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Thu Jun 11 10:10:37 2009 Subject: [Haskell-cafe] who's up for a hackathon? (ICFP, late Aug, early Sept) In-Reply-To: <20090610154356.GK29325@brighton.ac.uk> References: <20090610154356.GK29325@brighton.ac.uk> Message-ID: <20090611142702.GA24445@seas.upenn.edu> On Wed, Jun 10, 2009 at 04:43:57PM +0100, Eric Kow wrote: > Dear Haskellers, > > ICFP 2009 takes place from Monday 31 August to Wednesday 2 September, > with the Haskell Symposium following it on 3 September. > > Would anybody be interested having a Haskell Hackathon during this? My > thinking is that to catch people who are only going to the Haskell > Symposium, the best time is the following weekend (4-6 September). > Otherwise, the weekend before (29-30 August) is also an option and has > the benefit of catching people before they get tired :-) Sounds like fun! I'd be able to come if it was 29-30 August (looks like I'll just be hanging around with nothing to do in between the summer school and ICFP anyway), but probably not if it was after the Symposium. -Brent From v.reshetnikov at gmail.com Thu Jun 11 11:00:41 2009 From: v.reshetnikov at gmail.com (Vladimir Reshetnikov) Date: Thu Jun 11 10:44:16 2009 Subject: [Haskell-cafe] List comprehensions and impredicative rank-N types Message-ID: <4770d2590906110800k770dd4d2l797cee21bfdeebb8@mail.gmail.com> Hi, Consider the following definitions: ----------------------------------------------------------- {-# LANGUAGE RankNTypes, ImpredicativeTypes #-} foo :: [forall a. [a] -> [a]] foo = [reverse] bar :: [a -> b] -> a -> b bar fs = head fs ----------------------------------------------------------- According to the Haskell Report, [f | f <- foo] translates to (let ok f = [f]; ok _ = [] in concatMap ok foo), right? So, I wonder why (bar [f | f <- foo]) typechecks, but (bar (let ok f = [f]; ok _ = [] in concatMap ok foo)) and (bar foo) do not typecheck? Thanks, Vladimir From felipe.lessa at gmail.com Thu Jun 11 13:37:21 2009 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Thu Jun 11 13:21:18 2009 Subject: [Haskell-cafe] Re: [Haskell] ANNOUNCE: OpenGLRaw 1.0.0.0 In-Reply-To: <200906111856.01646.Sven.Panne@aedion.de> References: <200906111856.01646.Sven.Panne@aedion.de> Message-ID: <20090611173721.GA13950@kira.casa> On Thu, Jun 11, 2009 at 06:56:01PM +0200, Sven Panne wrote: > Version 1.0.0.0 covers the OpenGL 3.1 core, all ARB extensions > and all EXT extensions. What about OpenGL 2.1? As I understand, Linux won't have OpenGL 3.0 or 3.1 for at least some months, $ glxinfo | grep 'OpenGL version' OpenGL version string: 2.1 Mesa 7.5-rc3 Thanks! -- Felipe. From gtener at gmail.com Thu Jun 11 13:55:23 2009 From: gtener at gmail.com (=?UTF-8?Q?Krzysztof_Skrz=C4=99tnicki?=) Date: Thu Jun 11 13:38:56 2009 Subject: [Haskell-cafe] Re: [Haskell] ANNOUNCE: OpenGLRaw 1.0.0.0 In-Reply-To: <20090611173721.GA13950@kira.casa> References: <200906111856.01646.Sven.Panne@aedion.de> <20090611173721.GA13950@kira.casa> Message-ID: <220e47b40906111055i2c423d70qd6a370da823cb07@mail.gmail.com> On Thu, Jun 11, 2009 at 19:37, Felipe Lessa wrote: > On Thu, Jun 11, 2009 at 06:56:01PM +0200, Sven Panne wrote: >> Version 1.0.0.0 covers the OpenGL 3.1 core, all ARB extensions >> and all EXT extensions. > > What about OpenGL 2.1? ?As I understand, Linux won't have OpenGL > 3.0 or 3.1 for at least some months, > > $ glxinfo | grep 'OpenGL version' > OpenGL version string: 2.1 Mesa 7.5-rc3 > On my machine I get: $ glxinfo | grep -i version server glx version string: 1.4 client glx version string: 1.4 GLX version: 1.3 OpenGL version string: 3.0.0 NVIDIA 180.51 OpenGL shading language version string: 1.30 NVIDIA via Cg compiler So it doesn't appear to be true. Best regards Krzysztof Skrz?tnicki From felipe.lessa at gmail.com Thu Jun 11 14:14:45 2009 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Thu Jun 11 13:58:32 2009 Subject: [Haskell-cafe] Re: [Haskell] ANNOUNCE: OpenGLRaw 1.0.0.0 In-Reply-To: <220e47b40906111055i2c423d70qd6a370da823cb07@mail.gmail.com> References: <200906111856.01646.Sven.Panne@aedion.de> <20090611173721.GA13950@kira.casa> <220e47b40906111055i2c423d70qd6a370da823cb07@mail.gmail.com> Message-ID: <20090611181445.GA17216@kira.casa> On Thu, Jun 11, 2009 at 07:55:23PM +0200, Krzysztof Skrz?tnicki wrote: > On my machine I get: > > $ glxinfo | grep -i version > server glx version string: 1.4 > client glx version string: 1.4 > GLX version: 1.3 > OpenGL version string: 3.0.0 NVIDIA 180.51 > OpenGL shading language version string: 1.30 NVIDIA via Cg compiler > > So it doesn't appear to be true. So, open source Linux drivers won't have OpenGL 3.0 or 3.1 for at least some months :). I don't know the internals of the graphics subsystem, but AFAIK the open source drivers use Mesa to implement the OpenGL frontend, and the current version 7.5rc3 doesn't support it yet. FWIW, I'm using the Intel driver, version 2.7.1. -- Felipe. From jefferson.r.heard at gmail.com Thu Jun 11 14:38:48 2009 From: jefferson.r.heard at gmail.com (Jeff Heard) Date: Thu Jun 11 14:22:20 2009 Subject: [Haskell-cafe] Re: [Haskell] ANNOUNCE: OpenGLRaw 1.0.0.0 In-Reply-To: <20090611181445.GA17216@kira.casa> References: <200906111856.01646.Sven.Panne@aedion.de> <20090611173721.GA13950@kira.casa> <220e47b40906111055i2c423d70qd6a370da823cb07@mail.gmail.com> <20090611181445.GA17216@kira.casa> Message-ID: <4165d3a70906111138j2f09030ahd969d1f930648a99@mail.gmail.com> nVidia and ATI drivers both support GL 3.0 on Linux, although you're right that open source drivers don't. I for one welcome this package with open arms, since I'm mostly trying to implement a layer over OpenGL anyway with Hieroglyph. This'll help with the next revision of that. As for the package naming scheme, I don't mind it at all -- there are several different Graphics.Rendering packages with different backends and several Graphics.UI packages, so I think it's been fairly established. Perhaps there should be a Hackage Ontology project, though, or we should ask a librarian to look at Hackage and think about the problem and suggest a proposed standard for people to follow, then suggest to new library releasers under what set of QNames they ought to release their libraries under. This is more or less standard practice for large working groups on languages like XML and Java, and although it could be seen as a debatable practice to many, I prefer something descriptive of function in my module names, since package names so rarely are. case in point: Hieroglyph. What's it do? import Hieroglyph. Is there any clue by my function names which ones belong to a library called Hieroglyph? No. However, import Graphics.Rendering.Hieroglyph, and I see a function somewhere in the code called "arc" or "plane" or "circle", and I know it probably goes with the rendering package. On Thu, Jun 11, 2009 at 2:14 PM, Felipe Lessa wrote: > On Thu, Jun 11, 2009 at 07:55:23PM +0200, Krzysztof Skrz?tnicki wrote: >> On my machine I get: >> >> $ glxinfo | grep -i version >> server glx version string: 1.4 >> client glx version string: 1.4 >> GLX version: 1.3 >> OpenGL version string: 3.0.0 NVIDIA 180.51 >> OpenGL shading language version string: 1.30 NVIDIA via Cg compiler >> >> So it doesn't appear to be true. > > So, open source Linux drivers won't have OpenGL 3.0 or 3.1 for at > least some months :). ?I don't know the internals of the graphics > subsystem, but AFAIK the open source drivers use Mesa to > implement the OpenGL frontend, and the current version 7.5rc3 > doesn't support it yet. > > FWIW, I'm using the Intel driver, version 2.7.1. > > -- > Felipe. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From lemming at henning-thielemann.de Thu Jun 11 14:44:51 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Thu Jun 11 14:28:31 2009 Subject: [Haskell-cafe] Re: ANNOUNCE: OpenGLRaw 1.0.0.0 In-Reply-To: <4165d3a70906111138j2f09030ahd969d1f930648a99@mail.gmail.com> References: <200906111856.01646.Sven.Panne@aedion.de> <20090611173721.GA13950@kira.casa> <220e47b40906111055i2c423d70qd6a370da823cb07@mail.gmail.com> <20090611181445.GA17216@kira.casa> <4165d3a70906111138j2f09030ahd969d1f930648a99@mail.gmail.com> Message-ID: On Thu, 11 Jun 2009, Jeff Heard wrote: > case in point: Hieroglyph. What's it do? import Hieroglyph. Is > there any clue by my function names which ones belong to a library > called Hieroglyph? No. However, import > Graphics.Rendering.Hieroglyph, and I see a function somewhere in the > code called "arc" or "plane" or "circle", and I know it probably goes > with the rendering package. http://www.haskell.org/haskellwiki/Import_modules_properly From jefferson.r.heard at gmail.com Thu Jun 11 14:55:39 2009 From: jefferson.r.heard at gmail.com (Jeff Heard) Date: Thu Jun 11 14:39:14 2009 Subject: [Haskell-cafe] Re: ANNOUNCE: OpenGLRaw 1.0.0.0 In-Reply-To: References: <200906111856.01646.Sven.Panne@aedion.de> <20090611173721.GA13950@kira.casa> <220e47b40906111055i2c423d70qd6a370da823cb07@mail.gmail.com> <20090611181445.GA17216@kira.casa> <4165d3a70906111138j2f09030ahd969d1f930648a99@mail.gmail.com> Message-ID: <4165d3a70906111155yfe07a53y4c2ea3a151245222@mail.gmail.com> Oh, and I don't disagree with that at all. I just just have an aesthetic preference for multiply qualified library names. Chalk it up to the fact that my partner's a librarian, so I'm used to putting things in categories, subcategories, and sub-sub-categories :-) -- Jeff On Thu, Jun 11, 2009 at 2:44 PM, Henning Thielemann wrote: > > On Thu, 11 Jun 2009, Jeff Heard wrote: > >> case in point: Hieroglyph. ?What's it do? ?import Hieroglyph. ?Is >> there any clue by my function names which ones belong to a library >> called Hieroglyph? ?No. ?However, import >> Graphics.Rendering.Hieroglyph, and I see a function somewhere in the >> code called "arc" or "plane" or "circle", and I know it probably goes >> with the rendering package. > > http://www.haskell.org/haskellwiki/Import_modules_properly > From jefferson.r.heard at gmail.com Thu Jun 11 14:58:43 2009 From: jefferson.r.heard at gmail.com (Jeff Heard) Date: Thu Jun 11 14:42:18 2009 Subject: [Haskell-cafe] Re: ANNOUNCE: OpenGLRaw 1.0.0.0 In-Reply-To: <4165d3a70906111155yfe07a53y4c2ea3a151245222@mail.gmail.com> References: <200906111856.01646.Sven.Panne@aedion.de> <20090611173721.GA13950@kira.casa> <220e47b40906111055i2c423d70qd6a370da823cb07@mail.gmail.com> <20090611181445.GA17216@kira.casa> <4165d3a70906111138j2f09030ahd969d1f930648a99@mail.gmail.com> <4165d3a70906111155yfe07a53y4c2ea3a151245222@mail.gmail.com> Message-ID: <4165d3a70906111158g1092a777ic17e4c6bfd39fe7d@mail.gmail.com> And the one other thing is that it increases (to me) the at-a-glance comprehensibility of the module. If I'm reading over soemone else's code and I want to get a feel for where s/he put things, the fully qualified module structure and the fully qualified names in the import statements make it easy to get a feel for the organizational structure of the program. That way, on first reading I don't have to go through the whole module to figure out what was contained in Utils when I see the phrase import Utils or even import qualified Utils at the top of the module. -- Jeff On Thu, Jun 11, 2009 at 2:55 PM, Jeff Heard wrote: > Oh, and I don't disagree with that at all. ?I just just have an > aesthetic preference for multiply qualified library names. ?Chalk it > up to the fact that my partner's a librarian, so I'm used to putting > things in categories, subcategories, and sub-sub-categories :-) > > -- Jeff > > On Thu, Jun 11, 2009 at 2:44 PM, Henning > Thielemann wrote: >> >> On Thu, 11 Jun 2009, Jeff Heard wrote: >> >>> case in point: Hieroglyph. ?What's it do? ?import Hieroglyph. ?Is >>> there any clue by my function names which ones belong to a library >>> called Hieroglyph? ?No. ?However, import >>> Graphics.Rendering.Hieroglyph, and I see a function somewhere in the >>> code called "arc" or "plane" or "circle", and I know it probably goes >>> with the rendering package. >> >> http://www.haskell.org/haskellwiki/Import_modules_properly >> > From ryani.spam at gmail.com Thu Jun 11 15:23:05 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Thu Jun 11 15:06:37 2009 Subject: [Haskell-cafe] Software Transactional Memory and LWN In-Reply-To: <8763f3f1a8.fsf@malde.org> References: <87ab4ff9ze.fsf@malde.org> <4A30DF1F.7050400@kent.ac.uk> <8763f3f1a8.fsf@malde.org> Message-ID: <2f9b2d30906111223k75c93f22mf7a358b3be18b0d1@mail.gmail.com> On Thu, Jun 11, 2009 at 4:38 AM, Ketil Malde wrote: > Ignoring the paper in the interest of laz...expedience, I guess the > crucial part is committing the transactions - you'd either need locks > or to single-thread the committing. It's possible to single-thread the commit without locking using lock-free mechanisms, but it's extremely tricky. The current proof-of-concept implementation uses locks under the hood, but only during commit. One big benefit of STM, in fact, is that you can avoid using locks until commit-time; it's very difficult to write correct concurrent code even with locks around the entirety of your transaction (as is used in, for example, Java's "synchronize" methods). Being correct while delaying all locking until updates need to be made is impressive in itself. The other benefit is that you free the programmer from having to worry about locks; they are an implementation detail. There's no technical hurdle towards switching all of Haskell's STM code to a lock-free implementation; client code using STM doesn't have to change at all. Saying "all current implementations use locks" is kind of a cop-out; it would be like saying ten years ago "all current cars use gasoline, so why bother researching better batteries?" I am confident that there will be a lock-free implementation of STM in Haskell's future. -- ryan From wren at freegeek.org Thu Jun 11 20:49:56 2009 From: wren at freegeek.org (wren ng thornton) Date: Thu Jun 11 20:33:28 2009 Subject: [Haskell-cafe] Building a tree? In-Reply-To: <508660.12108.qm@web31106.mail.mud.yahoo.com> References: <508660.12108.qm@web31106.mail.mud.yahoo.com> Message-ID: <4A31A634.2000509@freegeek.org> michael rice wrote: > Example understood. Thanks. > > Is there a module for binary trees? Not that I know of off hand. Trees are one of those data structures with so many different variants that people end up rolling their own based on whatever they need at the time. Hence Data.Tree, Data.Sequence, Data.Set, Data.Map, Data.IntMap, Data.Trie,... -- Live well, ~wren From caseyh at istar.ca Thu Jun 11 21:47:18 2009 From: caseyh at istar.ca (Casey Hawthorne) Date: Thu Jun 11 21:30:59 2009 Subject: [Haskell-cafe] When folding is there a way to pick out the last point being processed? In-Reply-To: <4A31A634.2000509@freegeek.org> References: <508660.12108.qm@web31106.mail.mud.yahoo.com> <4A31A634.2000509@freegeek.org> Message-ID: When folding is there a way to pick out the last point being processed? The first point can easily be picked out with (x:xs) but last xs crawls down the list. -- Regards, Casey From tonymorris at gmail.com Thu Jun 11 22:33:13 2009 From: tonymorris at gmail.com (Tony Morris) Date: Thu Jun 11 22:16:29 2009 Subject: [Haskell-cafe] When folding is there a way to pick out the last point being processed? In-Reply-To: References: <508660.12108.qm@web31106.mail.mud.yahoo.com> <4A31A634.2000509@freegeek.org> Message-ID: <4A31BE69.7030407@gmail.com> By swapping from foldl to foldr? Care to provide more detail? Casey Hawthorne wrote: > When folding is there a way to pick out the last point being > processed? > > The first point can easily be picked out with (x:xs) but last xs > crawls down the list. > -- > Regards, > Casey > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- Tony Morris http://tmorris.net/ From thomas.dubuisson at gmail.com Thu Jun 11 22:41:11 2009 From: thomas.dubuisson at gmail.com (Thomas DuBuisson) Date: Thu Jun 11 22:24:44 2009 Subject: [Haskell-cafe] When folding is there a way to pick out the last point being processed? In-Reply-To: References: <508660.12108.qm@web31106.mail.mud.yahoo.com> <4A31A634.2000509@freegeek.org> Message-ID: <4c44d90b0906111941l31861ebdsf0b2823cf9c425f8@mail.gmail.com> Something like the belo 'foldL_last'? You could probably do it cleaner, but I don't think there is a library function that would help any more than foldl. foldL_last :: (a -> b -> a) -> a -> [b] -> (Maybe b, a) foldL_last f x xs = foldl (\(_,a) b -> (Just b, f a b)) (Nothing, x) xs Tom On Thu, Jun 11, 2009 at 6:47 PM, Casey Hawthorne wrote: > When folding is there a way to pick out the last point being > processed? > > The first point can easily be picked out with (x:xs) but last xs > crawls down the list. > -- > Regards, > Casey > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From claudiusmaximus at goto10.org Thu Jun 11 22:57:45 2009 From: claudiusmaximus at goto10.org (Claude Heiland-Allen) Date: Thu Jun 11 22:41:19 2009 Subject: [Haskell-cafe] When folding is there a way to pick out the last point being processed? In-Reply-To: References: <508660.12108.qm@web31106.mail.mud.yahoo.com> <4A31A634.2000509@freegeek.org> Message-ID: <4A31C429.1040204@goto10.org> Casey Hawthorne wrote: > When folding is there a way to pick out the last point being > processed? I came up with these: safeHead = foldr (const . Just) Nothing safeLast = foldr (flip mplus . Just) Nothing Claude -- http://claudiusmaximus.goto10.org From evan at eklitzke.org Thu Jun 11 23:17:38 2009 From: evan at eklitzke.org (Evan Klitzke) Date: Thu Jun 11 23:01:10 2009 Subject: [Haskell-cafe] Debugging misbehaving multi-threaded programs In-Reply-To: <87fxe7fcat.fsf@malde.org> References: <87fxe7fcat.fsf@malde.org> Message-ID: On Thu, Jun 11, 2009 at 12:40 AM, Ketil Malde wrote: > Evan Klitzke writes: > >> [...] Unfortunately, this doesn't seem to work; whenever the >> program terminates due to running out of heap space, the generated >> .prof file is empty. > > Unless there's some specific problem with profiling in combination > with threading, you can get heap profiling from a crashing program. > Not what you wanted, but you might at least be able to see what is > allocated. After fiddling around a bit, I found out that you can get a heap profile from a program that dies from an error, but not one that dies from actually running out of heap space. I was able to take advantage of this by making the main thread do a threadDelay and then error, with the threadDelay timed to occur during the program's misbehavior. -- Evan Klitzke :wq From vigalchin at gmail.com Fri Jun 12 00:02:54 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Thu Jun 11 23:46:25 2009 Subject: [Haskell-cafe] Semantic web RDF store Message-ID: <5ae4f2ba0906112102g3c6c8e44yd14251fad46bcffe@mail.gmail.com> Hello, Currently I am working on re-packaging Swish written by Graham Klyne so that is cabalized... I am chugging along. I am also thinking about writing a FFI for some RDF store API like http://www.rdflib.net/store/ so that Swish could be hooked into a "reliable"persistent store where the store type can be switched out like MySQL dor SQLite, etc. Has any one already done something like this? I don't like reinventing the wheel. Regards, Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090611/21ef3cae/attachment.html From vigalchin at gmail.com Fri Jun 12 00:14:44 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Thu Jun 11 23:58:17 2009 Subject: [Haskell-cafe] Re: Semantic web RDF store In-Reply-To: <5ae4f2ba0906112102g3c6c8e44yd14251fad46bcffe@mail.gmail.com> References: <5ae4f2ba0906112102g3c6c8e44yd14251fad46bcffe@mail.gmail.com> Message-ID: <5ae4f2ba0906112114m48731017u45ee67af74f7898e@mail.gmail.com> P.S. I am open to sugestions on any RDF store API's! Vasili On Thu, Jun 11, 2009 at 11:02 PM, Vasili I. Galchin wrote: > Hello, > > Currently I am working on re-packaging Swish written by Graham Klyne > so that is cabalized... I am chugging along. I am also thinking about > writing a FFI for some RDF store API like http://www.rdflib.net/store/ so > that Swish could be hooked into a "reliable"persistent store where the store > type can be switched out like MySQL dor SQLite, etc. Has any one already > done something like this? I don't like reinventing the wheel. > > Regards, > > Vasili > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090611/c9dd6fb0/attachment.html From vigalchin at gmail.com Fri Jun 12 00:50:37 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Fri Jun 12 00:34:08 2009 Subject: [Haskell-cafe] install problems ... Message-ID: <5ae4f2ba0906112150r5095e7d7t41bd10950daaa63e@mail.gmail.com> Hello, As I have said before I a, "cabalizing" Swish (a semantic web toolkit). I have it built and have run most of the original author's tests by and they pass. There are numerous warnings which seem to be either lack of a function type signature or "unreferenced" symbols ... I will go through one-by-one and clean these up. However, now I am getting the following install-time errors .... any advice on how to track down will be greatly apprecriated .... the following is the result of "cabal build -v": Preprocessing executables for swish-0.2.1... Building swish-0.2.1... /usr/bin/ar: creating dist/build/libHSswish-0.2.1.a Warning: output was redirected with -o, but no output will be generated because there is no Main module. Installing: /home/vigalchin/.cabal/lib/swish-0.2.1/ghc-6.8.2 Installing: /home/vigalchin/.cabal/bin cabal: Error: some packages failed to install: swish-0.2.1 failed during the final install step. The exception was: dist/build/N3Parser/N3Parser: copyFile: does not exist (No such file or directory) vigalchin@ubuntu:~/FTP/Haskell/Swish-0.2.1$ Regards, Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090612/66fd2686/attachment.html From conal at conal.net Fri Jun 12 01:23:51 2009 From: conal at conal.net (Conal Elliott) Date: Fri Jun 12 01:07:42 2009 Subject: [Haskell-cafe] Re: ANNOUNCE: OpenGLRaw 1.0.0.0 In-Reply-To: <4165d3a70906111155yfe07a53y4c2ea3a151245222@mail.gmail.com> References: <200906111856.01646.Sven.Panne@aedion.de> <20090611173721.GA13950@kira.casa> <220e47b40906111055i2c423d70qd6a370da823cb07@mail.gmail.com> <20090611181445.GA17216@kira.casa> <4165d3a70906111138j2f09030ahd969d1f930648a99@mail.gmail.com> <4165d3a70906111155yfe07a53y4c2ea3a151245222@mail.gmail.com> Message-ID: On Thu, Jun 11, 2009 at 11:55 AM, Jeff Heard wrote: > Oh, and I don't disagree with that at all. I just just have an > aesthetic preference for multiply qualified library names. Chalk it > up to the fact that my partner's a librarian, so I'm used to putting > things in categories, subcategories, and sub-sub-categories :-) Check out http://www.shirky.com/writings/ontology_overrated.html . -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090612/95f89bb1/attachment.html From mvanier42 at gmail.com Fri Jun 12 03:00:13 2009 From: mvanier42 at gmail.com (Michael Vanier) Date: Fri Jun 12 02:43:45 2009 Subject: [Haskell-cafe] Documentation bug -- building ghc from darcs sources Message-ID: <4A31FCFD.2050607@cs.caltech.edu> I've been trying to build ghc head from the darcs repo using these instructions: http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources Unfortunately, when I do ./darcs-all --extra get as described under "Getting more packages" it fails because the darcs-all script doesn't recognize the --extra option. Was this removed recently, and if so, how do I achieve the same effect? TIA, Mike From pkeir at dcs.gla.ac.uk Fri Jun 12 03:13:18 2009 From: pkeir at dcs.gla.ac.uk (Paul Keir) Date: Fri Jun 12 02:56:50 2009 Subject: [Haskell-cafe] ghci and applicative Message-ID: <3CDFB8AFEA98E34CB599475AB11589C82C3DC3@EX2.ad.dcs.gla.ac.uk> Hi, I'm finding that some data types which use Applicative to instantiate the Num class, give responses I wasn't expecting at the ghci prompt. A simple example is list: import Control.Applicative instance (Num a) => Num [a] where as + bs = (+) <$> as <*> bs (*) = undefined; abs = undefined signum = undefined; fromInteger = undefined f1 = let op = (+) in [1,2,3] `op` [1,1,1] f2 = let op = (+) in op [1,2,3] [1,1,1] Functions f1 and f2 give no problems at the ghci prompt. However if I instead type the body of either interactively, I get an error: *Main> let op = (+) *Main> [1,2,3] `op` [1,1,1] :1:0: Couldn't match expected type `Integer' against inferred type `[a]' In the first argument of `op', namely `[1, 2, 3]' In the expression: [1, 2, 3] `op` [1, 1, 1] In the definition of `it': it = [1, 2, 3] `op` [1, 1, 1] I get the same error message with op [1,2,3] [1,1,1]. Any thoughts? Thanks, Paul -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090612/74790124/attachment.html From ryani.spam at gmail.com Fri Jun 12 03:31:51 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Fri Jun 12 03:15:22 2009 Subject: [Haskell-cafe] ghci and applicative In-Reply-To: <3CDFB8AFEA98E34CB599475AB11589C82C3DC3@EX2.ad.dcs.gla.ac.uk> References: <3CDFB8AFEA98E34CB599475AB11589C82C3DC3@EX2.ad.dcs.gla.ac.uk> Message-ID: <2f9b2d30906120031n286be1c0w28978262a14f100a@mail.gmail.com> :set -XNoMonomorphismRestriction or eta-expand: let op x y = x+y The problem is that "op" looks like a value to the user, but it's a function (based on the dictionary passed in), which means that any evaluation it does isn't shared between instances. Consider: f1 = let v = fib 10000 in \x -> x + v f1 :: Integer -> Integer only calculates "fib 10000" once, but, f1 :: Num a => a -> a calculates "fib 10000" every time you call it. This can lead some programs to take exponentially longer than they seem like they should. -- ryan On Fri, Jun 12, 2009 at 12:13 AM, Paul Keir wrote: > Hi, > > I'm finding that some data types which use Applicative to > instantiate the Num class, give responses I wasn't expecting > at the ghci prompt. A simple example is list: > > import Control.Applicative > > instance (Num a) => Num [a] where > ?as + bs = (+) <$> as <*> bs > ?(*) = undefined;??? abs = undefined > ?signum = undefined; fromInteger = undefined > > f1 = let op = (+) in [1,2,3] `op` [1,1,1] > f2 = let op = (+) in op [1,2,3] [1,1,1] > > Functions f1 and f2 give no problems at the ghci prompt. > However if I instead type the body of either interactively, > I get an error: > > *Main> let op = (+) > *Main> [1,2,3] `op` [1,1,1] > > :1:0: > ??? Couldn't match expected type `Integer' against inferred type `[a]' > ??? In the first argument of `op', namely `[1, 2, 3]' > ??? In the expression: [1, 2, 3] `op` [1, 1, 1] > ??? In the definition of `it': it = [1, 2, 3] `op` [1, 1, 1] > > I get the same error message with op [1,2,3] [1,1,1]. Any thoughts? > > Thanks, > Paul > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From haskellmail at gmail.com Fri Jun 12 03:38:17 2009 From: haskellmail at gmail.com (kenny lu) Date: Fri Jun 12 03:21:48 2009 Subject: [Haskell-cafe] exporting Data.ByteString functions via FFI Message-ID: <90bba1dc0906120038v4e7ddae9g79777461623d6bef@mail.gmail.com> Hi, I was trying to write a FFI wrapper for my Haskell program which manipulates ByteString. But I am unable to compile/link it. Here is the toy program. {-# LANGUAGE ForeignFunctionInterface #-} module B where import Foreign.C.Types import Foreign.C.String import qualified Data.ByteString as BS rev :: BS.ByteString -> BS.ByteString rev bstr = BS.reverse bstr rev_hs :: CString -> IO CString rev_hs cstr = do { bstr <- BS.packCString cstr ; let bstr' = rev bstr ; cstr' <- newCString (show bstr') ; return cstr' } foreign export ccall rev_hs :: CString -> IO CString And here is the C counter-part. #include "B_stub.h" #include int main(int argc, char *argv[]) { char *str; hs_init(&argc, &argv); str = rev_hs("it works."); printf("Rev: %s\n", str); hs_exit(); return 0; } Compiling B.hs alone seems fine, but errors popped up when I was trying to compile/link it with C. $ ghc -c -O B.hs $ ghc -optc-O test_b.c B.o B_stub.o -o test_b Undefined symbols: "___stginit_bytestringzm0zi9zi1zi4_DataziByteString_", referenced from: ___stginit_Lib_ in B.o "_bytestringzm0zi9zi1zi4_DataziByteString_zdwreverse_info", referenced from: _s19w_info in B.o "_bytestringzm0zi9zi1zi4_DataziByteStringziInternal_zdwshowsPrec_info", referenced from: _s19v_info in B.o "_bytestringzm0zi9zi1zi4_DataziByteStringziInternal_zdwshowsPrec_closure", referenced from: _Lib_zdwa_srt in B.o "_bytestringzm0zi9zi1zi4_DataziByteString_zdwa4_info", referenced from: _Lib_zdwa_info in B.o "_bytestringzm0zi9zi1zi4_DataziByteString_reverse_info", referenced from: _Lib_rev_info in B.o ld: symbol(s) not found collect2: ld returned 1 exit status If I replace ByteString with the ordinary String, the above programs can be compiled and linked. Can someone tell me what I did wrong here? -Kenny -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090612/314a7c43/attachment.html From jochem at functor.nl Fri Jun 12 03:50:45 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Fri Jun 12 03:34:19 2009 Subject: [Haskell-cafe] exporting Data.ByteString functions via FFI In-Reply-To: <90bba1dc0906120038v4e7ddae9g79777461623d6bef@mail.gmail.com> References: <90bba1dc0906120038v4e7ddae9g79777461623d6bef@mail.gmail.com> Message-ID: <4A3208D5.7020702@functor.nl> kenny lu wrote: > Hi, > > I was trying to write a FFI wrapper for my Haskell program which manipulates > > ByteString. But I am unable to compile/link it. > > > Here is the toy program. > > {-# LANGUAGE ForeignFunctionInterface #-} > > module B where > > import Foreign.C.Types > import Foreign.C.String > import qualified Data.ByteString as BS > > rev :: BS.ByteString -> BS.ByteString > rev bstr = BS.reverse bstr > > rev_hs :: CString -> IO CString > rev_hs cstr = > do { bstr <- BS.packCString cstr > ; let bstr' = rev bstr > ; cstr' <- newCString (show bstr') > ; return cstr' > } > > foreign export ccall rev_hs :: CString -> IO CString > > > And here is the C counter-part. > > #include "B_stub.h" > #include > > int main(int argc, char *argv[]) { > char *str; > hs_init(&argc, &argv); > > str = rev_hs("it works."); > printf("Rev: %s\n", str); > > hs_exit(); > return 0; > } > > Compiling B.hs alone seems fine, but errors popped up when I was trying to > compile/link it with C. > > $ ghc -c -O B.hs > > $ ghc -optc-O test_b.c B.o B_stub.o -o test_b > Undefined symbols: > "___stginit_bytestringzm0zi9zi1zi4_DataziByteString_", referenced from: > ___stginit_Lib_ in B.o > "_bytestringzm0zi9zi1zi4_DataziByteString_zdwreverse_info", referenced > from: > _s19w_info in B.o > "_bytestringzm0zi9zi1zi4_DataziByteStringziInternal_zdwshowsPrec_info", > referenced from: > _s19v_info in B.o > "_bytestringzm0zi9zi1zi4_DataziByteStringziInternal_zdwshowsPrec_closure", > referenced from: > _Lib_zdwa_srt in B.o > "_bytestringzm0zi9zi1zi4_DataziByteString_zdwa4_info", referenced from: > _Lib_zdwa_info in B.o > "_bytestringzm0zi9zi1zi4_DataziByteString_reverse_info", referenced from: > _Lib_rev_info in B.o > ld: symbol(s) not found > collect2: ld returned 1 exit status > > > If I replace ByteString with the ordinary String, the above programs can be > compiled and linked. > > Can someone tell me what I did wrong here? Add -package bytestring to the ghc command line options. I believe that adding --make also may work. Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From haskellmail at gmail.com Fri Jun 12 04:04:13 2009 From: haskellmail at gmail.com (kenny lu) Date: Fri Jun 12 03:47:44 2009 Subject: [Haskell-cafe] exporting Data.ByteString functions via FFI In-Reply-To: <4A3208D5.7020702@functor.nl> References: <90bba1dc0906120038v4e7ddae9g79777461623d6bef@mail.gmail.com> <4A3208D5.7020702@functor.nl> Message-ID: <90bba1dc0906120104h5c2cde50qd0c759a85df4d50f@mail.gmail.com> It works indeed. Thanks. -Kenny On Fri, Jun 12, 2009 at 3:50 PM, Jochem Berndsen wrote: > kenny lu wrote: > > Hi, > > > > I was trying to write a FFI wrapper for my Haskell program which > manipulates > > > > ByteString. But I am unable to compile/link it. > > > > > > Here is the toy program. > > > > {-# LANGUAGE ForeignFunctionInterface #-} > > > > module B where > > > > import Foreign.C.Types > > import Foreign.C.String > > import qualified Data.ByteString as BS > > > > rev :: BS.ByteString -> BS.ByteString > > rev bstr = BS.reverse bstr > > > > rev_hs :: CString -> IO CString > > rev_hs cstr = > > do { bstr <- BS.packCString cstr > > ; let bstr' = rev bstr > > ; cstr' <- newCString (show bstr') > > ; return cstr' > > } > > > > foreign export ccall rev_hs :: CString -> IO CString > > > > > > And here is the C counter-part. > > > > #include "B_stub.h" > > #include > > > > int main(int argc, char *argv[]) { > > char *str; > > hs_init(&argc, &argv); > > > > str = rev_hs("it works."); > > printf("Rev: %s\n", str); > > > > hs_exit(); > > return 0; > > } > > > > Compiling B.hs alone seems fine, but errors popped up when I was trying > to > > compile/link it with C. > > > > $ ghc -c -O B.hs > > > > $ ghc -optc-O test_b.c B.o B_stub.o -o test_b > > Undefined symbols: > > "___stginit_bytestringzm0zi9zi1zi4_DataziByteString_", referenced from: > > ___stginit_Lib_ in B.o > > "_bytestringzm0zi9zi1zi4_DataziByteString_zdwreverse_info", referenced > > from: > > _s19w_info in B.o > > "_bytestringzm0zi9zi1zi4_DataziByteStringziInternal_zdwshowsPrec_info", > > referenced from: > > _s19v_info in B.o > > > "_bytestringzm0zi9zi1zi4_DataziByteStringziInternal_zdwshowsPrec_closure", > > referenced from: > > _Lib_zdwa_srt in B.o > > "_bytestringzm0zi9zi1zi4_DataziByteString_zdwa4_info", referenced from: > > _Lib_zdwa_info in B.o > > "_bytestringzm0zi9zi1zi4_DataziByteString_reverse_info", referenced > from: > > _Lib_rev_info in B.o > > ld: symbol(s) not found > > collect2: ld returned 1 exit status > > > > > > If I replace ByteString with the ordinary String, the above programs can > be > > compiled and linked. > > > > Can someone tell me what I did wrong here? > > Add -package bytestring to the ghc command line options. I believe that > adding --make also may work. > > Regards, > -- > Jochem Berndsen | jochem@functor.nl > GPG: 0xE6FABFAB > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090612/c9fb3b8e/attachment.html From loup.vaillant at gmail.com Fri Jun 12 04:27:31 2009 From: loup.vaillant at gmail.com (Loup Vaillant) Date: Fri Jun 12 04:11:04 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> Message-ID: <6f9f8f4a0906120127x2c1cce01x6abf6cae17f7ee19@mail.gmail.com> 2009/6/11 Thomas Davie : > Here's the logo, continuing on the batteries included theme: > http://www.cs.kent.ac.uk/people/rpg/tatd2/HaskellBatteries.png I'd sugest a thinner and smaller lambda, or bigger (maybe longer) batteries. The + tip of the batteries should also be colored in gold. Loup. From marlowsd at gmail.com Fri Jun 12 04:30:54 2009 From: marlowsd at gmail.com (Simon Marlow) Date: Fri Jun 12 04:14:40 2009 Subject: [Haskell-cafe] Re: Documentation bug -- building ghc from darcs sources In-Reply-To: <4A31FCFD.2050607@cs.caltech.edu> References: <4A31FCFD.2050607@cs.caltech.edu> Message-ID: <4A32123E.5060605@gmail.com> On 12/06/2009 08:00, Michael Vanier wrote: > I've been trying to build ghc head from the darcs repo using these > instructions: > > http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources > > Unfortunately, when I do > > ./darcs-all --extra get > > as described under "Getting more packages" it fails because the > darcs-all script doesn't recognize the --extra option. Was this removed > recently, and if so, how do I achieve the same effect? The --extra flag was removed recently, I've just updated the wiki pages to match. Thanks for spotting it. (in the future, posting to glasgow-haskell-users@haskell.org will make it more likely we'll notice your message). Cheers, Simon From tom.davie at gmail.com Fri Jun 12 04:39:39 2009 From: tom.davie at gmail.com (Thomas Davie) Date: Fri Jun 12 04:23:14 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <6f9f8f4a0906120127x2c1cce01x6abf6cae17f7ee19@mail.gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <6f9f8f4a0906120127x2c1cce01x6abf6cae17f7ee19@mail.gmail.com> Message-ID: <02E3B702-2B26-4513-B5E9-EFDB95E4C4ED@gmail.com> On 12 Jun 2009, at 10:27, Loup Vaillant wrote: > 2009/6/11 Thomas Davie : >> Here's the logo, continuing on the batteries included theme: >> http://www.cs.kent.ac.uk/people/rpg/tatd2/HaskellBatteries.png > > I'd sugest a thinner and smaller lambda, or bigger (maybe longer) > batteries. The + tip of the batteries should also be colored in gold. Hmm, I'm not sure I agree -- I think the main strength of the original logo is that it's simple, both in terms of all lines being the same width, and in terms of having only two colours used. It means it can be adapted to all sorts of different colour sets (as it is on Haskell.org). Perhaps the correct thing to do here is to make a black/gold version for the haskell platform? I do agree with the earlier comment that the font for the +/- needs to be more bold, if I'd had a vector version, I would have done that. Bob From tom at lokhorst.eu Fri Jun 12 04:47:07 2009 From: tom at lokhorst.eu (Tom Lokhorst) Date: Fri Jun 12 04:31:02 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <02E3B702-2B26-4513-B5E9-EFDB95E4C4ED@gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <6f9f8f4a0906120127x2c1cce01x6abf6cae17f7ee19@mail.gmail.com> <02E3B702-2B26-4513-B5E9-EFDB95E4C4ED@gmail.com> Message-ID: <317ca7670906120147x68e3be10p873f6be9a790aed9@mail.gmail.com> There's a SVG version of the logo on the wiki: http://haskell.org/haskellwiki/Thompson-Wheeler_logo On Fri, Jun 12, 2009 at 10:39 AM, Thomas Davie wrote: > > On 12 Jun 2009, at 10:27, Loup Vaillant wrote: > >> 2009/6/11 Thomas Davie : >>> >>> Here's the logo, continuing on the batteries included theme: >>> http://www.cs.kent.ac.uk/people/rpg/tatd2/HaskellBatteries.png >> >> I'd sugest a thinner and smaller lambda, or bigger (maybe longer) >> batteries. The + tip of the batteries should also be colored in gold. > > Hmm, I'm not sure I agree -- I think the main strength of the original logo > is that it's simple, both in terms of all lines being the same width, and in > terms of having only two colours used. ?It means it can be adapted to all > sorts of different colour sets (as it is on Haskell.org). > > Perhaps the correct thing to do here is to make a black/gold version for the > haskell platform? > > I do agree with the earlier comment that the font for the +/- needs to be > more bold, if I'd had a vector version, I would have done that. > > Bob > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From deniz.a.m.dogan at gmail.com Fri Jun 12 04:57:33 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Fri Jun 12 04:41:06 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <317ca7670906120147x68e3be10p873f6be9a790aed9@mail.gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <6f9f8f4a0906120127x2c1cce01x6abf6cae17f7ee19@mail.gmail.com> <02E3B702-2B26-4513-B5E9-EFDB95E4C4ED@gmail.com> <317ca7670906120147x68e3be10p873f6be9a790aed9@mail.gmail.com> Message-ID: <7b501d5c0906120157w78cb299dj1ab7a5a5189329f1@mail.gmail.com> 2009/6/12 Tom Lokhorst : > There's a SVG version of the logo on the wiki: > http://haskell.org/haskellwiki/Thompson-Wheeler_logo I think the biggest problem making the batteries not look like batteries is that they don't look "round". For that we need some careful "gradenting" of them, to make the bottoms of them look shadowed. -- Deniz Dogan From deniz.a.m.dogan at gmail.com Fri Jun 12 05:15:45 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Fri Jun 12 04:59:16 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <7b501d5c0906120157w78cb299dj1ab7a5a5189329f1@mail.gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <6f9f8f4a0906120127x2c1cce01x6abf6cae17f7ee19@mail.gmail.com> <02E3B702-2B26-4513-B5E9-EFDB95E4C4ED@gmail.com> <317ca7670906120147x68e3be10p873f6be9a790aed9@mail.gmail.com> <7b501d5c0906120157w78cb299dj1ab7a5a5189329f1@mail.gmail.com> Message-ID: <7b501d5c0906120215t2f79a7ebi4396f94dc85e11a1@mail.gmail.com> 2009/6/12 Deniz Dogan : > 2009/6/12 Tom Lokhorst : >> There's a SVG version of the logo on the wiki: >> http://haskell.org/haskellwiki/Thompson-Wheeler_logo > > I think the biggest problem making the batteries not look like > batteries is that they don't look "round". For that we need some > careful "gradenting" of them, to make the bottoms of them look > shadowed. > > -- > Deniz Dogan > Attached is a new version of the same idea with a slight gradient on the batteries and a slightly thicker font for the signs. -- Deniz Dogan -------------- next part -------------- A non-text attachment was scrubbed... Name: logo-1.svg Type: image/svg+xml Size: 5728 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090612/a9d5211b/logo-1.bin From deniz.a.m.dogan at gmail.com Fri Jun 12 05:25:43 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Fri Jun 12 05:09:14 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <7b501d5c0906120215t2f79a7ebi4396f94dc85e11a1@mail.gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <6f9f8f4a0906120127x2c1cce01x6abf6cae17f7ee19@mail.gmail.com> <02E3B702-2B26-4513-B5E9-EFDB95E4C4ED@gmail.com> <317ca7670906120147x68e3be10p873f6be9a790aed9@mail.gmail.com> <7b501d5c0906120157w78cb299dj1ab7a5a5189329f1@mail.gmail.com> <7b501d5c0906120215t2f79a7ebi4396f94dc85e11a1@mail.gmail.com> Message-ID: <7b501d5c0906120225g5c43e820g480486c35e047dc8@mail.gmail.com> 2009/6/12 Deniz Dogan : > 2009/6/12 Deniz Dogan : >> 2009/6/12 Tom Lokhorst : >>> There's a SVG version of the logo on the wiki: >>> http://haskell.org/haskellwiki/Thompson-Wheeler_logo >> >> I think the biggest problem making the batteries not look like >> batteries is that they don't look "round". For that we need some >> careful "gradenting" of them, to make the bottoms of them look >> shadowed. >> >> -- >> Deniz Dogan >> > > Attached is a new version of the same idea with a slight gradient on > the batteries and a slightly thicker font for the signs. > > -- > Deniz Dogan > I realise now that I forgot the little "head" on the plus side of the battery, so you'll just have to imagine it's there. ;) -- Deniz Dogan From tom.davie at gmail.com Fri Jun 12 05:25:53 2009 From: tom.davie at gmail.com (Thomas Davie) Date: Fri Jun 12 05:09:28 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <7b501d5c0906120215t2f79a7ebi4396f94dc85e11a1@mail.gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <6f9f8f4a0906120127x2c1cce01x6abf6cae17f7ee19@mail.gmail.com> <02E3B702-2B26-4513-B5E9-EFDB95E4C4ED@gmail.com> <317ca7670906120147x68e3be10p873f6be9a790aed9@mail.gmail.com> <7b501d5c0906120157w78cb299dj1ab7a5a5189329f1@mail.gmail.com> <7b501d5c0906120215t2f79a7ebi4396f94dc85e11a1@mail.gmail.com> Message-ID: <6DD7CAD2-585C-4CE2-B8C8-1A4E99995011@gmail.com> On 12 Jun 2009, at 11:15, Deniz Dogan wrote: > 2009/6/12 Deniz Dogan : >> 2009/6/12 Tom Lokhorst : >>> There's a SVG version of the logo on the wiki: >>> http://haskell.org/haskellwiki/Thompson-Wheeler_logo >> >> I think the biggest problem making the batteries not look like >> batteries is that they don't look "round". For that we need some >> careful "gradenting" of them, to make the bottoms of them look >> shadowed. >> >> -- >> Deniz Dogan >> > > Attached is a new version of the same idea with a slight gradient on > the batteries and a slightly thicker font for the signs. With various people's ideas taken into account, I've created a new version of my attempt: http://www.cs.kent.ac.uk/people/rpg/tatd2/logo-1.png http://www.cs.kent.ac.uk/people/rpg/tatd2/logo-1.svg I think the yellow/black is easily enough to highlight it as a battery, and saves adding gradients etc, that can become awkward if the logo is ever used in printing. Bob From deniz.a.m.dogan at gmail.com Fri Jun 12 05:32:53 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Fri Jun 12 05:16:23 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <6DD7CAD2-585C-4CE2-B8C8-1A4E99995011@gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <6f9f8f4a0906120127x2c1cce01x6abf6cae17f7ee19@mail.gmail.com> <02E3B702-2B26-4513-B5E9-EFDB95E4C4ED@gmail.com> <317ca7670906120147x68e3be10p873f6be9a790aed9@mail.gmail.com> <7b501d5c0906120157w78cb299dj1ab7a5a5189329f1@mail.gmail.com> <7b501d5c0906120215t2f79a7ebi4396f94dc85e11a1@mail.gmail.com> <6DD7CAD2-585C-4CE2-B8C8-1A4E99995011@gmail.com> Message-ID: <7b501d5c0906120232p61c2414er87e28721920f1e37@mail.gmail.com> 2009/6/12 Thomas Davie : > > On 12 Jun 2009, at 11:15, Deniz Dogan wrote: > >> 2009/6/12 Deniz Dogan : >>> >>> 2009/6/12 Tom Lokhorst : >>>> >>>> There's a SVG version of the logo on the wiki: >>>> http://haskell.org/haskellwiki/Thompson-Wheeler_logo >>> >>> I think the biggest problem making the batteries not look like >>> batteries is that they don't look "round". For that we need some >>> careful "gradenting" of them, to make the bottoms of them look >>> shadowed. >>> >>> -- >>> Deniz Dogan >>> >> >> Attached is a new version of the same idea with a slight gradient on >> the batteries and a slightly thicker font for the signs. > > With various people's ideas taken into account, I've created a new version > of my attempt: > > http://www.cs.kent.ac.uk/people/rpg/tatd2/logo-1.png > http://www.cs.kent.ac.uk/people/rpg/tatd2/logo-1.svg > > I think the yellow/black is easily enough to highlight it as a battery, and > saves adding gradients etc, that can become awkward if the logo is ever used > in printing. > > Bob > While I agree with you on the printing issue, I believe that we can use separate logos for web use (perhaps with gradients, depending on what others think) and another logo for printing. After all, one can argue that any colours apart from greyscale ones are non-optimal for printing as well, but that will not stop anyone from making a colourful logo. -- Deniz Dogan From ttencate at gmail.com Fri Jun 12 06:58:51 2009 From: ttencate at gmail.com (Thomas ten Cate) Date: Fri Jun 12 06:42:21 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <6DD7CAD2-585C-4CE2-B8C8-1A4E99995011@gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <6f9f8f4a0906120127x2c1cce01x6abf6cae17f7ee19@mail.gmail.com> <02E3B702-2B26-4513-B5E9-EFDB95E4C4ED@gmail.com> <317ca7670906120147x68e3be10p873f6be9a790aed9@mail.gmail.com> <7b501d5c0906120157w78cb299dj1ab7a5a5189329f1@mail.gmail.com> <7b501d5c0906120215t2f79a7ebi4396f94dc85e11a1@mail.gmail.com> <6DD7CAD2-585C-4CE2-B8C8-1A4E99995011@gmail.com> Message-ID: On Fri, Jun 12, 2009 at 11:25, Thomas Davie wrote: > With various people's ideas taken into account, I've created a new version > of my attempt: > > http://www.cs.kent.ac.uk/people/rpg/tatd2/logo-1.png > http://www.cs.kent.ac.uk/people/rpg/tatd2/logo-1.svg > > I think the yellow/black is easily enough to highlight it as a battery, and > saves adding gradients etc, that can become awkward if the logo is ever used > in printing. > > Bob I like this last version a lot, except that the ?minus sign should be the same width and height as the horizontal bar of the plus sign. How about this? http://thomas.home.fmf.nl/haskell-platform-logo-bob-mod.svg It's an Inkscape svg file, easily editable. Thomas From sfvisser at cs.uu.nl Fri Jun 12 07:03:18 2009 From: sfvisser at cs.uu.nl (Sebastiaan Visser) Date: Fri Jun 12 06:46:50 2009 Subject: [Haskell-cafe] [ANN] Data.Reify.CSE Message-ID: Hi all, This module[1] implements common sub-expression elimination for graphs generated by the Data.Reify package. (Which is a really neat tool!) The algorithm performs a simple fixed point iteration and is not (consciously) optimized for speed. This package might especially be useful for optimizing simple compilers for referential transparent domain specific languages. Which is exactly the reason I've written this code. An example of the usage is included in the Haddock documentation. Gr, -- Sebastiaan Visser [1] http://hackage.haskell.org/package/data-reify-cse From marcin.kosiba at gmail.com Fri Jun 12 07:12:53 2009 From: marcin.kosiba at gmail.com (Marcin Kosiba) Date: Fri Jun 12 06:56:33 2009 Subject: [Haskell-cafe] Software Transactional Memory and LWN In-Reply-To: <87ab4ff9ze.fsf@malde.org> References: <87ab4ff9ze.fsf@malde.org> Message-ID: <200906121312.56975.marcin.kosiba@gmail.com> On Thursday 11 June 2009, Ketil Malde wrote: > Hi, > > Browsing LWN, I ran across this comment: > > http://lwn.net/Articles/336039/ > > The author makes a bunch of unsubstantiated claims about STM, namely > that all implementations use locking under the hood, and that STM can > live- and deadlock. I've seen a lot of similar sentiments in other > places as well (comp.arch springs to mind). > > Now, I'm no expert on STM, but I was pretty sure these are incorrect, > and I certainly had the impression that Haskell's STM guarantees some > progress - which it couldn't in a deadlock situation. > > Am I wrong? Hi, While I'm no STM expert either, I'd like to remind an often overlooked detail: locks and STM are two different abstractions. While locks provide semantics for running critical sections (informally, parts of code which only one thread can execute) STM provides semantics for atomic actions (informally, actions the intermediate state of which can't be observed by other threads). Now, while an STM implementation can use locks under the hood, it doesn't change the fact that the programmer isn't exposed to using those. Saying STM is bad because it uses locks under the hood is the same as saying that a garbage-collected environment is bad because it uses malloc and free under the hood. As far as the STM-is-better-because-it-doesn't-use-locks theory is concerned, the idea here is that STM doesn't associate a lock with every atomic section. This means that (in an optimistic implementation) any number of threads (and potentially CPU cores) can execute the atomic action in parallel, and if there are few rollbacks, this can lead to better performance than using a single lock[3]. And you can't forget about composability -- code written using locks is less modular than code written using STM. While either optimistic[1] or pessimistic[2] STM can livelock, this can be solved by some sort of exponential backoff algorithm (which does not guarantee progress, just makes a livelock less likely). As far as deadlock is concerned -- if we allow for retry, then as it has already been mentioned, there is a possibility for deadlock. But with STM, you can do deadlock detection by means of cycle detection in wait-for graphs (in much the same way as it is done in DBMS). While now STM usually performs worse than locks, it is an active area of research (even Intel released an experimental STM-supporing C++ compiler[4]). It is also true, that as the number of cores in cpus grows, STM will become more attractive. Thanks! Marcin Kosiba [1]http://en.wikipedia.org/wiki/Software_transactional_memory#Implementation_issues [2]when a long-lived transaction is rolled-back by small transactions [3]you can even switch between STM and locking: General and Efficient Locking without Blocking. Yannis Smaragdakis, Anthony Kay, Reimer Behrends, Michal Young [4]http://software.intel.com/en-us/articles/intel-c-stm-compiler-prototype-edition-20/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: This is a digitally signed message part. Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090612/dfd4f2ee/attachment.bin From pkeir at dcs.gla.ac.uk Fri Jun 12 10:00:12 2009 From: pkeir at dcs.gla.ac.uk (Paul Keir) Date: Fri Jun 12 09:43:42 2009 Subject: [Haskell-cafe] ghci and applicative References: <3CDFB8AFEA98E34CB599475AB11589C82C3DC3@EX2.ad.dcs.gla.ac.uk> <2f9b2d30906120031n286be1c0w28978262a14f100a@mail.gmail.com> Message-ID: <3CDFB8AFEA98E34CB599475AB11589C82C3DC5@EX2.ad.dcs.gla.ac.uk> Thanks Ryan, I'm slowly becoming aware of the effects of Monomorphism. I'll look again at Neil Mitchell's blog post. I guess it's the same thing when I try: > let a = 1 > a + 1.0 I'm taking the "mono" as a clue that the type inferencing will complete after each ghci carriage return; once only. In this example when "a" is set, it is to an Integer. One might imagine ghci could wait until I use "a" somewhere, but that's not how things are. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090612/14048b6b/attachment.html From duncan.coutts at worc.ox.ac.uk Fri Jun 12 10:23:15 2009 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Fri Jun 12 10:26:37 2009 Subject: [Haskell-cafe] ghci and applicative In-Reply-To: <3CDFB8AFEA98E34CB599475AB11589C82C3DC5@EX2.ad.dcs.gla.ac.uk> References: <3CDFB8AFEA98E34CB599475AB11589C82C3DC3@EX2.ad.dcs.gla.ac.uk> <2f9b2d30906120031n286be1c0w28978262a14f100a@mail.gmail.com> <3CDFB8AFEA98E34CB599475AB11589C82C3DC5@EX2.ad.dcs.gla.ac.uk> Message-ID: <1244816595.26313.185.camel@localhost> On Fri, 2009-06-12 at 15:00 +0100, Paul Keir wrote: > Thanks Ryan, I'm slowly becoming aware of the effects of Monomorphism. > I'll look > again at Neil Mitchell's blog post. > > I guess it's the same thing when I try: > > > let a = 1 > > a + 1.0 > > I'm taking the "mono" as a clue that the type inferencing will > complete after each ghci carriage return; once only. In this example > when "a" is set, it is to an Integer. One might imagine ghci could > wait until I use "a" somewhere, but that's not how things are. Or be explicit about it and give it a polymorphic type: Prelude> let a :: Num a => a; a = 1 Prelude> :t a a :: (Num a) => a Prelude> a + 1.0 2.0 Duncan From claudiusmaximus at goto10.org Fri Jun 12 11:04:50 2009 From: claudiusmaximus at goto10.org (Claude Heiland-Allen) Date: Fri Jun 12 10:48:23 2009 Subject: [Haskell-cafe] graphical user interface library for editing graphs? Message-ID: <4A326E92.2090203@goto10.org> Greetings, I have an idea for a project. The eventual aim is rather eccentric, but the specifications I have sketched out are roughly as follows (best viewed with fixed-width font due to diagrams): 0. the graphical user interface is entirely mouse driven, mouse position/clicks/releases are shown by [ ] 1. the world consists of empty space, nodes, and links between nodes 2. nodes may either be filled ("*") or hollow ("o"); call hollow nodes "targets", targets may be "highlighted" ("O") 3a. left-click on empty creates a filled node linked to a target: [ ] * => | o 3b. left-click on a target fills it and links it to a new target: : : [o] * => | o 4a. right-click on empty creates a filled node linked to two targets: [ ] * => / \ o o 4b. right-click on a target fills it and links it to two new targets: : : [o] * => / \ o o 5a. left-click-drag on a filled node with 1 descending link highlights all targets linked under it: : : [*] [*] : => : * * / \ / \ o o O O 5b. left-click-drag as in 5a, when released on a highlighted target, creates a "weak" link (not considered as descending for purposes of 5a) from the original node to that target. that target is filled, all other targets are unhighlighted: : : * * : => :\ * * \ / \ / \| O [O] o [*] 6a. right-click-drag from a filled node at the top of a connected component highlights all targets not in that connected component: [*] * [*] * : | => : | o O 6b. right-click-drag as in 6a, when released on a highlighted target, joins the graphs together, such that the original node fills that target, and all other targets are unhighlighted: * * * : | => | [O] [*] : 7. when a connected component has no targets, double-clicking anywhere on it will launchMissiles My question: can you suggest a library that would make implementing this specification relatively painless? OpenGL-based would be preferable, as I would like to scale the graph under construction automatically to fit the display, and launchMissiles will require something with fast rendering. Thanks, Claude -- http://claudiusmaximus.goto10.org From marlowsd at gmail.com Fri Jun 12 11:13:15 2009 From: marlowsd at gmail.com (Simon Marlow) Date: Fri Jun 12 10:56:47 2009 Subject: [Haskell-cafe] Re: Why do ghc-built binaries use timer_create? In-Reply-To: References: Message-ID: <4A32708B.3010802@gmail.com> On 08/06/2009 22:10, Maur??cio wrote: >> This comes from an issue in haskell-beginner, (...) >> >> For better or worse, this is something that people should not be >> trying in the first place, (...) > > Sure! That's what I sugested in the original question. I'm actually > just curious on why timer_create is used at all. This is probably > just a small detail in program initialization, and maybe a link to > some description of what happens on program initialization (specially > ghc generated binaries) behind the naive user view would do it. timer_create is used in the RTS to create a regular tick signal. The tick signal is used for various things: thread pre-emption, profiling, deadlock detection, and idle-time GC, Cheers, Simon From marlowsd at gmail.com Fri Jun 12 11:23:22 2009 From: marlowsd at gmail.com (Simon Marlow) Date: Fri Jun 12 11:06:55 2009 Subject: [Haskell-cafe] Re: Debugging misbehaving multi-threaded programs In-Reply-To: References: Message-ID: <4A3272EA.8030205@gmail.com> On 11/06/2009 05:40, Evan Klitzke wrote: > I've written a multi-threaded Haskell program that I'm trying to > debug. Basically what's happening is the program runs for a while, and > then at some point one of the threads goes crazy and spins the CPU > while allocating memory; this proceeds until the system runs out of > available memory. I can't fix this without figuring out what code is > being executed in the loop (or at least which thread is misbehaving, > which would narrow things down a lot). > > I was hopeful that I could compile the program with profiling support > and then use +RTS -M100M along with some of the RTS profiling options > and get profiling information on CPU and memory usage at the time that > my program runs out of memory. The thinking here is that nearly all of > the CPU time and heap space will be from the misbehaving thread, so at > that point I could do more investigation into exactly what is > happening. Unfortunately, this doesn't seem to work; whenever the > program terminates due to running out of heap space, the generated > .prof file is empty. We fixed this recently (GHC 6.10.2): http://hackage.haskell.org/trac/ghc/ticket/2592 In 6.12.1 you'll be able to use ThreadScope, our parallel profiling tool. You could try it right now if you're brave enough to compile GHC (it needs GHC 6.11). The ThreadScope code is here: http://code.haskell.org/ThreadScope/ and shortly the Haskell Symposium paper about it will be available (we're just making the final corrections now). Cheers, Simon From flippa at flippac.org Fri Jun 12 11:58:46 2009 From: flippa at flippac.org (Philippa Cowderoy) Date: Fri Jun 12 11:42:31 2009 Subject: [Haskell-cafe] Wiki user accounts Message-ID: <1244822326.28941.29.camel@flippa-eee> I'm hearing reports of people having difficulty obtaining accounts on the Haskell wiki, without which it is impossible to make edits. Currently, account creation is disabled as an anti-spam measure, and the idea is for people to mail the admin and request an account. If this is to work, accounts need to be granted reasonably quickly - so far, I'm aware of a case where after 4 days there has been no response. This is particularly problematic for Anglohaskell, as signups and the like are via the wiki page - as a temporary workaround, I'll (and anyone else willing to lend a hand who already has an account) have to make edits on others' behalf, which is a serious inconvenience for both myself and attendees, as well as something of a barrier to entry. What's going on, and how can we speed things up? -- Philippa Cowderoy From gwern0 at gmail.com Fri Jun 12 12:46:41 2009 From: gwern0 at gmail.com (Gwern Branwen) Date: Fri Jun 12 12:30:15 2009 Subject: [Haskell-cafe] Wiki user accounts In-Reply-To: <1244822326.28941.29.camel@flippa-eee> References: <1244822326.28941.29.camel@flippa-eee> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On Fri, Jun 12, 2009 at 11:58 AM, Philippa Cowderoy wrote: > I'm hearing reports of people having difficulty obtaining accounts on > the Haskell wiki, without which it is impossible to make edits. > Currently, account creation is disabled as an anti-spam measure, and the > idea is for people to mail the admin and request an account. If this is > to work, accounts need to be granted reasonably quickly - so far, I'm > aware of a case where after 4 days there has been no response. > > This is particularly problematic for Anglohaskell, as signups and the > like are via the wiki page - as a temporary workaround, I'll (and anyone > else willing to lend a hand who already has an account) have to make > edits on others' behalf, which is a serious inconvenience for both > myself and attendees, as well as something of a barrier to entry. > > What's going on, and how can we speed things up? Presumably Ashley is busy. http://haskell.org/haskellwiki/?title=Special%3AListusers&group=sysop There are only 3 bureaucrats/admins; one is a dummy account, one is Ashley, and one is John Peterson (who hasn't edited for a year). One solution would be to have Ashley re-enable user registrations. This has been suggested before, but no one knows how bad the spam would be. Another solution would be to sysop a few users to admin/bureaucrat, so that even if a few are inactive or away, the rest can handle requests. If I might suggest some users we might give the bit to: myself, dons, Magnus Therning, Neil Mitchell, and byorgey. All have been editing the wiki for some time, some have administrator experience on Wikipedia, and all have commit bits for various Haskell repos (and so presumably can be trusted). (Of course, this list isn't intended to be exhaustive; they're just who comes to mind looking over Recent Changes.) - -- gwern -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEAREKAAYFAkoyhm8ACgkQvpDo5Pfl1oLTzACfff/rM02Fy/b/VbCwIqgaWO/B 39QAnAkZGKyOTg2zVpDw7NcwNkaED7Ln =KXdO -----END PGP SIGNATURE----- From ttencate at gmail.com Fri Jun 12 13:53:41 2009 From: ttencate at gmail.com (Thomas ten Cate) Date: Fri Jun 12 13:37:11 2009 Subject: [Haskell-cafe] Wiki user accounts In-Reply-To: References: <1244822326.28941.29.camel@flippa-eee> Message-ID: This runs on MediaWiki, right? How about adding a CAPTCHA for account registrations? http://www.mediawiki.org/wiki/Extension:ConfirmEdit And, more generally: http://www.mediawiki.org/wiki/Manual:Combating_spam Cheers, Thomas On Fri, Jun 12, 2009 at 18:46, Gwern Branwen wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA512 > > On Fri, Jun 12, 2009 at 11:58 AM, Philippa Cowderoy wrote: >> I'm hearing reports of people having difficulty obtaining accounts on >> the Haskell wiki, without which it is impossible to make edits. >> Currently, account creation is disabled as an anti-spam measure, and the >> idea is for people to mail the admin and request an account. If this is >> to work, accounts need to be granted reasonably quickly - so far, I'm >> aware of a case where after 4 days there has been no response. >> >> This is particularly problematic for Anglohaskell, as signups and the >> like are via the wiki page - as a temporary workaround, I'll (and anyone >> else willing to lend a hand who already has an account) have to make >> edits on others' behalf, which is a serious inconvenience for both >> myself and attendees, as well as something of a barrier to entry. >> >> What's going on, and how can we speed things up? > > Presumably Ashley is busy. > > http://haskell.org/haskellwiki/?title=Special%3AListusers&group=sysop > > There are only 3 bureaucrats/admins; one is a dummy account, one is > Ashley, and one is John Peterson (who hasn't edited for a year). > > One solution would be to have Ashley re-enable user registrations. > This has been suggested before, but no one knows how bad the spam > would be. Another solution would be to sysop a few users to > admin/bureaucrat, so that even if a few are inactive or away, the rest > can handle requests. > > If I might suggest some users we might give the bit to: myself, dons, > Magnus Therning, Neil Mitchell, and byorgey. All have been editing the > wiki for some time, some have administrator experience on Wikipedia, > and all have commit bits for various Haskell repos (and so presumably > can be trusted). (Of course, this list isn't intended to be > exhaustive; they're just who comes to mind looking over Recent > Changes.) > > - -- > gwern > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v1.4.9 (GNU/Linux) > > iEYEAREKAAYFAkoyhm8ACgkQvpDo5Pfl1oLTzACfff/rM02Fy/b/VbCwIqgaWO/B > 39QAnAkZGKyOTg2zVpDw7NcwNkaED7Ln > =KXdO > -----END PGP SIGNATURE----- > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From gwern0 at gmail.com Fri Jun 12 14:16:41 2009 From: gwern0 at gmail.com (Gwern Branwen) Date: Fri Jun 12 14:00:10 2009 Subject: [Haskell-cafe] Wiki user accounts In-Reply-To: References: <1244822326.28941.29.camel@flippa-eee> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On Fri, Jun 12, 2009 at 1:53 PM, Thomas ten Cate wrote: > This runs on MediaWiki, right? How about adding a CAPTCHA for account > registrations? > > http://www.mediawiki.org/wiki/Extension:ConfirmEdit See http://haskell.org/haskellwiki/Special:Version ConfirmEdit would require an upgrade. - -- gwern -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEAREKAAYFAkoym4gACgkQvpDo5Pfl1oJHAwCghVWZxh2O+zi4WNp2VHBytXTH a6EAn2wlTz/pjp7vUfuaWZJ1WpNuyQ7m =k/yM -----END PGP SIGNATURE----- From daniel.is.fischer at web.de Fri Jun 12 14:22:25 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Fri Jun 12 14:06:43 2009 Subject: [Haskell-cafe] Wiki user accounts In-Reply-To: References: <1244822326.28941.29.camel@flippa-eee> Message-ID: <200906122022.26010.daniel.is.fischer@web.de> Am Freitag 12 Juni 2009 18:46:41 schrieb Gwern Branwen: > There are only 3 bureaucrats/admins; one is a dummy account, one is > Ashley, and one is John Peterson (who hasn't edited for a year). > > One solution would be to have Ashley re-enable user registrations. > This has been suggested before, but no one knows how bad the spam > would be. Another solution would be to sysop a few users to > admin/bureaucrat, so that even if a few are inactive or away, the rest > can handle requests. I support that. > > If I might suggest some users we might give the bit to: myself, dons, > Magnus Therning, Neil Mitchell, and byorgey. I consider these users trustworthy. Which of them besides Gwern are willing to take the job? > All have been editing the > wiki for some time, some have administrator experience on Wikipedia, > and all have commit bits for various Haskell repos (and so presumably > can be trusted). (Of course, this list isn't intended to be > exhaustive; they're just who comes to mind looking over Recent > Changes.) From magnus at therning.org Fri Jun 12 14:36:55 2009 From: magnus at therning.org (Magnus Therning) Date: Fri Jun 12 14:20:30 2009 Subject: [Haskell-cafe] Wiki user accounts In-Reply-To: <200906122022.26010.daniel.is.fischer@web.de> References: <1244822326.28941.29.camel@flippa-eee> <200906122022.26010.daniel.is.fischer@web.de> Message-ID: <4A32A047.9080605@therning.org> Daniel Fischer wrote: > Am Freitag 12 Juni 2009 18:46:41 schrieb Gwern Branwen: >> There are only 3 bureaucrats/admins; one is a dummy account, one is >> Ashley, and one is John Peterson (who hasn't edited for a year). >> >> One solution would be to have Ashley re-enable user registrations. >> This has been suggested before, but no one knows how bad the spam >> would be. Another solution would be to sysop a few users to >> admin/bureaucrat, so that even if a few are inactive or away, the rest >> can handle requests. > > I support that. > >> If I might suggest some users we might give the bit to: myself, dons, >> Magnus Therning, Neil Mitchell, and byorgey. > > I consider these users trustworthy. > Which of them besides Gwern are willing to take the job? Cool, I'm up for it! /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 197 bytes Desc: OpenPGP digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090612/e07e1eb1/signature.bin From felipe.lessa at gmail.com Fri Jun 12 14:47:42 2009 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Fri Jun 12 14:31:17 2009 Subject: [Haskell-cafe] Wiki user accounts In-Reply-To: References: <1244822326.28941.29.camel@flippa-eee> Message-ID: <20090612184742.GA8739@kira.casa> On Fri, Jun 12, 2009 at 07:53:41PM +0200, Thomas ten Cate wrote: > This runs on MediaWiki, right? How about adding a CAPTCHA for account > registrations? What do we avoid at all costs? _______________________________________ |_______________________________________| -- Felipe. From byorgey at seas.upenn.edu Fri Jun 12 15:30:45 2009 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Fri Jun 12 15:13:17 2009 Subject: [Haskell-cafe] ghci and applicative In-Reply-To: <3CDFB8AFEA98E34CB599475AB11589C82C3DC5@EX2.ad.dcs.gla.ac.uk> References: <3CDFB8AFEA98E34CB599475AB11589C82C3DC3@EX2.ad.dcs.gla.ac.uk> <2f9b2d30906120031n286be1c0w28978262a14f100a@mail.gmail.com> <3CDFB8AFEA98E34CB599475AB11589C82C3DC5@EX2.ad.dcs.gla.ac.uk> Message-ID: <20090612193045.GA28717@seas.upenn.edu> On Fri, Jun 12, 2009 at 03:00:12PM +0100, Paul Keir wrote: > Thanks Ryan, I'm slowly becoming aware of the effects of Monomorphism. I'll look > again at Neil Mitchell's blog post. > > I guess it's the same thing when I try: > > > let a = 1 > > a + 1.0 > > I'm taking the "mono" as a clue that the type inferencing will complete after > each ghci carriage return; once only. In this example when "a" is set, it is > to an Integer. One might imagine ghci could wait until I use "a" somewhere, but > that's not how things are. It can wait. You just have to turn off the monomorphism restriction (recommended). Prelude> :set -XNoMonomorphismRestriction Prelude> let a = 1 Prelude> a + 2.0 3.0 You can even add :set -XNoMonomorphismRestriction to your .ghci file so that it is always turned off in ghci. -Brent From byorgey at seas.upenn.edu Fri Jun 12 15:34:36 2009 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Fri Jun 12 15:17:09 2009 Subject: [Haskell-cafe] Wiki user accounts In-Reply-To: <200906122022.26010.daniel.is.fischer@web.de> References: <1244822326.28941.29.camel@flippa-eee> <200906122022.26010.daniel.is.fischer@web.de> Message-ID: <20090612193436.GB28717@seas.upenn.edu> On Fri, Jun 12, 2009 at 08:22:25PM +0200, Daniel Fischer wrote: > Am Freitag 12 Juni 2009 18:46:41 schrieb Gwern Branwen: > > There are only 3 bureaucrats/admins; one is a dummy account, one is > > Ashley, and one is John Peterson (who hasn't edited for a year). > > > > One solution would be to have Ashley re-enable user registrations. > > This has been suggested before, but no one knows how bad the spam > > would be. Another solution would be to sysop a few users to > > admin/bureaucrat, so that even if a few are inactive or away, the rest > > can handle requests. > > I support that. > > > > > If I might suggest some users we might give the bit to: myself, dons, > > Magnus Therning, Neil Mitchell, and byorgey. > > I consider these users trustworthy. > Which of them besides Gwern are willing to take the job? Fine with me. -Brent From lrpalmer at gmail.com Fri Jun 12 18:29:54 2009 From: lrpalmer at gmail.com (Luke Palmer) Date: Fri Jun 12 18:13:24 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <6DD7CAD2-585C-4CE2-B8C8-1A4E99995011@gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <6f9f8f4a0906120127x2c1cce01x6abf6cae17f7ee19@mail.gmail.com> <02E3B702-2B26-4513-B5E9-EFDB95E4C4ED@gmail.com> <317ca7670906120147x68e3be10p873f6be9a790aed9@mail.gmail.com> <7b501d5c0906120157w78cb299dj1ab7a5a5189329f1@mail.gmail.com> <7b501d5c0906120215t2f79a7ebi4396f94dc85e11a1@mail.gmail.com> <6DD7CAD2-585C-4CE2-B8C8-1A4E99995011@gmail.com> Message-ID: <7ca3f0160906121529r13efcb38r1ea0392c63af8165@mail.gmail.com> Nice work, I love this one. :-) On Fri, Jun 12, 2009 at 3:25 AM, Thomas Davie wrote: > > On 12 Jun 2009, at 11:15, Deniz Dogan wrote: > > 2009/6/12 Deniz Dogan : >> >>> 2009/6/12 Tom Lokhorst : >>> >>>> There's a SVG version of the logo on the wiki: >>>> http://haskell.org/haskellwiki/Thompson-Wheeler_logo >>>> >>> >>> I think the biggest problem making the batteries not look like >>> batteries is that they don't look "round". For that we need some >>> careful "gradenting" of them, to make the bottoms of them look >>> shadowed. >>> >>> -- >>> Deniz Dogan >>> >>> >> Attached is a new version of the same idea with a slight gradient on >> the batteries and a slightly thicker font for the signs. >> > > With various people's ideas taken into account, I've created a new version > of my attempt: > > http://www.cs.kent.ac.uk/people/rpg/tatd2/logo-1.png > http://www.cs.kent.ac.uk/people/rpg/tatd2/logo-1.svg > > I think the yellow/black is easily enough to highlight it as a battery, and > saves adding gradients etc, that can become awkward if the logo is ever used > in printing. > > Bob > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090612/c6901131/attachment.html From nfjinjing at gmail.com Fri Jun 12 19:08:22 2009 From: nfjinjing at gmail.com (Jinjing Wang) Date: Fri Jun 12 18:51:50 2009 Subject: [Haskell-cafe] [ANN] Nemesis : easy task management Message-ID: <81ea7d400906121608h549bad46kd7ae63712178566f@mail.gmail.com> You can have a description file named Nemesis, with content nemesis = do clean [ "**/*.hi" , "**/*.o" , "manifest" ] task "dist" $ do sh "cabal clean" sh "cabal configure" sh "cabal sdist" task "i" (sh "ghci -isrc src/System/Nemesis.hs") task "manifest" $ do sh "find . | grep 'hs$' > manifest" then after run `nemesis`, there will be a compiled bin `nem` in your local path, which allows you to do `nem clean` Install with `cabal install nemesis` Cheers, -- jinjing From golubovsky at gmail.com Fri Jun 12 23:58:07 2009 From: golubovsky at gmail.com (Dimitry Golubovsky) Date: Fri Jun 12 23:41:35 2009 Subject: [Haskell-cafe] HSH and IO () Message-ID: John & all, I use HSH in my project where several external programs and Haskell functions need to be piped together: HSH is of great help here. I however came across the situation when one of pipe-connected functions has signature IO (), yet it reads from stdin* and writes to stdout. The documentation mentions "instance ShellCommand (Handle -> Handle -> IO ())" which could be of some help, but in the latest version of HSH on Hackage this instance is commented out. What was the reason of doing that? Is this to be expected in the upcoming versions? Thank you. ---------------------------- * I modelled that by calling getContents, but the actual program will call a foreign library that contains a C function that reads from stdin (that is, FILE *), and that cannot be changed easily. -- Dimitry Golubovsky Anywhere on the Web From asmith9983 at gmail.com Sat Jun 13 00:09:46 2009 From: asmith9983 at gmail.com (A Smith) Date: Fri Jun 12 23:53:16 2009 Subject: [Haskell-cafe] Haskell Meetup groups in Glasgow Message-ID: <1e11fb0e0906122109p1794151eg619617909ff37b4f@mail.gmail.com> Do any Haskell Meetup groups exist in or around Glasgow, an informal get-to-gether in a pub,cafe or wherever ? I'm in Edinburgh, and on my own have been desperately trying to rewire my brain from Perl to Haskell without much success for most of this year. I posted the meetup group question a few weeks ago for Edinburgh but got no response. -- Andrew -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090612/60330738/attachment.html From jgoerzen at complete.org Sat Jun 13 00:46:18 2009 From: jgoerzen at complete.org (John Goerzen) Date: Sat Jun 13 00:29:54 2009 Subject: [Haskell-cafe] Re: HSH and IO () In-Reply-To: References: Message-ID: <4A332F1A.9020508@complete.org> Dimitry Golubovsky wrote: > John & all, > > I use HSH in my project where several external programs and Haskell > functions need to be piped together: HSH is of great help here. > > I however came across the situation when one of pipe-connected > functions has signature IO (), yet it reads from stdin* and writes to > stdout. > > The documentation mentions "instance ShellCommand (Handle -> Handle -> > IO ())" which could be of some help, but in the latest version of HSH > on Hackage this instance is commented out. > > What was the reason of doing that? Is this to be expected in the > upcoming versions? Yes; that's due to the new more flexible way of sending data between processes in HSH -- the Channel. You can replace it with a function that can take any Channel, and produce a result as a Channel of one particular sort. In particular, this instance: instance ShellCommand (Channel -> IO Channel) where is the direct replacement for what you were doing. A Channel is generally a String, a lazy ByteString, or a Handle. There are helper functions in HSH.Channel to deal with these: chanAsString, chanAsBSL, and chanToHandle. You can think of the first two as similar to hGetContents. The last will write the channel out literally to a passed-along handle. So, let's say that you wanted to process input as a String, and before you were given a Handle that you used hGetContents on. Now, you will get a Channel, on which you will call chanAsString. It will convert whatever type of Channel you were handed into a String, lazily. Does that make sense? From radamajna at gmail.com Sat Jun 13 06:03:48 2009 From: radamajna at gmail.com (=?ISO-8859-1?Q?Radam=E9s_Ajna?=) Date: Sat Jun 13 05:47:38 2009 Subject: [Haskell-cafe] Atom - help. Message-ID: <17afcbce0906130303o580bc4bfoadc70837fcb6f30c@mail.gmail.com> hi there, I've been working with haskell and atom dsl, however I'm new to haskell.. John Van Enk inspired me with programming arduino->atmegas , with haskell, So here is my problem. With an action , action :: ([String] -> String) -> [UE] -> Atom () , it's possible make calls to some precoded C functions like, setLED v = action (\[x] -> "setLED(" ++ x ++ ")") [v'] where v' = ue . value $ v where setLed is a precode function. I want call a precoded C function that returns some value, but action always give me Atom () , that's I would like to do but I don't know how .. Atom (V Int8) < ---- "int read()" thanks... related links http://hackage.haskell.org/package/atom-0.0.5 http://blog.sw17ch.com/wordpress/?p=111 http://leepike.wordpress.com/2009/05/05/an-atomic-fibonacci-server-exploring-the-atom-haskell-dsl/ Radam?s From ithika at gmail.com Sat Jun 13 06:33:24 2009 From: ithika at gmail.com (Dougal Stanton) Date: Sat Jun 13 06:16:53 2009 Subject: [Haskell-cafe] Haskell Meetup groups in Glasgow In-Reply-To: <1e11fb0e0906122109p1794151eg619617909ff37b4f@mail.gmail.com> References: <1e11fb0e0906122109p1794151eg619617909ff37b4f@mail.gmail.com> Message-ID: <2d3641330906130333t4a324459sc35b84a45317960c@mail.gmail.com> On Sat, Jun 13, 2009 at 5:09 AM, A Smith wrote: > Do any Haskell Meetup groups exist in or around Glasgow, an informal > get-to-gether in a pub,cafe or wherever ? > I'm in Edinburgh, and on my own have been desperately trying to rewire my > brain from Perl to Haskell without much success for most of this year. I > posted? the meetup group question a few weeks ago for Edinburgh but got no > response. Sorry, I didn't see your Edinburgh message. I am also in Edinburgh and though I don't know of any Haskell meet-ups I don't think it would be hard to get critical mass for one. Edinburgh Uni teaches it to the first years (AFAIK), Philip Wadler works here, and the ICFP and Haskell Symposium are going to be held here later in the year. There must be more than just the two of us! :-) Cheers, D -- Dougal Stanton dougal@dougalstanton.net // http://www.dougalstanton.net From golubovsky at gmail.com Sat Jun 13 08:20:10 2009 From: golubovsky at gmail.com (Dimitry Golubovsky) Date: Sat Jun 13 08:03:37 2009 Subject: [Haskell-cafe] Re: HSH and IO () In-Reply-To: <4A332F1A.9020508@complete.org> References: <4A332F1A.9020508@complete.org> Message-ID: John, Thanks for the reply. In this case, would the body of my function run in a separate thread via forkProcess (that's what is needed, maybe I didn't make it clear)? In my previous project, I had to do like this (probably not very portable, at least requires System.Posix): ======================================================== (fd1, fd2) <- createPipe hscfd <- fileToFd hscFile hscpid <- forkProcess $ redirFd fd1 0 $ redirFd fd2 (-1) $ redirFd hscfd 1 $ hsffigMain (fromJust $ gccPath dopt) (inclDirs dopt) minusD gccpid <- forkProcess $ redirFd fd2 1 $ executeFile (fromJust $ gccPath dopt) False (["-E", "-dD"] ++ minusI ++ minusD ++ [incFile]) Nothing closeFd hscfd closeFd fd1 closeFd fd2 gccrt <- getProcessStatus True False gccpid hscrt <- getProcessStatus True False hscpid ======================================================== where hscpid corresponds to a process that runs a Haskell function (hsffigMain :: a -> b -> c -> IO ()) defined within the same program, and gccpid runs an external program (gcc), and they are piped together. I am trying to avoid writing this mess using HSH. I'm just trying to find out whether this was already done. If not, what is the best way to write the above to be integrated into HSH (I'd be glad to contribute). Thank you. On Sat, Jun 13, 2009 at 12:46 AM, John Goerzen wrote: > > You can replace it with a function that can take any Channel, and > produce a result as a Channel of one particular sort. ?In particular, > this instance: > > instance ShellCommand (Channel -> IO Channel) where > -- Dimitry Golubovsky Anywhere on the Web From keithshep at gmail.com Sat Jun 13 10:03:05 2009 From: keithshep at gmail.com (Keith Sheppard) Date: Sat Jun 13 09:46:32 2009 Subject: [Haskell-cafe] curious about sum Message-ID: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> Is there any reason that sum isn't strict? I can't think of any case where that is a good thing. Prelude> sum [0 .. 1000000] *** Exception: stack overflow -Keith -- keithsheppard.name From jochem at functor.nl Sat Jun 13 10:09:28 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Sat Jun 13 09:52:59 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> Message-ID: <4A33B318.7090203@functor.nl> Keith Sheppard wrote: > Is there any reason that sum isn't strict? I can't think of any case > where that is a good thing. > > Prelude> sum [0 .. 1000000] > *** Exception: stack overflow It is useful if the (+) is nonstrict; although I cannot think of any useful mathematical structure where (+) would be nonstrict. Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From deniz.a.m.dogan at gmail.com Sat Jun 13 10:17:57 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Sat Jun 13 10:01:24 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <4A33B318.7090203@functor.nl> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <4A33B318.7090203@functor.nl> Message-ID: <7b501d5c0906130717k1b6ff394x3abe866aa84d2fa2@mail.gmail.com> 2009/6/13 Jochem Berndsen : > Keith Sheppard wrote: >> Is there any reason that sum isn't strict? I can't think of any case >> where that is a good thing. >> >> Prelude> sum [0 .. 1000000] >> *** Exception: stack overflow > > It is useful if the (+) is nonstrict; although I cannot think of any > useful mathematical structure where (+) would be nonstrict. I remember needing a non-strict sum at least once, but I do not remember the exact application. But imagine having a (very) long list of numbers and you want to do A if the sum exceeds a small number, otherwise B. if sum [0..100000] > 10 then A else B However, this idea didn't work, because of strictness. -- Deniz Dogan From deduktionstheorem at web.de Sat Jun 13 10:26:49 2009 From: deduktionstheorem at web.de (Stephan Friedrichs) Date: Sat Jun 13 10:10:33 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <4A33B318.7090203@functor.nl> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <4A33B318.7090203@functor.nl> Message-ID: <4A33B729.9070609@web.de> Jochem Berndsen wrote: > Keith Sheppard wrote: >> Is there any reason that sum isn't strict? I can't think of any case >> where that is a good thing. >> >> Prelude> sum [0 .. 1000000] >> *** Exception: stack overflow > > It is useful if the (+) is nonstrict; although I cannot think of any > useful mathematical structure where (+) would be nonstrict. What about some numeric representations? type MyNum = [()] instance Num MyNum where (+) = (++) Regards, Stephan -- Fr?her hie? es ja: Ich denke, also bin ich. Heute wei? man: Es geht auch so. - Dieter Nuhr From keithshep at gmail.com Sat Jun 13 10:47:46 2009 From: keithshep at gmail.com (Keith Sheppard) Date: Sat Jun 13 10:31:13 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <4A33B729.9070609@web.de> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <4A33B318.7090203@functor.nl> <4A33B729.9070609@web.de> Message-ID: <92e42b740906130747u28525d6ag49b7b0c6766aa35a@mail.gmail.com> That's an interesting example. I guess a lazy number system like that would work nicely for Deniz's use case. On Sat, Jun 13, 2009 at 10:26 AM, Stephan Friedrichs wrote: > Jochem Berndsen wrote: >> Keith Sheppard wrote: >>> Is there any reason that sum isn't strict? I can't think of any case >>> where that is a good thing. >>> >>> Prelude> sum [0 .. 1000000] >>> *** Exception: stack overflow >> >> It is useful if the (+) is nonstrict; although I cannot think of any >> useful mathematical structure where (+) would be nonstrict. > > What about some numeric representations? > > type MyNum = [()] > > instance Num MyNum where > ?(+) = (++) > > Regards, > Stephan > > -- > > Fr?her hie? es ja: Ich denke, also bin ich. > Heute wei? man: Es geht auch so. > > ?- Dieter Nuhr > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- keithsheppard.name From jochem at functor.nl Sat Jun 13 11:00:36 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Sat Jun 13 10:44:05 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <7b501d5c0906130717k1b6ff394x3abe866aa84d2fa2@mail.gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <4A33B318.7090203@functor.nl> <7b501d5c0906130717k1b6ff394x3abe866aa84d2fa2@mail.gmail.com> Message-ID: <4A33BF14.6000406@functor.nl> Deniz Dogan wrote: > 2009/6/13 Jochem Berndsen : >> Keith Sheppard wrote: >>> Is there any reason that sum isn't strict? I can't think of any case >>> where that is a good thing. >>> >>> Prelude> sum [0 .. 1000000] >>> *** Exception: stack overflow >> It is useful if the (+) is nonstrict; although I cannot think of any >> useful mathematical structure where (+) would be nonstrict. > > I remember needing a non-strict sum at least once, but I do not > remember the exact application. But imagine having a (very) long list > of numbers and you want to do A if the sum exceeds a small number, > otherwise B. > > if sum [0..100000] > 10 then A else B > > However, this idea didn't work, because of strictness. You can only do such things if you know that all entries of your list are nonnegative. That requires a custom solution anyway (not to mention the fact that to determine whether x > 10 or not, we need to explicitly compute x). Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From tomahawkins at gmail.com Sat Jun 13 11:39:07 2009 From: tomahawkins at gmail.com (Tom Hawkins) Date: Sat Jun 13 11:22:55 2009 Subject: [Haskell-cafe] Atom - help. In-Reply-To: <594c1e830906130837m4c1acaaal348744a7ff64f646@mail.gmail.com> References: <17afcbce0906130303o580bc4bfoadc70837fcb6f30c@mail.gmail.com> <594c1e830906130837m4c1acaaal348744a7ff64f646@mail.gmail.com> Message-ID: <594c1e830906130839t28a108dcuc2eff6516e4743f1@mail.gmail.com> Calling foreign functions that return values is problematic for the compiler -- I haven't invested enough time to come up with a good solution. The work around is to assign the result to an external variable. ?The drawback is the result will not be available until the rule executing the action has completed. results <- bool' "result" ? -- Global, external variable to capture result. action (\ [a, b, c] -> printf "result = function(%s, %s %s)" a b c) [a, b, c] -Tom On Sat, Jun 13, 2009 at 5:03 AM, Radam?s Ajna wrote: > hi there, > > I've been working with haskell and atom dsl, however I'm new to haskell.. > John Van Enk inspired me with programming arduino->atmegas , with haskell, > So here is my problem. > With an action , action :: ([String] -> String) -> [UE] -> Atom () , > it's possible make calls to some precoded C functions like, > > setLED v = action (\[x] -> "setLED(" ++ x ++ ")") [v'] > ? ?where v' = ue . value $ v > > where setLed is a precode function. > > I want call a precoded C function that returns some value, but action > always give me Atom () , > that's I would like to do but I don't know how .. > > ? Atom (V Int8) < ?---- "int read()" > > > thanks... > related links > http://hackage.haskell.org/package/atom-0.0.5 > http://blog.sw17ch.com/wordpress/?p=111 > http://leepike.wordpress.com/2009/05/05/an-atomic-fibonacci-server-exploring-the-atom-haskell-dsl/ > > > > Radam?s > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From daniel.is.fischer at web.de Sat Jun 13 11:41:54 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sat Jun 13 11:26:09 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <4A33BF14.6000406@functor.nl> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <7b501d5c0906130717k1b6ff394x3abe866aa84d2fa2@mail.gmail.com> <4A33BF14.6000406@functor.nl> Message-ID: <200906131741.54193.daniel.is.fischer@web.de> Am Samstag 13 Juni 2009 17:00:36 schrieb Jochem Berndsen: > Deniz Dogan wrote: > > 2009/6/13 Jochem Berndsen : > >> Keith Sheppard wrote: > >>> Is there any reason that sum isn't strict? I can't think of any case > >>> where that is a good thing. > >>> > >>> Prelude> sum [0 .. 1000000] > >>> *** Exception: stack overflow > >> > >> It is useful if the (+) is nonstrict; although I cannot think of any > >> useful mathematical structure where (+) would be nonstrict. > > > > I remember needing a non-strict sum at least once, but I do not > > remember the exact application. But imagine having a (very) long list > > of numbers and you want to do A if the sum exceeds a small number, > > otherwise B. > > > > if sum [0..100000] > 10 then A else B > > > > However, this idea didn't work, because of strictness. > > You can only do such things if you know that all entries of your list > are nonnegative. That requires a custom solution anyway (not to mention > the fact that to determine whether x > 10 or not, we need to explicitly > compute x). Well, if you have lazy Peano numbers of any kind, you know that all entries are non- negative and you needn't evaluate x fully to determine whether it's > 10. Isn't that the point why one would use lazy numbers at all? > > Regards, From jochem at functor.nl Sat Jun 13 11:50:05 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Sat Jun 13 11:33:33 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <200906131741.54193.daniel.is.fischer@web.de> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <7b501d5c0906130717k1b6ff394x3abe866aa84d2fa2@mail.gmail.com> <4A33BF14.6000406@functor.nl> <200906131741.54193.daniel.is.fischer@web.de> Message-ID: <4A33CAAD.7020709@functor.nl> Daniel Fischer wrote: > Am Samstag 13 Juni 2009 17:00:36 schrieb Jochem Berndsen: >> Deniz Dogan wrote: >>> 2009/6/13 Jochem Berndsen : >>>> Keith Sheppard wrote: >>>>> Is there any reason that sum isn't strict? I can't think of any case >>>>> where that is a good thing. >>>>> >>>>> Prelude> sum [0 .. 1000000] >>>>> *** Exception: stack overflow >>>> It is useful if the (+) is nonstrict; although I cannot think of any >>>> useful mathematical structure where (+) would be nonstrict. >>> I remember needing a non-strict sum at least once, but I do not >>> remember the exact application. But imagine having a (very) long list >>> of numbers and you want to do A if the sum exceeds a small number, >>> otherwise B. >>> >>> if sum [0..100000] > 10 then A else B >>> >>> However, this idea didn't work, because of strictness. >> You can only do such things if you know that all entries of your list >> are nonnegative. That requires a custom solution anyway (not to mention >> the fact that to determine whether x > 10 or not, we need to explicitly >> compute x). > > Well, if you have lazy Peano numbers of any kind, you know that all entries are non- > negative and you needn't evaluate x fully to determine whether it's > 10. Isn't that the > point why one would use lazy numbers at all? Yes. (That's what I meant with 'custom solution', using Peano numbers instead of Ints or Integers.) Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From invite+yn4n5bx at facebookmail.com Sat Jun 13 12:09:31 2009 From: invite+yn4n5bx at facebookmail.com (Rakesh Malik) Date: Sat Jun 13 11:52:59 2009 Subject: [Haskell-cafe] Check out my photos on Facebook Message-ID: Hi haskell-cafe@haskell.org, I set up a Facebook profile where I can post my pictures, videos and events and I want to add you as a friend so you can see it. First, you need to join Facebook! Once you join, you can also create your own profile. Thanks, Rakesh To sign up for Facebook, follow the link below: http://www.facebook.com/p.php?i=898160075&k=Z5E62YTRPW2CUGGAX144X3&r haskell-cafe@haskell.org was invited to join Facebook by Rakesh Malik. If you do not wish to receive this type of email from Facebook in the future, please click on the link below to unsubscribe. http://www.facebook.com/o.php?k=917e28&u=531922198&mid=9dcc69G1fb47d16G0G8 Facebook's offices are located at 1601 S. California Ave., Palo Alto, CA 94304. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090613/ada0e09b/attachment.html From deniz.a.m.dogan at gmail.com Sat Jun 13 12:25:11 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Sat Jun 13 12:08:38 2009 Subject: [Haskell-cafe] Check out my photos on Facebook In-Reply-To: References: Message-ID: <7b501d5c0906130925i3ecbb3eted6268a0f66f989f@mail.gmail.com> 2009/6/13 Rakesh Malik : > To sign up for Facebook, follow the link below: > http://www.facebook.com/p.php?i=898160075&k=Z5E62YTRPW2CUGGAX144X3&r I followed that link, in case anyone cares. -- Deniz Dogan From conal at conal.net Sat Jun 13 13:23:45 2009 From: conal at conal.net (Conal Elliott) Date: Sat Jun 13 13:07:31 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> Message-ID: You can make numeric class instances from arbitrary Applicatives [1]. I imagine a lot of them (e.g. Stream) would want at least some non-strictness. We might provide strict alternatives for sum and product. I wonder what else. [1] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/applicative-numbers - Conal On Sat, Jun 13, 2009 at 7:03 AM, Keith Sheppard wrote: > Is there any reason that sum isn't strict? I can't think of any case > where that is a good thing. > > Prelude> sum [0 .. 1000000] > *** Exception: stack overflow > > -Keith > -- > keithsheppard.name > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090613/f4f45d07/attachment.html From deniz.a.m.dogan at gmail.com Sat Jun 13 14:56:25 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Sat Jun 13 14:39:56 2009 Subject: [Haskell-cafe] ANNOUNCE: hunp-0.0 Message-ID: <7b501d5c0906131156h30795a94l49f3a87f86129e4f@mail.gmail.com> Inspired by the CLI utility "unp", which was nice but lacked some DWIM functionality, I developed hunp (or h?np, but pronounced hump because it's easier). It automagically calls the right "unpacker" program for you and works on both files and directories: $ hunp ~/download/something/ ...finds ~/download/something/hello.r00 and calls "unrar x ~/download/something/hello.r00". $ hunp ~/howdy.tar.gz ...calls "tar zxvf ~/howdy.tar.gz" Get it from http://hackage.haskell.org/package/hunp or from git://github.com/skorpan/hunp.git Enjoy! -- Deniz Dogan PS. I was unable to find the thread on how to properly announce things on the mailing lists, so I hope everyone is okay with this going only to Haskell caf?. From jake.mcarthur at gmail.com Sat Jun 13 16:18:47 2009 From: jake.mcarthur at gmail.com (Jake McArthur) Date: Sat Jun 13 16:02:17 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> Message-ID: <4A3409A7.500@gmail.com> Keith Sheppard wrote: > Is there any reason that sum isn't strict? I can't think of any case > where that is a good thing. > > Prelude> sum [0 .. 1000000] > *** Exception: stack overflow As others have said, there are cases where non-strictness is what you want. And if you are using a type that is strict (the common case), GHC's optimizations will catch it. The historical reason for this is that foldl' is not Haskell 98, only foldl. - Jake From byorgey at seas.upenn.edu Sat Jun 13 17:28:44 2009 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Sat Jun 13 17:12:10 2009 Subject: [Haskell-cafe] Haskell Weekly News: Issue 121 - June 13, 2009 Message-ID: <20090613212844.GA20072@seas.upenn.edu> --------------------------------------------------------------------------- Haskell Weekly News http://sequence.complete.org/hwn/20090613 Issue 121 - June 13, 2009 --------------------------------------------------------------------------- Welcome to issue 121 of HWN, a newsletter covering developments in the [1]Haskell community. Announcements purely functional lazy non-deterministic programming. Sebastian Fischer [2]announced the [3]explicit-sharing library, which supports lazy functional-logic programming in Haskell. nntp 0.0.1. Maciej Piechotka [4]announced the release of [5]nntp, a library to connect to nntp (i.e. mainly USENET) servers. OpenGLRaw 1.0.0.0. Sven Panne [6]announced the release of [7]OpenGLRaw, a low-level binding for OpenGL. The eventual goal is to make the OpenGL package easier to install, more modular and a bit more flexible. pgm-0.1 on Hackage. Frederick Ross [8]announced [9]pgm, a pure Haskell library to read and write PGM images. It seamlessly handles the divide between 1 and 2 byte per pixel images; reads and writes UArrays; can handle multiple PGMs concatenated one after another in a file; and encodes and decodes all comments in the PGM header, which can be used to drop arbitrary metadata into files in a human readable manner. iteratee-0.2.1 released. John Lato [10]announced the release of [11]iteratee-0.2.1, a major update to the iteratee library. This library provides types and functions for performing enumerator/iteratee based I/O operations in Haskell, as [12]described by Oleg. The new version is a large redesign, including support for resumable exceptions and a greatly simplified interface. testrunner-0.9. Reinier Lamers [13]announced [14]testrunner, a new framework for running unit test. It can run unit tests in parallel; can run QuickCheck and HUnit tests as well as simple boolean expressions; and comes with a ready-made main function for your unit test executable. serial-0.2. Frederick Ross [15]announced version 0.2 of [16]serial, a library for working with line-oriented POSIX serial ports. hunp-0.0. Deniz Dogan [17]announced [18]hunp, a command-line utility which automagically calls the right "unpacker" program for you and works on both files and directories. Nemesis : easy task management. Jinjing Wang [19]announced a new release of [20]nemesis, a simple rake-like task management tool. Data.Reify.CSE. Sebastiaan Visser [21]announced the [22]data-reify-cse module, which implements common sub-expression elimination for graphs generated by the Data.Reify package. This package might especially be useful for optimizing simple compilers for referentially transparent domain specific languages. Hac phi accommodation: register by June 15 for reduced rate! Brent Yorgey [23]reminded anyone interested in attending [24]Hac phi that Monday 15 June is the deadline for getting a special reduced hotel rate. alloy-1.0.0 (generic programming). Neil Brown [25]announced the [26]first release of the [27]Allow generic programming library. It is intended to be a fairly fast blend of several other generics approaches, such as SYB (but without the dynamic typing) and Uniplate (but allowing an arbitrary number of target types), for performing transformations on specific types in large tree structures. StrictBench 0.1 - Benchmarking code through strict evaluation. R.A. Niemeijer [28]announced the release of [29]StrictBench, a library for timing full evaluation of values. haskeem 0.7.0 uploaded to hackage. Uwe Hollerbach [30]announced [31]haskeem, a small scheme interpreter written in Haskell. numtype 1.0 -- Type-level (low cardinality) integers. Bjorn Buckwalter [32]announced the [33]Numeric.NumType module, now released as its own package, which implements a unary type-level representation of integers, supporting addition, subtraction, multiplication, and division. Google Summer of Code Progress updates from participants in the 2008 [34]Google Summer of Code. space profiling. Gergely Patai has some [35]pretty graphs generated by his profiling library. haskell-src-exts. Niklas Broberg is [36]quite close to releasing haskell-src-exts 1.0.0, as soon as he has full and correct support for (almost) everything code-related, with only a few things left to do. He also wrote [37]a post explaining the intricacies of parsing code containing the 'forall' keyword (well, whether it is a keyword depends on which extensions are enabled...) fast darcs. Petr Rockai made a bit less progress this week, with finals and other things interfering, but [38]made some progress on some documentation, tracking down a performance regression, and other things. Discussion Adding an ignore function to Control.Monad. Gwern Branwen [39]proposed adding an 'ignore' function to Control.Monad which explicitly changes an m a into a m (). Bikeshedding (and some useful discussion) ensued. Wiki user accounts. Philippa Cowderoy began a [40]discussion of what to do about the current situation with wiki user accounts (namely, that account creation is disabled due to spam, and the one maintainer of the wiki can't always respond to account creation requests instantly). Lightweight type-level dependent programming in Haskell. Ryan Ingram made an interesting [41]post about implementing lightweight closed type classes in Haskell. who's up for a hackathon? (ICFP, late Aug, early Sept). Eric Kow [42]wanted to know who would be interested in having a hackathon immediately before or after ICFP in Edinburgh. Jobs Galois is hiring functional programmers. Don Stewart [43]announced that [44]Galois is hiring! See the announcement for more details. Blog noise [45]Haskell news from the [46]blogosphere. Blog posts from people new to the Haskell community are marked with >>>, be sure to welcome them! * Niklas Broberg: [47]GSoC status report, week 3. * Joachim Breitner: [48]Introducing L-seed. * Conal Elliott: [49]Memoizing polymorphic functions - part two. * London Haskell Users Group: [50]Next Meeting: Sean Leather, Fun and generic things to do with EMGM. * David Amos: [51]It's on Hackage!. Haskell for Maths is now just a cabal-install away. * Michael Snoyman: [52]Filename encoding issues. * David Amos: [53]Permutation groups. * Edward Kmett: [54]Recursion Schemes: A Field Guide (Redux). * mightybyte: [55]Intro to HAppS-State. * Conal Elliott: [56]Memoizing polymorphic functions - part one. * Lennart Augustsson: [57]More LLVM. * Roman Cheplyaka: [58]Don't play with your monads. * Galois, Inc: [59]Tech Talk: Orc in Haskell. * Petr Rockai: [60]soc progress 3. Progress on Petr's GSoC darcs project. * Magnus Therning: [61]Using msmtp with darcs. * Erik de Castro Lopo: [62]Debian Maintainer. Erik is now a Debian maintainer, and plans to give Haskell on Debian a much-needed facelift! * Niklas Broberg: [63]What's in a forall?. More Haskell parsing fun. * Well-Typed.Com: [64]GHC, primops and exorcising GMP. * Niklas Broberg: [65]What's in a forall?. More than you might expect! * >>> Zsol: [66]Visualizing the graphrewrite process behind Haskell. Work on the [67]visual-graphrewrite package. * Eric Kow (kowey): [68]testrunner for practical quickcheck. * Sebastian Fischer: [69]Explicit sharing of monadic effects. Purely functional, lazy, non-deterministic programming! * LHC Team: [70]New backend. * >>> James McNeill: [71]Messing with Haskell. * Dan Piponi (sigfpe): [72]Hashing Molecules. * Shin-Cheng Mu: [73]Longest Segment Satisfying Suffix and Overlap-Closed Predicates. * David Amos: [74]Simple graphs with Math.Combinatorics.Graph. David shows off his Haskell for Maths library. * Gergely Patai: [75]More colourful graphs. Graphs from Gergely's GSoC project on profiling. * Bryan O'Sullivan: [76]Case conversion and text 0.3. The text module gets solid, standards-compliant case conversion. * Bjorn Buckwalter: [77]numtype 1.0: Type-level (low cardinality) integers. * >>> J?rn Dinkla: [78]Parallelization with Haskell - Easy as can be. Quotes of the Week * sjanssen: in our sub-culture, "considered harmful" means "burn it with fire" * quicksilver: after all, anyone who insists on talking about himself in the third person is clearly someone to be reckoned with. About the Haskell Weekly News New editions are posted to [79]the Haskell mailing list as well as to [80]the Haskell Sequence and [81]Planet Haskell. [82]RSS is also available, and headlines appear on [83]haskell.org. To help create new editions of this newsletter, please see the information on [84]how to contribute. Send stories to byorgey at cis dot upenn dot edu. The darcs repository is available at darcs get [85]http://code.haskell.org/~byorgey/code/hwn/ . References 1. http://haskell.org/ 2. http://article.gmane.org/gmane.comp.lang.haskell.libraries/11265 3. http://sebfisch.github.com/explicit-sharing 4. http://article.gmane.org/gmane.comp.lang.haskell.general/17271 5. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/nntp 6. http://www.haskell.org//pipermail/haskell/2009-June/021402.html 7. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/OpenGLRaw 8. http://article.gmane.org/gmane.comp.lang.haskell.general/17263 9. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/pgm 10. http://article.gmane.org/gmane.comp.lang.haskell.general/17262 11. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/iteratee 12. http://okmij.org/ftp/Streams.html#iteratee 13. http://article.gmane.org/gmane.comp.lang.haskell.general/17258 14. http://projects.haskell.org/testrunner/ 15. http://article.gmane.org/gmane.comp.lang.haskell.general/17257 16. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/serial 17. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59843 18. http://hackage.haskell.org/package/hunp 19. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59824 20. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/nemesis 21. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59807 22. http://hackage.haskell.org/package/data-reify-cse 23. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59741 24. http://haskell.org/haskellwiki/Hac_%CF%86 25. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59631 26. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/alloy 27. http://twistedsquare.com/Alloy-Tutorial.pdf 28. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59605 29. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/StrictBench 30. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59551 31. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/haskeem 32. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59543 33. http://dimensional.googlecode.com/ 34. http://hackage.haskell.org/trac/summer-of-code/wiki/SoC2008 35. http://just-bottom.blogspot.com/2009/06/more-colourful-graphs.html 36. http://nibrofun.blogspot.com/2009/06/gsoc-status-report-week-3.html 37. http://nibrofun.blogspot.com/2009/06/whats-in-forall.html 38. http://web.mornfall.net/blog/soc_progress_3.html 39. http://thread.gmane.org/gmane.comp.lang.haskell.libraries/11278 40. http://thread.gmane.org/gmane.comp.lang.haskell.cafe/59814 41. http://thread.gmane.org/gmane.comp.lang.haskell.cafe/59749 42. http://thread.gmane.org/gmane.comp.lang.haskell.cafe/59737 43. http://article.gmane.org/gmane.comp.lang.haskell.general/17264 44. http://www.galois.com/ 45. http://planet.haskell.org/ 46. http://haskell.org/haskellwiki/Blog_articles 47. http://nibrofun.blogspot.com/2009/06/gsoc-status-report-week-3.html 48. https://www.joachim-breitner.de/blog/archives/330-Introducing-L-seed.html 49. http://conal.net/blog/posts/memoizing-polymorphic-functions-part-two/ 50. http://www.londonhug.net/2009/06/12/next-meeting-sean-leather-fun-and-generic-things-to-do-with-emgm/ 51. http://haskellformaths.blogspot.com/2009/06/its-on-hackage.html 52. http://blog.snoyman.com/2009/06/11/filename-encoding-issues/ 53. http://haskellformaths.blogspot.com/2009/06/permutation-groups.html 54. http://comonad.com/reader/2009/recursion-schemes/ 55. http://softwaresimply.blogspot.com/2008/02/intro-to-happs-state.html 56. http://conal.net/blog/posts/memoizing-polymorphic-functions-part-one/ 57. http://augustss.blogspot.com/2009/06/more-llvm-recently-someone-asked-me-on.html 58. http://ro-che.blogspot.com/2009/06/dont-play-with-your-monads.html 59. http://www.galois.com/blog/2009/06/09/tech-talk-orc/ 60. http://web.mornfall.net/blog/soc_progress_3.html 61. http://therning.org/magnus/archives/656 62. http://www.mega-nerd.com/erikd/Blog/CodeHacking/Debian/debian_maintainer.html 63. http://nibrofun.blogspot.com/2009/06/whats-in-forall.html 64. http://blog.well-typed.com/2009/06/ghc-primops-and-exorcising-gmp/ 65. http://nibrofun.blogspot.com/2009/06/whats-in-forall.html 66. http://lazybottom.blogspot.com/2009/06/visualizing-graphrewrite-process-behind.html 67. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/visual-graphrewrite 68. http://koweycode.blogspot.com/2009/06/testrunner-for-practical-quickcheck.html 69. http://www-ps.informatik.uni-kiel.de/~sebf/haskell/explicit-sharing.html 70. http://lhc-compiler.blogspot.com/2009/06/new-backend.html 71. http://playtechs.blogspot.com/2009/06/messing-with-haskell.html 72. http://blog.sigfpe.com/2009/06/hashing-molecules.html 73. http://www.iis.sinica.edu.tw/~scm/2009/longest-segment-satisfying-suffix-and-overlap-closed-predicates/ 74. http://haskellformaths.blogspot.com/2009/06/simple-graphs-with-mathcombinatoricsgra.html 75. http://just-bottom.blogspot.com/2009/06/more-colourful-graphs.html 76. http://www.serpentine.com/blog/2009/06/07/case-conversion-and-text-03/ 77. http://flygdynamikern.blogspot.com/2009/06/announce-numtype-10-type-level-low.html 78. http://blog.dinkla.net/?p=15 79. http://www.haskell.org/mailman/listinfo/haskell 80. http://sequence.complete.org/ 81. http://planet.haskell.org/ 82. http://sequence.complete.org/node/feed 83. http://haskell.org/ 84. http://haskell.org/haskellwiki/HWN 85. http://code.haskell.org/~byorgey/code/hwn/ From simon at joyful.com Sat Jun 13 18:07:30 2009 From: simon at joyful.com (Simon Michael) Date: Sat Jun 13 17:51:06 2009 Subject: [Haskell-cafe] ANN: hledger 0.6 released Message-ID: <940603EB-D7A5-40D4-BEF3-E598BB571A3B@joyful.com> I'm pleased to announce the release of hledger 0.6. For docs, online demo etc., see http://hledger.org . Some pre-built binaries are now available at http://hledger.org/ binaries . Or, install with: cabal install hledger [-fhapps] [-fvty]. (Using the latest Haskell Platform, "cabal install hledger -fhapps" works on gnu/ linux, mac and windows. Hurrah!) I'd like to hear feedback, especially if you hit trouble getting started. Happy tracking! - Simon (sm) 2009/06/13 hledger 0.6 ...................... * now cabal-installable on unix, mac, and windows, with Haskell Platform * provide experimental platform binaries * parsing: fix a silly failure to open ledger file paths containing ~ * parsing: show better errors for unbalanced transaction and missing default year * parsing: allow parentheses and brackets inside account names, as ledger does * parsing: fail on empty account name components, don't just ignore * add: description passed as arguments now affects first transaction only * add: better handling of virtual postings and default amounts * print, register: show virtual accounts bracketed/parenthesised * web: improved web ui supporting full patterns & period expressions * new "stats" command reports some ledger statistics * many dev/doc/deployment infrastructure improvements * move website into darcs repo, update home page * move issue tracker to google code Release stats: * Contributors: Simon Michael * Days since last release: 21 * Commits: 94 * Lines of non-test code: 2865 * Tests: 82 * Test coverage: 53% expressions * Known errors: 3 (inconsistent eliding, vty-related failures) * Performance: similar (http://hledger.org/profs/200906131120.bench) -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090613/af686ff0/attachment.html From jgoerzen at complete.org Sat Jun 13 19:01:43 2009 From: jgoerzen at complete.org (John Goerzen) Date: Sat Jun 13 18:45:13 2009 Subject: [Haskell-cafe] Re: HSH and IO () In-Reply-To: References: <4A332F1A.9020508@complete.org> Message-ID: <4A342FD7.3030705@complete.org> Dimitry Golubovsky wrote: > John, > > Thanks for the reply. > > In this case, would the body of my function run in a separate thread > via forkProcess (that's what is needed, maybe I didn't make it clear)? No; at least not automatically. The idea is that a function that is Channel -> IO Channel should be very similar in concept to a String -> String - processing its input lazily. > In my previous project, I had to do like this (probably not very > portable, at least requires System.Posix): You are aware that HSH has built-in support for executing external commands, right? What is hssfigMain? Is it calling some other program or is it part of the current process? I would suggest that the appropriate idea is to make hsffigMain be some other executable. Then you could just: runIO $ ("hsffigMain", [args, args, ...]) -|- (fromJust $ gccPath dopt, ["-E", "-dD", ...]) > where hscpid corresponds to a process that runs a Haskell function > (hsffigMain :: a -> b -> c -> IO ()) defined within the same program, > and gccpid runs an external program (gcc), and they are piped > together. I am trying to avoid writing this mess using HSH. OK, so I should have read more before starting to reply. But why are you writing to me about HSH if you're trying to *avoid* HSH? I'm confused. > I'm just trying to find out whether this was already done. If not, > what is the best way to write the above to be integrated into HSH (I'd > be glad to contribute). Integraing hsffigMain into HSH directly will be difficult because it apparently already has its notions about where its input and output come from; the fact that its return type is IO () implies that its output either goes to stdout or to a file. This type of function cannot be generalized to pipes, because you can only dup2() your stdout once. (You couldn't have two functions like hsffigMain in your pipeline). Your best bet is to make this a separate executable. -- John From dagit at codersbase.com Sat Jun 13 20:06:41 2009 From: dagit at codersbase.com (Jason Dagit) Date: Sat Jun 13 19:50:08 2009 Subject: [Haskell-cafe] Re: HSH and IO () In-Reply-To: <4A342FD7.3030705@complete.org> References: <4A332F1A.9020508@complete.org> <4A342FD7.3030705@complete.org> Message-ID: On Sat, Jun 13, 2009 at 4:01 PM, John Goerzen wrote: > Dimitry Golubovsky wrote: > > > where hscpid corresponds to a process that runs a Haskell function > > (hsffigMain :: a -> b -> c -> IO ()) defined within the same program, > > and gccpid runs an external program (gcc), and they are piped > > together. I am trying to avoid writing this mess using HSH. > > OK, so I should have read more before starting to reply. But why are > you writing to me about HSH if you're trying to *avoid* HSH? I'm confused. I think Dimitry meant, "I'm trying to avoid writing this mess *by* using HSH instead." At least, that's how I read it. Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090613/b14b0900/attachment.html From jgoerzen at complete.org Sat Jun 13 21:49:59 2009 From: jgoerzen at complete.org (John Goerzen) Date: Sat Jun 13 21:33:29 2009 Subject: [Haskell-cafe] Re: HSH and IO () In-Reply-To: References: <4A332F1A.9020508@complete.org> <4A342FD7.3030705@complete.org> Message-ID: <20090614014959.GA3021@complete.org> On Sat, Jun 13, 2009 at 05:06:41PM -0700, Jason Dagit wrote: > On Sat, Jun 13, 2009 at 4:01 PM, John Goerzen wrote: > > > Dimitry Golubovsky wrote: > > > > > where hscpid corresponds to a process that runs a Haskell function > > > (hsffigMain :: a -> b -> c -> IO ()) defined within the same program, > > > and gccpid runs an external program (gcc), and they are piped > > > together. I am trying to avoid writing this mess using HSH. > > > > OK, so I should have read more before starting to reply. But why are > > you writing to me about HSH if you're trying to *avoid* HSH? I'm confused. > > > I think Dimitry meant, "I'm trying to avoid writing this mess *by* using HSH > instead." > > At least, that's how I read it. Ah, that makes more sense. Sorry for the misparsing. -- John From golubovsky at gmail.com Sat Jun 13 22:17:02 2009 From: golubovsky at gmail.com (Dimitry Golubovsky) Date: Sat Jun 13 22:00:28 2009 Subject: [Haskell-cafe] Re: HSH and IO () In-Reply-To: <4A342FD7.3030705@complete.org> References: <4A332F1A.9020508@complete.org> <4A342FD7.3030705@complete.org> Message-ID: John, On Sat, Jun 13, 2009 at 7:01 PM, John Goerzen wrote: >> where hscpid corresponds to a process that runs a Haskell function >> (hsffigMain :: a -> b -> c -> IO ()) defined within the same program, >> and gccpid runs an external program (gcc), and they are piped >> together. I am trying to avoid writing this mess using HSH. > > OK, so I should have read more before starting to reply. ?But why are > you writing to me about HSH if you're trying to *avoid* HSH? ?I'm confused. Sorry, I should have written "by using"; Jason made the right correction. I thought that forkProcess-based shell commands existed in HSH thus I could avoid all these low-level manipulations with handles that are usually done in C programming. > Integraing hsffigMain into HSH directly will be difficult because it > apparently already has its notions about where its input and output come > from; the fact that its return type is IO () implies that its output I'll try to write a wrapper for a forked process inside a Channel -> IO Channel typed function. > Your best bet is to make this a separate executable. That's not what was intended, but now I see the situation more clearly. Thanks for the explanation. If I get any working code, I'll post a link on the list. -- Dimitry Golubovsky Anywhere on the Web From magicloud.magiclouds at gmail.com Sat Jun 13 22:22:37 2009 From: magicloud.magiclouds at gmail.com (Magicloud Magiclouds) Date: Sat Jun 13 22:06:03 2009 Subject: [Haskell-cafe] How to know the build dependencies? Message-ID: <3bd412d40906131922p6e0cbc55mec4dd2a4ddc990d6@mail.gmail.com> Hi, I am learning to use cabal for my code. Just when I start, I met a question, is there an easy way to find out what packages my code depends? Thanks. From jgoerzen at complete.org Sat Jun 13 22:53:48 2009 From: jgoerzen at complete.org (John Goerzen) Date: Sat Jun 13 22:37:18 2009 Subject: [Haskell-cafe] Re: HSH and IO () In-Reply-To: References: <4A332F1A.9020508@complete.org> <4A342FD7.3030705@complete.org> Message-ID: <4A34663C.6090905@complete.org> Dimitry Golubovsky wrote: > I'll try to write a wrapper for a forked process inside a Channel -> > IO Channel typed function. Your best bet would be to start with these instances in HSH.Command: instance ShellCommand (String, [String]) where instance ShellCommand String where and the implementation of genericCommand, which they both call. It is really not that difficult of an implementation, and as of GHC 6.10, no longer even requires the specialized POSIX items. The reason I have two bodies for genericCommand is that if the input channel is a Handle, I can pass it directly as stdin to the child process; otherwise, it is necessary to use chanToHandle to zap it over to stdin. Now, with what you're trying to do, you will probably not be able to get away without using the POSIX stuff though, since you have to dup2() stdin/stdout. I still recommend splitting this into multiple executables. With your approach, the stdin and stdout of your main executable will be messed up forever. This can and does lead to unforseen consequences. -- John From gwern0 at gmail.com Sat Jun 13 23:13:21 2009 From: gwern0 at gmail.com (Gwern Branwen) Date: Sat Jun 13 22:56:47 2009 Subject: [Haskell-cafe] How to know the build dependencies? In-Reply-To: <3bd412d40906131922p6e0cbc55mec4dd2a4ddc990d6@mail.gmail.com> References: <3bd412d40906131922p6e0cbc55mec4dd2a4ddc990d6@mail.gmail.com> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On Sat, Jun 13, 2009 at 10:22 PM, Magicloud Magiclouds wrote: > Hi, > I am learning to use cabal for my code. > Just when I start, I met a question, is there an easy way to find > out what packages my code depends? > > Thanks. Not really. The easiest way is to just build your code and add every package Cabal complains about being hid into your build-depends. (Usually this won't take more than a minute or 3 if you're toggling between a terminal and an editor.) - -- gwern -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEAREKAAYFAko0arEACgkQvpDo5Pfl1oJbNACfYNB+oScSsiwF3qwZMHzu3AjM s24An3tcamliH1rJzZiNg1EqjTLLYzzo =7Fgw -----END PGP SIGNATURE----- From shu at rfrn.org Sat Jun 13 23:41:46 2009 From: shu at rfrn.org (Shu-yu Guo) Date: Sat Jun 13 23:25:11 2009 Subject: [Haskell-cafe] Unicode workaround for getDirectoryContents under Windows? Message-ID: Hello all, It seems like getDirectoryContents applies codepage conversion based on the default program locale under Windows. What this means is that if my default codepage is some kind of Latin, Asian glyphs get returned as '?' in the filename. By '?' I don't mean that the font is lacking the glyph and rendering it as '?', but I mean 'show (head (getDirectoryContents "C:\\Music"))' returns something that looks like like "?? ????". This is a problem as I can't get the filenames of my music directory, some of which are in Japanese and Chinese, some of which have accents. If I change the default codepage to Japanese, say, then I get the Japanese filenames in Shift-JIS and I lose all the accented letters. I have filed this as a bug already, but is there a workaround in the meantime (I don't know the Win32 API, but didn't see anything that looked like it would help under System.Win32 anyways) that lets me gets the list of files in a directory that's encoded in some kind of Unicode? Cheers, -- shu From judah.jacobson at gmail.com Sun Jun 14 00:56:54 2009 From: judah.jacobson at gmail.com (Judah Jacobson) Date: Sun Jun 14 00:40:20 2009 Subject: [Haskell-cafe] Unicode workaround for getDirectoryContents under Windows? In-Reply-To: References: Message-ID: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> On Sat, Jun 13, 2009 at 8:41 PM, Shu-yu Guo wrote: > Hello all, > > It seems like getDirectoryContents applies codepage conversion based > on the default program locale under Windows. What this means is that > if my default codepage is some kind of Latin, Asian glyphs get > returned as '?' in the filename. By '?' I don't mean that the font is > lacking the glyph and rendering it as '?', but I mean 'show (head > (getDirectoryContents "C:\\Music"))' returns something that looks like > like "?? ????". > > This is a problem as I can't get the filenames of my music directory, > some of which are in Japanese and Chinese, some of which have accents. > If I change the default codepage to Japanese, say, then I get the > Japanese filenames in Shift-JIS and I lose all the accented letters. > > I have filed this as a bug already, but is there a workaround in the > meantime (I don't know the Win32 API, but didn't see anything that > looked like it would help under System.Win32 anyways) that lets me > gets the list of files in a directory that's encoded in some kind of > Unicode? Try taking a look at the code in the following module, which uses FFI to access the Unicode-aware Win32 APIs: http://code.haskell.org/haskeline/System/Console/Haskeline/Directory.hsc Hope that helps, -Judah From bulat.ziganshin at gmail.com Sun Jun 14 02:26:57 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Jun 14 02:10:33 2009 Subject: [Haskell-cafe] Unicode workaround for getDirectoryContents under Windows? In-Reply-To: References: Message-ID: <1577107476.20090614102657@gmail.com> Hello Shu-yu, Sunday, June 14, 2009, 7:41:46 AM, you wrote: > It seems like getDirectoryContents applies codepage conversion based it's not a bug, but old-fashioned architecture of entire file apis you may find my Win32Files.hs module useful - it adopts UTF-16 versions of file operations http://downloads.sourceforge.net/freearc/FreeArc-0.51-sources.tar.bz2 -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From fernanbolando at mailc.net Sun Jun 14 04:06:09 2009 From: fernanbolando at mailc.net (Fernan Bolando) Date: Sun Jun 14 03:49:36 2009 Subject: [Haskell-cafe] I need a hint in list processing Message-ID: <1d5d51400906140106n3b391c5au3a1cfda421509e1d@mail.gmail.com> Hi all If I have a number of list example list1 = [2,3] list2 = [1,2] list3 = [2,3,4] list4 = [1,2,3] I want to create a list from the list above with n elements, non-repeating and each elements index represents 1 of the elements from the corresponding list so for the above input I would get. a = [3,2,4,1] ofcourse there may be several set that will satisfy the problem, so a list of list that satisfies would be good. How do I do this in haskell? or is there a code snippet that seems to work similarly? thanks fernan -- http://www.fernski.com From mle+hs at mega-nerd.com Sun Jun 14 04:13:42 2009 From: mle+hs at mega-nerd.com (Erik de Castro Lopo) Date: Sun Jun 14 03:57:14 2009 Subject: [Haskell-cafe] I need a hint in list processing In-Reply-To: <1d5d51400906140106n3b391c5au3a1cfda421509e1d@mail.gmail.com> References: <1d5d51400906140106n3b391c5au3a1cfda421509e1d@mail.gmail.com> Message-ID: <20090614181342.d2b18250.mle+hs@mega-nerd.com> Fernan Bolando wrote: > Hi all > > If I have a number of list > example > list1 = [2,3] > list2 = [1,2] > list3 = [2,3,4] > list4 = [1,2,3] > > I want to create a list from the list above with n elements, > non-repeating and each elements index represents 1 of the elements > from the corresponding list so for the above input I would get. > > a = [3,2,4,1] > > ofcourse there may be several set that will satisfy the problem, so a > list of list that satisfies would be good. > > How do I do this in haskell? or is there a code snippet that seems to > work similarly? Well you could simply concatenate all the lists using the (++) operator and then use Data.List.nub: http://haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html#v:nub to remove duplicates. Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/ From duncan.coutts at worc.ox.ac.uk Sun Jun 14 04:31:09 2009 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Sun Jun 14 04:15:18 2009 Subject: [Haskell-cafe] install problems ... In-Reply-To: <5ae4f2ba0906112150r5095e7d7t41bd10950daaa63e@mail.gmail.com> References: <5ae4f2ba0906112150r5095e7d7t41bd10950daaa63e@mail.gmail.com> Message-ID: <1244968269.26313.909.camel@localhost> On Thu, 2009-06-11 at 23:50 -0500, Vasili I. Galchin wrote: > Hello, > > As I have said before I a, "cabalizing" Swish (a semantic web > toolkit). I have it built and have run most of the original author's > tests by and they pass. There are numerous warnings which seem to be > either lack of a function type signature or "unreferenced" symbols ... > I will go through one-by-one and clean these up. However, now I am > getting the following install-time errors .... any advice on how to > track down will be greatly apprecriated .... the following is the > result of "cabal build -v": > > Preprocessing executables for swish-0.2.1... > Building swish-0.2.1... > /usr/bin/ar: creating dist/build/libHSswish-0.2.1.a > Warning: output was redirected with -o, but no output will be > generated because there is no Main module. This warning is very suspicious. Perhaps you can post your .cabal file. I suspect that it's using an inappropriate ghc flag. Duncan From fernanbolando at mailc.net Sun Jun 14 04:32:33 2009 From: fernanbolando at mailc.net (Fernan Bolando) Date: Sun Jun 14 04:16:02 2009 Subject: [Haskell-cafe] I need a hint in list processing In-Reply-To: <20090614181342.d2b18250.mle+hs@mega-nerd.com> References: <1d5d51400906140106n3b391c5au3a1cfda421509e1d@mail.gmail.com> <20090614181342.d2b18250.mle+hs@mega-nerd.com> Message-ID: <1d5d51400906140132l4d5103efo32bc076d84e7b667@mail.gmail.com> On Sun, Jun 14, 2009 at 4:13 PM, Erik de Castro Lopo wrote: > Fernan Bolando wrote: > >> Hi all >> >> If I have a number of list >> example >> list1 = [2,3] >> list2 = [1,2] >> list3 = [2,3,4] >> list4 = [1,2,3] >> >> I want to create a list from the list above with n elements, >> non-repeating and each elements index represents 1 of the elements >> from the corresponding list so for the above input I would get. >> >> a = [3,2,4,1] >> >> ofcourse there may be several set that will satisfy the problem, so a >> list of list that satisfies would be good. >> >> How do I do this in haskell? or is there a code snippet that seems to >> work similarly? > > Well you could simply concatenate all the lists using the (++) operator > and then use Data.List.nub: > > ? ?http://haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html#v:nub > > to remove duplicates. > Using Data.List.nub Data.List> nub [2,3,1,2,2,3,4,1,2,3] [2,3,1,4] that is not exactly what I want. list1 only has 2,3 has elements and list2 only has elements 1,2...this means the first element should only be 2 or 3 and the second element should only have 1 or 2...etc fernan -- http://www.fernski.com From miguelimo38 at yandex.ru Sun Jun 14 04:51:20 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Sun Jun 14 04:34:48 2009 Subject: [Haskell-cafe] I need a hint in list processing In-Reply-To: <1d5d51400906140106n3b391c5au3a1cfda421509e1d@mail.gmail.com> References: <1d5d51400906140106n3b391c5au3a1cfda421509e1d@mail.gmail.com> Message-ID: ghci> map reverse $ foldM (\answer list -> [x:answer | x <- list, not $ x `elem` answer]) [] [[2,3], [1,2], [2,3,4], [1,2,3]] [[2,1,4,3],[3,1,4,2],[3,2,4,1]] On 14 Jun 2009, at 12:06, Fernan Bolando wrote: > Hi all > > If I have a number of list > example > list1 = [2,3] > list2 = [1,2] > list3 = [2,3,4] > list4 = [1,2,3] > > I want to create a list from the list above with n elements, > non-repeating and each elements index represents 1 of the elements > from the corresponding list so for the above input I would get. > > a = [3,2,4,1] > > ofcourse there may be several set that will satisfy the problem, so a > list of list that satisfies would be good. > > How do I do this in haskell? or is there a code snippet that seems to > work similarly? > > thanks > fernan > > -- > http://www.fernski.com > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From vigalchin at gmail.com Sun Jun 14 04:58:57 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Sun Jun 14 04:42:22 2009 Subject: [Haskell-cafe] install problems ... In-Reply-To: <1244968269.26313.909.camel@localhost> References: <5ae4f2ba0906112150r5095e7d7t41bd10950daaa63e@mail.gmail.com> <1244968269.26313.909.camel@localhost> Message-ID: <5ae4f2ba0906140158l1acf4b9cudd1bc6644d1df80d@mail.gmail.com> Hi Duncan, Actually it was do to a typo on an "Executable" I specified "N3Parser" where I meant "N3ParserTest" => DUH ..... I am totally ashamed ..... Vasili On Sun, Jun 14, 2009 at 3:31 AM, Duncan Coutts wrote: > On Thu, 2009-06-11 at 23:50 -0500, Vasili I. Galchin wrote: > > Hello, > > > > As I have said before I a, "cabalizing" Swish (a semantic web > > toolkit). I have it built and have run most of the original author's > > tests by and they pass. There are numerous warnings which seem to be > > either lack of a function type signature or "unreferenced" symbols ... > > I will go through one-by-one and clean these up. However, now I am > > getting the following install-time errors .... any advice on how to > > track down will be greatly apprecriated .... the following is the > > result of "cabal build -v": > > > > Preprocessing executables for swish-0.2.1... > > Building swish-0.2.1... > > /usr/bin/ar: creating dist/build/libHSswish-0.2.1.a > > Warning: output was redirected with -o, but no output will be > > generated because there is no Main module. > > This warning is very suspicious. Perhaps you can post your .cabal file. > I suspect that it's using an inappropriate ghc flag. > > Duncan > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090614/f6d8917f/attachment.html From vigalchin at gmail.com Sun Jun 14 05:03:39 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Sun Jun 14 04:47:04 2009 Subject: [Haskell-cafe] install problems ... In-Reply-To: <5ae4f2ba0906140158l1acf4b9cudd1bc6644d1df80d@mail.gmail.com> References: <5ae4f2ba0906112150r5095e7d7t41bd10950daaa63e@mail.gmail.com> <1244968269.26313.909.camel@localhost> <5ae4f2ba0906140158l1acf4b9cudd1bc6644d1df80d@mail.gmail.com> Message-ID: <5ae4f2ba0906140203g64a98f22o801618b248783592@mail.gmail.com> BTW is "TimeDate" a Hugism? Vasili On Sun, Jun 14, 2009 at 3:58 AM, Vasili I. Galchin wrote: > Hi Duncan, > > Actually it was do to a typo on an "Executable" > > I specified "N3Parser" where I meant "N3ParserTest" => DUH ..... I am > totally ashamed ..... > > Vasili > > > On Sun, Jun 14, 2009 at 3:31 AM, Duncan Coutts < > duncan.coutts@worc.ox.ac.uk> wrote: > >> On Thu, 2009-06-11 at 23:50 -0500, Vasili I. Galchin wrote: >> > Hello, >> > >> > As I have said before I a, "cabalizing" Swish (a semantic web >> > toolkit). I have it built and have run most of the original author's >> > tests by and they pass. There are numerous warnings which seem to be >> > either lack of a function type signature or "unreferenced" symbols ... >> > I will go through one-by-one and clean these up. However, now I am >> > getting the following install-time errors .... any advice on how to >> > track down will be greatly apprecriated .... the following is the >> > result of "cabal build -v": >> > >> > Preprocessing executables for swish-0.2.1... >> > Building swish-0.2.1... >> > /usr/bin/ar: creating dist/build/libHSswish-0.2.1.a >> > Warning: output was redirected with -o, but no output will be >> > generated because there is no Main module. >> >> This warning is very suspicious. Perhaps you can post your .cabal file. >> I suspect that it's using an inappropriate ghc flag. >> >> Duncan >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090614/acc5e086/attachment.html From magicloud.magiclouds at gmail.com Sun Jun 14 05:30:33 2009 From: magicloud.magiclouds at gmail.com (Magicloud Magiclouds) Date: Sun Jun 14 05:13:58 2009 Subject: [Haskell-cafe] [cabal] How to deal with build-depency that not under cabal's control? Message-ID: <3bd412d40906140230rb7a0525v40a806f64196fe21@mail.gmail.com> Hi, I use gtk2hs in linux. Well, I have no idea how to install gtk2hs by cabal, but my program needs it, and I want my program cabalized. So how to do this? Thanks. -- ??????? ??????? From timothyea at comcast.net Sun Jun 14 05:55:38 2009 From: timothyea at comcast.net (Tim Attwood) Date: Sun Jun 14 05:43:27 2009 Subject: [Haskell-cafe] Re: Logo fun In-Reply-To: <7ca3f0160906121529r13efcb38r1ea0392c63af8165@mail.gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com><6f9f8f4a0906120127x2c1cce01x6abf6cae17f7ee19@mail.gmail.com><02E3B702-2B26-4513-B5E9-EFDB95E4C4ED@gmail.com><317ca7670906120147x68e3be10p873f6be9a790aed9@mail.gmail.com><7b501d5c0906120157w78cb299dj1ab7a5a5189329f1@mail.gmail.com><7b501d5c0906120215t2f79a7ebi4396f94dc85e11a1@mail.gmail.com><6DD7CAD2-585C-4CE2-B8C8-1A4E99995011@gmail.com> <7ca3f0160906121529r13efcb38r1ea0392c63af8165@mail.gmail.com> Message-ID: Graphics are fun. Here's my version. http://s201.photobucket.com/albums/aa280/Zakardis/?action=view¤t=lambda_haskell_platform.png From deniz.a.m.dogan at gmail.com Sun Jun 14 06:05:40 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Sun Jun 14 05:49:08 2009 Subject: [Haskell-cafe] How to know the build dependencies? In-Reply-To: References: <3bd412d40906131922p6e0cbc55mec4dd2a4ddc990d6@mail.gmail.com> Message-ID: <7b501d5c0906140305o16a51491v95b6185353d5f6b2@mail.gmail.com> 2009/6/14 Gwern Branwen : > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA512 > > On Sat, Jun 13, 2009 at 10:22 PM, Magicloud Magiclouds wrote: >> Hi, >> ?I am learning to use cabal for my code. >> ?Just when I start, I met a question, is there an easy way to find >> out what packages my code depends? >> >> Thanks. > > Not really. The easiest way is to just build your code and add every > package Cabal complains about being hid into your build-depends. > (Usually this won't take more than a minute or 3 if you're toggling > between a terminal and an editor.) > > - -- > gwern Someone really ought to write a tool for this... -- Deniz Dogan From mle+hs at mega-nerd.com Sun Jun 14 06:07:22 2009 From: mle+hs at mega-nerd.com (Erik de Castro Lopo) Date: Sun Jun 14 05:50:56 2009 Subject: [Haskell-cafe] Running Hoogle as a cgi script. Message-ID: <20090614200722.019c5e8c.mle+hs@mega-nerd.com> Hi all, I'd like to run my own version of Hoogle: http://hackage.haskell.org/package/hoogle as a CGI script much like this: http://www.haskell.org/hoogle/ but there doesn't seem to be any documentation on how to do this. Clues anyone? Cheers, Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/ From claus.reinke at talk21.com Sun Jun 14 06:24:44 2009 From: claus.reinke at talk21.com (Claus Reinke) Date: Sun Jun 14 06:08:12 2009 Subject: [Haskell-cafe] How to know the build dependencies? References: <3bd412d40906131922p6e0cbc55mec4dd2a4ddc990d6@mail.gmail.com> Message-ID: <30C970C22DA94A9DBF3DB8E976AA5FA8@cr3lt> > I am learning to use cabal for my code. > Just when I start, I met a question, is there an easy way to find > out what packages my code depends? If you've managed to get your code to compile, ghc --show-iface Main.hi is perhaps the easiest way (ghc --make and ghci will also report package dependencies as they encounter them). If you're looking for the package for a particular module, ghc-pkg can help ghc-pkg find-module Control.Concurrent c:/ghc/ghc-6.10.3\package.conf: base-3.0.3.1, base-4.1.0.0 ghc-pkg find-module Data.Map c:/ghc/ghc-6.10.3\package.conf: containers-0.2.0.1 If you're looking for a minimal set of imports before hunting for packages, ghc's -ddump-minimal-imports will create a file Main.imports with that information. You could then run ghc-pkg find-module over that list. These are not the only options. Perhaps the available tools need to be advertized more?-) Claus From roma at ro-che.info Sun Jun 14 06:25:42 2009 From: roma at ro-che.info (Roman Cheplyaka) Date: Sun Jun 14 06:09:08 2009 Subject: [Haskell-cafe] [cabal] How to deal with build-depency that not under cabal's control? In-Reply-To: <3bd412d40906140230rb7a0525v40a806f64196fe21@mail.gmail.com> References: <3bd412d40906140230rb7a0525v40a806f64196fe21@mail.gmail.com> Message-ID: <20090614102542.GA1182@flit> * Magicloud Magiclouds [2009-06-14 17:30:33+0800] > Hi, > I use gtk2hs in linux. Well, I have no idea how to install gtk2hs by > cabal, but my program needs it, and I want my program cabalized. So > how to do this? > Thanks. gtk2hs consists of several cabal packages, e.g. gtk, glib and so on. (See `ghc-pkg list`) Specify those of them you need as dependencies in cabal file. -- Roman I. Cheplyaka :: http://ro-che.info/ "Don't let school get in the way of your education." - Mark Twain From roma at ro-che.info Sun Jun 14 06:47:51 2009 From: roma at ro-che.info (Roman Cheplyaka) Date: Sun Jun 14 06:31:17 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <7b501d5c0906130717k1b6ff394x3abe866aa84d2fa2@mail.gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <4A33B318.7090203@functor.nl> <7b501d5c0906130717k1b6ff394x3abe866aa84d2fa2@mail.gmail.com> Message-ID: <20090614104751.GB1182@flit> * Deniz Dogan [2009-06-13 16:17:57+0200] > I remember needing a non-strict sum at least once, but I do not > remember the exact application. We may agree that lazy sum is sometimes (rarely) needed, but then it can be always written as fold. However, in most cases user wants strict sum. So it's not really an excuse. -- Roman I. Cheplyaka :: http://ro-che.info/ "Don't let school get in the way of your education." - Mark Twain From roma at ro-che.info Sun Jun 14 06:52:58 2009 From: roma at ro-che.info (Roman Cheplyaka) Date: Sun Jun 14 06:36:26 2009 Subject: [Haskell-cafe] [cabal] How to deal with build-depency that not under cabal's control? In-Reply-To: <3bd412d40906140348m35a40a18se29cb980c49dfa95@mail.gmail.com> References: <3bd412d40906140230rb7a0525v40a806f64196fe21@mail.gmail.com> <20090614102542.GA1182@flit> <3bd412d40906140348m35a40a18se29cb980c49dfa95@mail.gmail.com> Message-ID: <20090614105258.GA4604@flit> * Magicloud Magiclouds [2009-06-14 18:48:26+0800] > My gtk2hs is install manually, `configure && make && make install`. So It's okay. > when I add gtk to build-dependency, it tells me > Setup.hs: At least the following dependencies are missing: > gtk -any Installation of gtk2hs registers these packages for you. Again, check `ghc-pkg list gtk`. If you installed gtk2hs, it must be there. If you, say, upgraded your ghc after you installed gtk2hs, you have to reinstall gtk2hs. > How to register my manual-installed gtk2hs to cabal? > > On Sun, Jun 14, 2009 at 6:25 PM, Roman Cheplyaka wrote: > > * Magicloud Magiclouds [2009-06-14 17:30:33+0800] > >> Hi, > >> ? I use gtk2hs in linux. Well, I have no idea how to install gtk2hs by > >> cabal, but my program needs it, and I want my program cabalized. So > >> how to do this? > >> Thanks. > > > > gtk2hs consists of several cabal packages, e.g. gtk, glib and so on. > > (See `ghc-pkg list`) > > Specify those of them you need as dependencies in cabal file. > > > > -- > > Roman I. Cheplyaka :: http://ro-che.info/ > > "Don't let school get in the way of your education." - Mark Twain > > _______________________________________________ > > Haskell-Cafe mailing list > > Haskell-Cafe@haskell.org > > http://www.haskell.org/mailman/listinfo/haskell-cafe > > > > > > -- > ??????? > ??????? -- Roman I. Cheplyaka :: http://ro-che.info/ "Don't let school get in the way of your education." - Mark Twain From gtener at gmail.com Sun Jun 14 08:41:05 2009 From: gtener at gmail.com (=?UTF-8?Q?Krzysztof_Skrz=C4=99tnicki?=) Date: Sun Jun 14 08:24:30 2009 Subject: [Haskell-cafe] How to know the build dependencies? In-Reply-To: <3bd412d40906131922p6e0cbc55mec4dd2a4ddc990d6@mail.gmail.com> References: <3bd412d40906131922p6e0cbc55mec4dd2a4ddc990d6@mail.gmail.com> Message-ID: <220e47b40906140541s541e2dy84fbfc5b8f29f9d5@mail.gmail.com> If your module compiles, you can get the info by passing '-ddump-types': TYPE SIGNATURES numbersTests :: Test testAverage :: Test testBindInt :: Test TYPE CONSTRUCTORS Dependent modules: [(MoresmauJP.Util.Numbers, False)] Dependent packages: [HUnit-1.2.0.3, base, ghc-prim, integer] It is, however, available only after your code has successfully compiled. Best regards Krzysztof Skrz?tnicki On Sun, Jun 14, 2009 at 04:22, Magicloud Magiclouds wrote: > Hi, > ?I am learning to use cabal for my code. > ?Just when I start, I met a question, is there an easy way to find > out what packages my code depends? > > Thanks. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From gwern0 at gmail.com Sun Jun 14 10:12:51 2009 From: gwern0 at gmail.com (Gwern Branwen) Date: Sun Jun 14 09:56:16 2009 Subject: [Haskell-cafe] How to know the build dependencies? In-Reply-To: <7b501d5c0906140305o16a51491v95b6185353d5f6b2@mail.gmail.com> References: <3bd412d40906131922p6e0cbc55mec4dd2a4ddc990d6@mail.gmail.com> <7b501d5c0906140305o16a51491v95b6185353d5f6b2@mail.gmail.com> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On Sun, Jun 14, 2009 at 6:05 AM, Deniz Dogan wrote: > Someone really ought to write a tool for this... Well, it's an issue of time. Just building and adding the deps is fast and straightforward. A tool I'd need to know about, have installed, and remember to use in the middle of a Cabalizing session. The people who most need such a tool are those who are least likely to use it. And given the overhead, it's unclear that it would actually save time. Sometimes, somethings aren't worth automating. Now, if someone were to create such a tool and integrate it into 'mkcabal', then it might make sense. You could create the basic .cabal with the build-depends filled in. But as a separate tool it's too small a task to handle. Even memorizing the -show-iface or - -ddump-types options may not be worthwhile - how often does one create Cabal packages from scratch? - -- gwern -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEAREKAAYFAko1BWEACgkQvpDo5Pfl1oKvigCeO7ABRVr/9+kT62dIFpo0k5+f y/AAnR6wLaDpX5/lZPqQzB/Wb4kuj8i9 =L2iA -----END PGP SIGNATURE----- From deniz.a.m.dogan at gmail.com Sun Jun 14 10:14:27 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Sun Jun 14 09:57:52 2009 Subject: [Haskell-cafe] How to know the build dependencies? In-Reply-To: References: <3bd412d40906131922p6e0cbc55mec4dd2a4ddc990d6@mail.gmail.com> <7b501d5c0906140305o16a51491v95b6185353d5f6b2@mail.gmail.com> Message-ID: <7b501d5c0906140714v496495b4p172e444b784b6cfa@mail.gmail.com> 2009/6/14 Gwern Branwen : > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA512 > > On Sun, Jun 14, 2009 at 6:05 AM, Deniz Dogan wrote: >> Someone really ought to write a tool for this... > > Well, it's an issue of time. Just building and adding the deps is fast > and straightforward. A tool I'd need to know about, have installed, > and remember to use in the middle of a Cabalizing session. The people > who most need such a tool are those who are least likely to use it. > And given the overhead, it's unclear that it would actually save time. > Sometimes, somethings aren't worth automating. > > Now, if someone were to create such a tool and integrate it into > 'mkcabal', then it might make sense. You could create the basic .cabal > with the build-depends filled in. But as a separate tool it's too > small a task to handle. Even memorizing the -show-iface or > - -ddump-types options may not be worthwhile - how often does one create > Cabal packages from scratch? I'm sorry, I was not aware of those flags when I wrote my message. You're right. -- Deniz Dogan From daimaox at gmail.com Sun Jun 14 11:19:22 2009 From: daimaox at gmail.com (Gjuro Chensen) Date: Sun Jun 14 11:02:45 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more Message-ID: <24022673.post@talk.nabble.com> Hello everyone! Im a Haskell newbie, and Ive have few unanswered questions. For someone more experienced (at least I think so) its a very simple task, but I just cant get a grip on it and its pretty frustrating. It wouldn't be that bad if I haven't browse thru bunch of pages and tutorials and still nothing... The problem is: take a string, and if every words starts with uppercase letter then print yes, else no. Forum Text Bold -> yes Frog image File -> no Ive had my share of approaches to this, but I just cant make it work. Standard one seemed the most simple: search :: String -> String search [] = [] and then use words (splits string on space) to split the string so I could get a list and go through it recursively. But how to apply words to entered string in this form? To find the first letter I came up with: first = take 1 (head x). And compare it with elem or ASCII values to determine if its upper case. Any help, advice or suggestion is appreciated. Thanks in advance! -- View this message in context: http://www.nabble.com/Haskell---string-to-list-isusses%2C-and-more-tp24022673p24022673.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From deniz.a.m.dogan at gmail.com Sun Jun 14 11:42:53 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Sun Jun 14 11:26:18 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: <24022673.post@talk.nabble.com> References: <24022673.post@talk.nabble.com> Message-ID: <7b501d5c0906140842hcde03c4i9fe0c21cf3bfb578@mail.gmail.com> 2009/6/14 Gjuro Chensen : > > Hello everyone! > > Im a Haskell newbie, and Ive have few unanswered questions. For someone more > experienced (at least I think so) its a very simple task, but I just cant > get a grip on it and its pretty frustrating. It wouldn't be that bad if I > haven't browse thru bunch of pages and tutorials and still nothing... > The problem is: take a string, and if every words starts with uppercase > letter then print yes, else no. > Forum Text Bold -> yes > Frog image File -> no > > Ive had my share of approaches to this, but I just cant make it work. > Standard one seemed the most simple: > > search :: String -> String > search [] = [] > > > and then use words (splits string on space) to split the string so I could > get a list and go through it recursively. But how to apply words to entered > string in this form? > > To find the first letter I came up with: first = take 1 (head x). And > compare it with elem or ASCII values to determine if its upper case. > > Any help, advice or suggestion is appreciated. > > Thanks in advance! > > -- > View this message in context: http://www.nabble.com/Haskell---string-to-list-isusses%2C-and-more-tp24022673p24022673.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 > As you say, there are a number of possible approaches to take here. I'd say take a look at functions "all" [1] and "isUpper" [2], those should be all you need. * "all" takes a predicate (a function) and a list of elements. It returns True if that predicate holds for all of the elements in the list, otherwise False. * "isUpper" takes a Char and returns True if that character is an uppercase letter, otherwise False. [1] http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html [2] http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Char.html -- Deniz Dogan From jochem at functor.nl Sun Jun 14 11:44:27 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Sun Jun 14 11:27:53 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: <24022673.post@talk.nabble.com> References: <24022673.post@talk.nabble.com> Message-ID: <4A351ADB.8060807@functor.nl> Gjuro Chensen wrote: > Hello everyone! > > Im a Haskell newbie, and Ive have few unanswered questions. For someone more > experienced (at least I think so) its a very simple task, but I just cant > get a grip on it and its pretty frustrating. It wouldn't be that bad if I > haven't browse thru bunch of pages and tutorials and still nothing... > The problem is: take a string, and if every words starts with uppercase > letter then print yes, else no. > Forum Text Bold -> yes > Frog image File -> no > > Ive had my share of approaches to this, but I just cant make it work. > Standard one seemed the most simple: > > search :: String -> String > search [] = [] > > > and then use words (splits string on space) to split the string so I could > get a list and go through it recursively. But how to apply words to entered > string in this form? > > To find the first letter I came up with: first = take 1 (head x). And > compare it with elem or ASCII values to determine if its upper case. The idea of using `words' is very good. If we want to use a bottom-up approach, we should have a function that determines if a word starts with an upper-case letter, i.e. a function of type startsWithUppercase :: String -> Bool startsWithUppercase = ... (Hint: look at 'isUpper' from Data.Char) Now we need a way to see if for each word, some predicate is satisfied. There is a standard function for this, "all". You can also do this by using "map" and "and". The resulting function can be very concise if you get the hang of it :) Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From deniz.a.m.dogan at gmail.com Sun Jun 14 11:48:09 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Sun Jun 14 11:31:33 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: <7b501d5c0906140842hcde03c4i9fe0c21cf3bfb578@mail.gmail.com> References: <24022673.post@talk.nabble.com> <7b501d5c0906140842hcde03c4i9fe0c21cf3bfb578@mail.gmail.com> Message-ID: <7b501d5c0906140848o464f7906l2e22cb5e397826fa@mail.gmail.com> 2009/6/14 Deniz Dogan : > I'd say take a look at functions "all" [1] and "isUpper" [2], those > should be all you need. Sorry, "words" is also needed for the idea I was thinking of. -- Deniz Dogan From daniel.is.fischer at web.de Sun Jun 14 11:59:42 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sun Jun 14 11:43:55 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: <24022673.post@talk.nabble.com> References: <24022673.post@talk.nabble.com> Message-ID: <200906141759.42340.daniel.is.fischer@web.de> Am Sonntag 14 Juni 2009 17:19:22 schrieb Gjuro Chensen: > Hello everyone! > > Im a Haskell newbie, and Ive have few unanswered questions. For someone > more experienced (at least I think so) its a very simple task, but I just > cant get a grip on it and its pretty frustrating. It wouldn't be that bad > if I haven't browse thru bunch of pages and tutorials and still nothing... > The problem is: take a string, and if every words starts with uppercase > letter then print yes, else no. > Forum Text Bold -> yes > Frog image File -> no > > Ive had my share of approaches to this, but I just cant make it work. > Standard one seemed the most simple: > > search :: String -> String > search [] = [] > > > and then use words (splits string on space) to split the string so I could That's good. So you have everyWordStartsWithAnUppercaseLetter string = doSomething (words string) doSomething :: [String] -> Bool checks wordStartsWithAnUppercaseLetter :: String -> Bool for each word in the list and returns True if all words satisfy the condition, False if not. There's a handy function in the prelude for that: Prelude> :t all all :: (a -> Bool) -> [a] -> Bool > get a list and go through it recursively. But how to apply words to entered > string in this form? > > To find the first letter I came up with: first = take 1 (head x). And No, I don't think that's what you want: Prelude> :t (take 1 . head) (take 1 . head) :: [[a]] -> [a] Since String is a synonym for [Char], "head" gets the first letter of a word. > compare it with elem or ASCII values to determine if its upper case. What about unicode strings? Prelude> :t Data.Char.isUpper Data.Char.isUpper :: Char -> Bool is what you want. > > Any help, advice or suggestion is appreciated. > > Thanks in advance! How to assemble that is left to you. From toby at miller.ms Sun Jun 14 12:25:04 2009 From: toby at miller.ms (Toby Miller) Date: Sun Jun 14 12:08:30 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: <24022673.post@talk.nabble.com> References: <24022673.post@talk.nabble.com> Message-ID: Here's what I came up with. I especially like the 2nd version, even though it's longer, as it seems very declarative. caps1 s = all (\x -> isUpper (head x)) (words s) caps2 s = all startsWithUpper (words s) where startsWithUpper w = isUpper (head w) I'm also fairly new to Haskell, so I would appreciate feedback from the more experienced. Thanks. On Jun 14, 2009, at 11:19 AM, Gjuro Chensen wrote: > > Hello everyone! > > Im a Haskell newbie, and Ive have few unanswered questions. For > someone more > experienced (at least I think so) its a very simple task, but I just > cant > get a grip on it and its pretty frustrating. It wouldn't be that bad > if I > haven't browse thru bunch of pages and tutorials and still nothing... > The problem is: take a string, and if every words starts with > uppercase > letter then print yes, else no. > Forum Text Bold -> yes > Frog image File -> no > > Ive had my share of approaches to this, but I just cant make it work. > Standard one seemed the most simple: > > search :: String -> String > search [] = [] > > > and then use words (splits string on space) to split the string so I > could > get a list and go through it recursively. But how to apply words to > entered > string in this form? > > To find the first letter I came up with: first = take 1 (head x). And > compare it with elem or ASCII values to determine if its upper case. > > Any help, advice or suggestion is appreciated. > > Thanks in advance! > > -- > View this message in context: http://www.nabble.com/Haskell---string-to-list-isusses%2C-and-more-tp24022673p24022673.html > Sent from the Haskell - Haskell-Cafe mailing list archive at > Nabble.com. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From jochem at functor.nl Sun Jun 14 12:29:23 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Sun Jun 14 12:12:48 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: References: <24022673.post@talk.nabble.com> Message-ID: <4A352563.7070305@functor.nl> Toby Miller wrote: > Here's what I came up with. I especially like the 2nd version, even > though it's longer, as it seems very declarative. > > caps1 s = all (\x -> isUpper (head x)) (words s) > > caps2 s = all startsWithUpper (words s) where > startsWithUpper w = isUpper (head w) > > > I'm also fairly new to Haskell, so I would appreciate feedback from the > more experienced. This seems fine, but you need to check that words never returns a list containing the empty string (otherwise `head' will fail). I prefer in this case a point free style though, but some might disagree. Cheers, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From deniz.a.m.dogan at gmail.com Sun Jun 14 12:29:58 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Sun Jun 14 12:13:21 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: References: <24022673.post@talk.nabble.com> Message-ID: <7b501d5c0906140929jf9994f6w699fe6fb88b766ac@mail.gmail.com> 2009/6/14 Toby Miller : > Here's what I came up with. ?I especially like the 2nd version, even though > it's longer, as it seems very declarative. > > caps1 s = all (\x -> isUpper (head x)) (words s) > > caps2 s = all startsWithUpper (words s) where > ? ?startsWithUpper w = isUpper (head w) > > > I'm also fairly new to Haskell, so I would appreciate feedback from the more > experienced. > > Thanks. Not that I'm very experienced myself, but I came up with the first idea as well: caps1 = all (isUpper . head) . words -- Deniz Dogan From andrewcoppin at btinternet.com Sun Jun 14 12:31:02 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jun 14 12:14:21 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: References: <24022673.post@talk.nabble.com> Message-ID: <4A3525C6.5050408@btinternet.com> Toby Miller wrote: > Here's what I came up with. I especially like the 2nd version, even > though it's longer, as it seems very declarative. > > caps1 s = all (\x -> isUpper (head x)) (words s) > > caps2 s = all startsWithUpper (words s) where > startsWithUpper w = isUpper (head w) > > > I'm also fairly new to Haskell, so I would appreciate feedback from > the more experienced. > > Thanks. caps = all (isUpper . head) . words But then, I'm strange like that... From deniz.a.m.dogan at gmail.com Sun Jun 14 12:31:05 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Sun Jun 14 12:14:29 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: <4A352563.7070305@functor.nl> References: <24022673.post@talk.nabble.com> <4A352563.7070305@functor.nl> Message-ID: <7b501d5c0906140931s7b5d2a5bv60f9f6b21374a70c@mail.gmail.com> 2009/6/14 Jochem Berndsen : > Toby Miller wrote: >> caps1 s = all (\x -> isUpper (head x)) (words s) > This seems fine, but you need to check that words never returns a list > containing the empty string (otherwise `head' will fail). Is there any such case? I was thinking about that as well, but couldn't think of any case where head would be called on an empty list. -- Deniz Dogan From jochem at functor.nl Sun Jun 14 12:32:17 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Sun Jun 14 12:15:41 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: <7b501d5c0906140931s7b5d2a5bv60f9f6b21374a70c@mail.gmail.com> References: <24022673.post@talk.nabble.com> <4A352563.7070305@functor.nl> <7b501d5c0906140931s7b5d2a5bv60f9f6b21374a70c@mail.gmail.com> Message-ID: <4A352611.5040305@functor.nl> Deniz Dogan wrote: > 2009/6/14 Jochem Berndsen : >> Toby Miller wrote: >>> caps1 s = all (\x -> isUpper (head x)) (words s) >> This seems fine, but you need to check that words never returns a list >> containing the empty string (otherwise `head' will fail). > > Is there any such case? I was thinking about that as well, but > couldn't think of any case where head would be called on an empty > list. Not that I know of; but I tested this in order to make sure that I didn't overlook something obvious. (At least, it's a potential issue that we need to check, since `head' is partial.) Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From toby at miller.ms Sun Jun 14 12:49:36 2009 From: toby at miller.ms (Toby Miller) Date: Sun Jun 14 12:33:02 2009 Subject: [Haskell-cafe] How to know the build dependencies? In-Reply-To: <7b501d5c0906140305o16a51491v95b6185353d5f6b2@mail.gmail.com> References: <3bd412d40906131922p6e0cbc55mec4dd2a4ddc990d6@mail.gmail.com> <7b501d5c0906140305o16a51491v95b6185353d5f6b2@mail.gmail.com> Message-ID: On Jun 14, 2009, at 6:05 AM, Deniz Dogan wrote: > 2009/6/14 Gwern Branwen : >> -----BEGIN PGP SIGNED MESSAGE----- >> Hash: SHA512 >> >> On Sat, Jun 13, 2009 at 10:22 PM, Magicloud Magiclouds wrote: >>> Hi, >>> I am learning to use cabal for my code. >>> Just when I start, I met a question, is there an easy way to find >>> out what packages my code depends? >>> >>> Thanks. >> >> Not really. The easiest way is to just build your code and add every >> package Cabal complains about being hid into your build-depends. >> (Usually this won't take more than a minute or 3 if you're toggling >> between a terminal and an editor.) >> >> - -- >> gwern > > Someone really ought to write a tool for this... Visualising the Haskell Universe ? Control.Monad.Writer -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090614/368223c5/attachment.html From daimaox at gmail.com Sun Jun 14 13:14:11 2009 From: daimaox at gmail.com (Gjuro Chensen) Date: Sun Jun 14 12:57:35 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: <24022673.post@talk.nabble.com> References: <24022673.post@talk.nabble.com> Message-ID: <24023759.post@talk.nabble.com> Gjuro Chensen wrote: > > > /cut > > I dont know everyone will see this, but I would like thank everyone who found time to help, and not spam too much doing it:D. Well, I did it! Its not great (especially comparing to those one line solutions, wow!), but it works. module Main where startsWithUpper :: String -> Bool startsWithUpper []= False startsWithUpper string = if myIsUpper(head(string)) then True else False myIsUpper :: Char -> Bool myIsUpper x = if x>='A' && x <= 'Z' then True else False checkAll string = check (words string) check :: [String] -> Bool check []=False check x = if all startsWithUpper x then True else False Since importing modules isnt allowed, I made my own isUpper. And thats it, for few days of Haskell, Im happy. Once again, many many thanks to everyone! -- View this message in context: http://www.nabble.com/Haskell---string-to-list-isusses%2C-and-more-tp24022673p24023759.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From jochem at functor.nl Sun Jun 14 13:18:21 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Sun Jun 14 13:01:46 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: <24023759.post@talk.nabble.com> References: <24022673.post@talk.nabble.com> <24023759.post@talk.nabble.com> Message-ID: <4A3530DD.8010703@functor.nl> Gjuro Chensen wrote: > startsWithUpper :: String -> Bool > startsWithUpper []= False > startsWithUpper string = > if myIsUpper(head(string)) then True > else False It is very good that you caught the issue of taking the head of an empty list :) I saw here and also below, that you did things like if P then True else False You can shorten this to 'P'. Also, normally Haskellers like to pattern match, changing the second clause of your function into startsWithUpper (x:xs) = myIsUpper x > check :: [String] -> Bool > check []=False Why is this False and not True? Certainly in the empty string all words start with an uppercase letter, don't they? (If it's True, you can even remove this clause, and let the other one take care of the rest.) Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From briand at aracnet.com Sun Jun 14 14:44:19 2009 From: briand at aracnet.com (brian) Date: Sun Jun 14 14:27:43 2009 Subject: [Haskell-cafe] slow code Message-ID: <9621AF5D-5C87-43A6-B8A2-103109570416@aracnet.com> Haskell Gurus, I have tried to use profiling to tell me what's going on here, but it hasn't helped much, probably because I'm not interpreting the results correctly. Empirically I have determined that the show's are pretty slow, so an alternative to them would be helpful. I replaced the show's with "", and compiled with -O2 and not much improvement. I need to write _a lot_ of code in this style. A few words about how best to do this would be helpful. Laziness, infinite lists, uvector ?? Help... Thanks, Brian import Complex import System.IO genData :: Double -> Int -> (Double -> Complex Double) -> ([Double], [Complex Double]) genData tstop n f = let deltat = tstop / (fromIntegral n) t = [ fromIntegral(i) * deltat | i <- [0..n-1]] in (t, map f t) main = do let (t, y) = genData 100.0E-6 (2 ^ 15) (\x -> x :+ 0.0) h <- openFile "data.txt" WriteMode mapM_ (\(x, y) -> do hPutStr h (show t) hPutStr h " " hPutStrLn h (show (realPart y))) (zip t y) hClose h From agocorona at gmail.com Sun Jun 14 14:51:08 2009 From: agocorona at gmail.com (Alberto G. Corona ) Date: Sun Jun 14 14:34:35 2009 Subject: Fwd: [Haskell-cafe] curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <4A33B318.7090203@functor.nl> <7b501d5c0906130717k1b6ff394x3abe866aa84d2fa2@mail.gmail.com> Message-ID: Once more I forgot to send my messages to the haskell cafe list. All the rest of the list which I?m suscribed to, send the mail replies to the list automatically, but this doesn?t. Please, can this be changed?. ---------- Forwarded message ---------- From: Alberto G. Corona Date: 2009/6/13 Subject: Re: [Haskell-cafe] curious about sum To: Deniz Dogan first, I was completely wrong. It is foldl what is neccesary. sum is defined in terms of foldl: sum= foldl (+) 0 but Prelude> foldl (+) 0 [1..1000000] *** Exception: stack overflow that is not because + is non strict, but because foldl is: foldl f z0 xs0 = lgo z0 xs0 where lgo z [] = z lgo z (x:xs) = lgo (f z x) xs this version of foldl IS strict: foldlStrict f z0 xs0 = lgo z0 xs0 where lgo z [] = z lgo z (x:xs) =let t= f z x in t `seq` lgo t xs main= print $ foldlStrict (+) 0 [1..1000000] 500000500000 so the garbage collector do the job in freeing the consumed part of the list. 2009/6/13 Alberto G. Corona > > Prelude> let strictplus x y= let z=x +y in z `seq` z; sum1= foldr strictplus 0 in sum1[0..1000000] > *** Exception: stack overflow > I suppose that strictplus is strict, so the garbage collector would free the consumed part of the list. > Then, why the stack overflow? > 2009/6/13 Deniz Dogan >> >> 2009/6/13 Jochem Berndsen : >> > Keith Sheppard wrote: >> >> Is there any reason that sum isn't strict? I can't think of any case >> >> where that is a good thing. >> >> >> >> Prelude> sum [0 .. 1000000] >> >> *** Exception: stack overflow >> > >> > It is useful if the (+) is nonstrict; although I cannot think of any >> > useful mathematical structure where (+) would be nonstrict. >> >> I remember needing a non-strict sum at least once, but I do not >> remember the exact application. But imagine having a (very) long list >> of numbers and you want to do A if the sum exceeds a small number, >> otherwise B. >> >> if sum [0..100000] > 10 then A else B >> >> However, this idea didn't work, because of strictness. >> >> -- >> Deniz Dogan >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090614/7ced6adb/attachment-0001.html From tom.davie at gmail.com Sun Jun 14 15:10:57 2009 From: tom.davie at gmail.com (Thomas Davie) Date: Sun Jun 14 14:54:23 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <20090614104751.GB1182@flit> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <4A33B318.7090203@functor.nl> <7b501d5c0906130717k1b6ff394x3abe866aa84d2fa2@mail.gmail.com> <20090614104751.GB1182@flit> Message-ID: On 14 Jun 2009, at 12:47, Roman Cheplyaka wrote: > * Deniz Dogan [2009-06-13 16:17:57+0200] >> I remember needing a non-strict sum at least once, but I do not >> remember the exact application. > > We may agree that lazy sum is sometimes (rarely) needed, but then it > can > be always written as fold. However, in most cases user wants strict > sum. > > So it's not really an excuse. How's this for an "excuse" - Haskell is a lazy language. It also happens to have support for strictifying things when necessary. The Haskell API is designed to be lazy, like the rest of the language, similarly though, where commonly used, strict versions are provided, like for example foldl'. A much better idea than making sum strict, would simply be to add a sum'. Bob From jochem at functor.nl Sun Jun 14 15:23:00 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Sun Jun 14 15:06:28 2009 Subject: Fwd: [Haskell-cafe] curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <4A33B318.7090203@functor.nl> <7b501d5c0906130717k1b6ff394x3abe866aa84d2fa2@mail.gmail.com> Message-ID: <4A354E14.7070205@functor.nl> Alberto G. Corona wrote: > Once more I forgot to send my messages to the haskell cafe list. All the > rest of the list which I?m suscribed to, send the mail replies to the list > automatically, but this doesn?t. Please, can this be changed?. This comes up every so often, but I would be against this. Your e-mail client should support mailing lists. > this version of foldl IS strict: > > foldlStrict f z0 xs0 = lgo z0 xs0 > where > lgo z [] = z > lgo z (x:xs) =let t= f z x in t `seq` lgo t xs > > main= print $ foldlStrict (+) 0 [1..1000000] > 500000500000 > > so the garbage collector do the job in freeing the consumed part of the > list This is correct; the function you defined is equivalent to foldl' in Data.List, if I'm not mistaken. Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From claus.reinke at talk21.com Sun Jun 14 17:29:00 2009 From: claus.reinke at talk21.com (Claus Reinke) Date: Sun Jun 14 17:12:28 2009 Subject: [Haskell-cafe] curious about sum References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com><4A33B318.7090203@functor.nl><7b501d5c0906130717k1b6ff394x3abe866aa84d2fa2@mail.gmail.com><20090614104751.GB1182@flit> Message-ID: > A much better idea than making sum strict, would simply be to add a > sum'. Even better to abstract over strictness, to keep a lid on code duplication? {-# LANGUAGE TypeOperators #-} sum = foldlS ($) (+) 0 sum' = foldlS ($!) (+) 0 -- identity on constructors of t (from a), modulo strictness in a type a :-?> t = (a -> t) -> (a -> t) foldlS :: (b :-?> ([a] -> b)) -> (a -> b -> b) -> (b -> [a] -> b) foldlS ($) op n [] = n foldlS ($) op n (h:t) = (foldlS ($) op $ (op h n)) t Strictness is encoded as a constructor transformer - ($) keeps the constructor in question unchanged, ($!) makes it strict. Also works with container types (Maps strict or not strict in their elements can share the same strictness-abstracted code, for instance). Though sometimes there is more than one strictness choice to make in the same piece of code.. Claus From sjoerd at w3future.com Sun Jun 14 19:29:04 2009 From: sjoerd at w3future.com (Sjoerd Visscher) Date: Sun Jun 14 19:12:36 2009 Subject: [Haskell-cafe] traversal transformations Message-ID: Hi, While playing with Church Encodings of data structures, I realized there are generalisations in the same way Data.Foldable and Data.Traversable are generalisations of lists. The normal Church Encoding of lists is like this: > newtype List a = L { unL :: forall b. (a -> b -> b) -> b -> b } It represents a list by a right fold: > foldr f z l = unL l f z List can be constructed with cons and nil: > nil = L $ \f -> id > cons a l = L $ \f -> f a . unL l f Oleg has written about this: http://okmij.org/ftp/Haskell/zip-folds.lhs Now function of type (b -> b) are endomorphisms which have a Data.Monoid instance, so the type can be generalized: > newtype FM a = FM { unFM :: forall b. Monoid b => (a -> b) -> b } > fmnil = FM $ \f -> mempty > fmcons a l = FM $ \f -> f a `mappend` unFM l f Now lists are represented by (almost) their foldMap function: > instance Foldable FM where > foldMap = flip unFM But notice that there is now nothing list specific in the FM type, nothing prevents us to add other constructor functions. > fmsnoc l a = FM $ \f -> unFM l f `mappend` f a > fmlist = fmcons 2 $ fmcons 3 $ fmnil `fmsnoc` 4 `fmsnoc` 5 *Main> getProduct $ foldMap Product fmlist 120 Now that we have a container type represented by foldMap, there's nothing stopping us to do a container type represented by traverse from Data.Traversable: {-# LANGUAGE RankNTypes #-} import Data.Monoid import Data.Foldable import Data.Traversable import Control.Monad import Control.Applicative newtype Container a = C { travC :: forall f b . Applicative f => (a -> f b) -> f (Container b) } czero :: Container a cpure :: a -> Container a ccons :: a -> Container a -> Container a csnoc :: Container a -> a -> Container a cpair :: Container a -> Container a -> Container a cnode :: Container a -> a -> Container a -> Container a ctree :: a -> Container (Container a) -> Container a cflat :: Container (Container a) -> Container a czero = C $ \f -> pure czero cpure x = C $ \f -> cpure <$> f x ccons x l = C $ \f -> ccons <$> f x <*> travC l f csnoc l x = C $ \f -> csnoc <$> travC l f <*> f x cpair l r = C $ \f -> cpair <$> travC l f <*> travC r f cnode l x r = C $ \f -> cnode <$> travC l f <*> f x <*> travC r f ctree x l = C $ \f -> ctree <$> f x <*> travC l (traverse f) cflat l = C $ \f -> cflat <$> travC l (traverse f) instance Functor Container where fmap g c = C $ \f -> travC c (f . g) instance Foldable Container where foldMap = foldMapDefault instance Traversable Container where traverse = flip travC instance Monad Container where return = cpure m >>= f = cflat $ fmap f m instance Monoid (Container a) where mempty = czero mappend = cpair Note that there are all kinds of "constructors", and they can all be combined. Writing their definitions is similar to how you would write Traversable instances. So I'm not sure what we have here, as I just ran into it, I wasn't looking for a solution to a problem. It is also all quite abstract, and I'm not sure I understand what is going on everywhere. Is this useful? Has this been done before? Are there better implementations of foldMap and (>>=) for Container? Finally, a little example. A Show instance (for debugging purposes) which shows the nesting structure. newtype ShowContainer a = ShowContainer { doShowContainer :: String } instance Functor ShowContainer where fmap _ (ShowContainer x) = ShowContainer $ "(" ++ x ++ ")" instance Applicative ShowContainer where pure _ = ShowContainer "()" ShowContainer l <*> ShowContainer r = ShowContainer $ init l ++ "," ++ r ++ ")" instance Show a => Show (Container a) where show = doShowContainer . traverse (ShowContainer . show) greetings, -- Sjoerd Visscher sjoerd@w3future.com From paul.chiusano at gmail.com Sun Jun 14 19:42:50 2009 From: paul.chiusano at gmail.com (Paul Chiusano) Date: Sun Jun 14 19:26:15 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? Message-ID: Hello, I was recently trying to figure out if there was a way, at runtime, to do better strictness analysis for polymorphic HOFs, for which the strictness of some arguments might depend on the strictness of the strictness of function types that are passed as arguments [1]. As an example, consider foldl. The 'seed' parameter of foldl can be made strict as long as the binary function used for the fold is strict in its arguments. Unfortunately, because strictness analysis is done statically, Haskell can't assume anything about the strictness of the binary function - assuming we only compile one instance of foldl, it must be the most conservative version possible, and that means making the seed parameter lazy. :-( I started thinking about ways you could to a check at runtime for this sort of thing, something to the effect of asking foldl, before heap-allocating a thunk for the seed parameter, whether that parameter could be made strict. foldl could then inspect other arguments that have been supplied, and based on these arguments, evaluate or go ahead with creating a thunk the seed parameter. It's a runtime cost, sure, but would it be more than the cost of having to do an additional heap allocation? In any case a small runtime cost might be worth it if the analysis becomes more uniform. So, my question is: does doing this sort of runtime analysis seem like a horrible idea? Is it even possible? Has anyone tried this in the past? (So far I haven't found anything, but would love references if people have them.) Note that I'm not suggesting Haskell should do anything like this. I'm playing around with the ideas because I'm interesting in creating a lazy language and I was hoping to have strictness analysis be very predictable and uniform, something the programmer can count on and use to simply reason about space usage ... which might be hopelessly unrealistic goal! I guess the more general question is - is "perfect" strictness analysis (however that is defined) possible, if we're willing to incur some runtime cost? What would that look like? Best, Paul [1]: More background on my thinking here - a bit half-baked, so bear with me! http://pchiusano.blogspot.com/2009/06/perfect-strictness-analysis-part-1.html http://pchiusano.blogspot.com/2009/06/perfect-strictness-analysis-part-2.html -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090614/d86a0c49/attachment.html From marco-oweber at gmx.de Sun Jun 14 20:30:39 2009 From: marco-oweber at gmx.de (Marc Weber) Date: Sun Jun 14 20:14:05 2009 Subject: [Haskell-cafe] Haskell EDSL to generate SQL? In-Reply-To: References: Message-ID: <20090615003039.GA22985@gmx.de> On Sat, Apr 04, 2009 at 03:40:56PM +0200, G??nther Schmidt wrote: > Hi, > > I tried to solve some large data processing solely in Haskell so I could > avoid lots of eventually very long and complex SQL statements. You won't find something comparable to SQLAlchemy (python ORM mapper) in haskell yet (AFAIK) :-( Also have a look at: http://www.haskell.org/haskellwiki/MetaHDBC (This means writing SQL, but it will be checked) Marc Weber From gwern0 at gmail.com Sun Jun 14 20:51:13 2009 From: gwern0 at gmail.com (Gwern Branwen) Date: Sun Jun 14 20:34:37 2009 Subject: [Haskell-cafe] Wiki user accounts In-Reply-To: References: <1244822326.28941.29.camel@flippa-eee> Message-ID: On Fri, Jun 12, 2009 at 12:46 PM, Gwern Branwen wrote: ... > If I might suggest some users we might give the bit to: myself, dons, > Magnus Therning, Neil Mitchell, and byorgey. All have been editing the > wiki for some time, some have administrator experience on Wikipedia, > and all have commit bits for various Haskell repos (and so presumably > can be trusted). (Of course, this list isn't intended to be > exhaustive; they're just who comes to mind looking over Recent > Changes.) I've spoken with John Peterson (the other admin/bureaucrat besides Ashley), and he has no problem with giving these people the bit. If there aren't any objections by next Saturday/Sunday, I will email him and ask him to do so. -- gwern From ashley at semantic.org Sun Jun 14 22:14:15 2009 From: ashley at semantic.org (Ashley Yakeley) Date: Sun Jun 14 21:57:40 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: References: <1244822326.28941.29.camel@flippa-eee> Message-ID: <4A35AE77.5030309@semantic.org> Gwern Branwen wrote: >> This runs on MediaWiki, right? How about adding a CAPTCHA for account >> registrations? >> >> http://www.mediawiki.org/wiki/Extension:ConfirmEdit > > See http://haskell.org/haskellwiki/Special:Version > > ConfirmEdit would require an upgrade. This is the ideal solution. But it requires an update of the machine from an old Red Hat distro (RHEL AS release 3 update 9) to something a bit more modern, like Debian 5.0 or Ubuntu Server 9.04. -- Ashley Yakeley From ashley at semantic.org Sun Jun 14 22:53:00 2009 From: ashley at semantic.org (Ashley Yakeley) Date: Sun Jun 14 22:36:24 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: References: <1244822326.28941.29.camel@flippa-eee> Message-ID: <4A35B78C.3040809@semantic.org> Gwern Branwen wrote: > Presumably Ashley is busy. Yes. Average request rate is about one each day; I tend to do them in a lump about once a week. > One solution would be to have Ashley re-enable user registrations. > This has been suggested before, but no one knows how bad the spam > would be. Basically, someone was creating thousands of accounts automatically. It seems likely this will happen again. > Another solution would be to sysop a few users to > admin/bureaucrat, so that even if a few are inactive or away, the rest > can handle requests. What would the process be? -- Ashley Yakeley From ekirpichov at gmail.com Sun Jun 14 23:18:28 2009 From: ekirpichov at gmail.com (Eugene Kirpichov) Date: Sun Jun 14 23:01:51 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? In-Reply-To: References: Message-ID: <5e0214850906142018p247f2f0ftfe15e717ae6c77be@mail.gmail.com> 2009/6/15 Paul Chiusano : > Hello, > I was recently trying to figure out if there was a way, at runtime, to do > better strictness analysis for polymorphic HOFs, for which the strictness of > some arguments might depend on the strictness of the strictness of function > types that are passed as arguments [1]. As an example, consider foldl. The > 'seed' parameter of foldl can be made strict as long as the binary function > used for the fold is strict in its arguments. Unfortunately, because > strictness analysis is done statically, Haskell can't assume anything about > the strictness of the binary function - assuming we only compile one > instance of foldl, it must be the most conservative version possible, and > that means making the seed parameter lazy. :-( > I started thinking about ways you could to a check at runtime for this sort > of thing, something to the effect of asking foldl, before heap-allocating a > thunk for the seed parameter, whether that parameter could be made strict. > foldl could then inspect other arguments that have been supplied, and based > on these arguments, evaluate or go ahead with creating a thunk the seed > parameter. It's a runtime cost, sure, but would it be more than the cost of > having to do an additional heap allocation? In any case a small runtime cost > might be worth it if the analysis becomes more uniform. > So, my question is: does doing this sort of runtime analysis seem like a > horrible idea? Is it even possible? Has anyone tried this in the past? (So > far I haven't found anything, but would love references if people have > them.) > Note that I'm not suggesting Haskell should do anything like this. I'm > playing around with the ideas because I'm interesting in creating a lazy > language and I was hoping to have strictness analysis be very predictable > and uniform,?something the programmer can count on and use to simply reason > about space usage ... which might be hopelessly unrealistic goal! I guess > the more general question is - is "perfect" strictness analysis (however > that is defined) possible, if we're willing to incur some runtime cost? What > would that look like? The idea looks cool, but perfect strictness analysis is not possible, t.i. the problem of determining whether f _|_ = _|_ is undecidable, since it is a non-trivial property of f (there exist f's for which it is true, and ones for which it is false) and non-trivial properties are undecidable, thanks to Rice theorem. > Best, > Paul > [1]: > More background on my thinking here - a bit half-baked, so bear with me! > ??http://pchiusano.blogspot.com/2009/06/perfect-strictness-analysis-part-1.html > ??http://pchiusano.blogspot.com/2009/06/perfect-strictness-analysis-part-2.html > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- Eugene Kirpichov Web IR developer, market.yandex.ru From ok at cs.otago.ac.nz Sun Jun 14 23:18:46 2009 From: ok at cs.otago.ac.nz (Richard O'Keefe) Date: Sun Jun 14 23:02:10 2009 Subject: [Haskell-cafe] Performance of functional priority queues Message-ID: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> There's a current thread in the Erlang mailing list about priority queues. I'm aware of, for example, the Brodal/Okasaki paper and the David King paper. I'm also aware of James Cook's priority queue package in Hackage, have my own copy of Okasaki's book, and have just spent an hour searching the web. One of the correspondents in that thread claims that it is provably impossible to have an efficient priority queue implementation without mutability. I think he's cuckoo. But I'd like to have some numbers to back me up. Can anyone point me to some actual benchmark results comparing priority queue performance *with* mutation and priority queue performance *without* mutation, in the same functional or mostly-functional language? From ok at cs.otago.ac.nz Sun Jun 14 23:38:44 2009 From: ok at cs.otago.ac.nz (Richard O'Keefe) Date: Sun Jun 14 23:22:11 2009 Subject: [Haskell-cafe] I need a hint in list processing In-Reply-To: <1d5d51400906140106n3b391c5au3a1cfda421509e1d@mail.gmail.com> References: <1d5d51400906140106n3b391c5au3a1cfda421509e1d@mail.gmail.com> Message-ID: <48B5CA6F-A6BD-4E7E-85D2-3532B59A0634@cs.otago.ac.nz> On 14 Jun 2009, at 8:06 pm, Fernan Bolando wrote: > Hi all > > If I have a number of list > example > list1 = [2,3] > list2 = [1,2] > list3 = [2,3,4] > list4 = [1,2,3] > > I want to create a list from the list above with n elements, > non-repeating and each elements index represents 1 of the elements > from the corresponding list so for the above input I would get. > > a = [3,2,4,1] I have been staring at this off and on all day, and I haven't the faintest idea what you want. What is "n". What is it that doesn't repeat? How does the index of an element represent 1 element? Which list corresponds to what? I'm beginning to suspect that what you want is a "choice" function: f [s1,...,sn] = [x1,...,xn] when each xi is an element of the corresponding si and no two xs are the same. Instead of finding one answer, let's find them all. all_choices :: Eq a => [[a]] -> [[a]] all_choices [] = [[]] all_choices (set:sets) = [x:xs | xs <- all_choices sets, x <- set, not(x `elem` xs)] The test case all_choices [[2,3], [1,2], [2,3,4], [1,2,3]] has the answer [[3,2,4,1], [3,1,4,2], [2,1,4,3]] and you probably want to use it something like case all_choices sets of [] -> there are no such choices (first_choice:_) -> first_choice is one such choice For inputs like [[1,2],[2,1],[1]] there is of course no such choice function. From tonymorris at gmail.com Sun Jun 14 23:55:12 2009 From: tonymorris at gmail.com (Tony Morris) Date: Sun Jun 14 23:38:38 2009 Subject: [Haskell-cafe] I need a hint in list processing In-Reply-To: <48B5CA6F-A6BD-4E7E-85D2-3532B59A0634@cs.otago.ac.nz> References: <1d5d51400906140106n3b391c5au3a1cfda421509e1d@mail.gmail.com> <48B5CA6F-A6BD-4E7E-85D2-3532B59A0634@cs.otago.ac.nz> Message-ID: <4A35C620.2060003@gmail.com> nub . concat ? Richard O'Keefe wrote: > > On 14 Jun 2009, at 8:06 pm, Fernan Bolando wrote: > >> Hi all >> >> If I have a number of list >> example >> list1 = [2,3] >> list2 = [1,2] >> list3 = [2,3,4] >> list4 = [1,2,3] >> >> I want to create a list from the list above with n elements, >> non-repeating and each elements index represents 1 of the elements >> from the corresponding list so for the above input I would get. >> >> a = [3,2,4,1] > > I have been staring at this off and on all day, > and I haven't the faintest idea what you want. > > What is "n". What is it that doesn't repeat? > How does the index of an element represent 1 element? > Which list corresponds to what? > > I'm beginning to suspect that what you want is a "choice" > function: > f [s1,...,sn] = [x1,...,xn] > when each xi is an element of the corresponding si > and no two xs are the same. > > Instead of finding one answer, let's find them all. > > all_choices :: Eq a => [[a]] -> [[a]] > all_choices [] = [[]] > all_choices (set:sets) = > [x:xs | xs <- all_choices sets, x <- set, not(x `elem` xs)] > > The test case > > all_choices [[2,3], [1,2], [2,3,4], [1,2,3]] > > has the answer > > [[3,2,4,1], [3,1,4,2], [2,1,4,3]] > > and you probably want to use it something like > > case all_choices sets of > [] -> there are no such choices > (first_choice:_) -> first_choice is one such choice > > For inputs like [[1,2],[2,1],[1]] there is of course no such > choice function. > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- Tony Morris http://tmorris.net/ From tonymorris at gmail.com Mon Jun 15 01:17:47 2009 From: tonymorris at gmail.com (Tony Morris) Date: Mon Jun 15 01:01:14 2009 Subject: [Haskell-cafe] I need a hint in list processing In-Reply-To: <32AEE5AD-F75A-4DB0-881D-DB2A3718FE5E@cs.otago.ac.nz> References: <1d5d51400906140106n3b391c5au3a1cfda421509e1d@mail.gmail.com> <48B5CA6F-A6BD-4E7E-85D2-3532B59A0634@cs.otago.ac.nz> <4A35C620.2060003@gmail.com> <2A0A2D98-03B8-4A6B-8A78-EFB0892AC624@cs.otago.ac.nz> <4A35CD6B.7090702@gmail.com> <32AEE5AD-F75A-4DB0-881D-DB2A3718FE5E@cs.otago.ac.nz> Message-ID: <4A35D97B.8080009@gmail.com> Just guessing. How do you know it's an accident? Richard O'Keefe wrote: > > On 15 Jun 2009, at 4:26 pm, Tony Morris wrote: > >> Prelude Data.List> nub . concat $ [[2, 3], [1, 2], [2, 3, 4], [1, 2, 3]] >> [2,3,1,4] > > In this particular case. But that's a lucky accident.\ > > -- Tony Morris http://tmorris.net/ From dagit at codersbase.com Mon Jun 15 01:23:55 2009 From: dagit at codersbase.com (Jason Dagit) Date: Mon Jun 15 01:07:19 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? In-Reply-To: <5e0214850906142018p247f2f0ftfe15e717ae6c77be@mail.gmail.com> References: <5e0214850906142018p247f2f0ftfe15e717ae6c77be@mail.gmail.com> Message-ID: On Sun, Jun 14, 2009 at 8:18 PM, Eugene Kirpichov wrote: > The idea looks cool, but perfect strictness analysis is not possible, > t.i. the problem of determining whether f _|_ = _|_ is undecidable, > since it is a non-trivial property of f (there exist f's for which it > is true, and ones for which it is false) and non-trivial properties > are undecidable, thanks to Rice theorem. Unless you remove _|_ from the language. If you have a "total" functional programming language[1] it becomes a trivial property, right? I guess this would also extend to some dependently typed languages too. [1] http://lambda-the-ultimate.org/node/2003 Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/0c4edaf9/attachment.html From vigalchin at gmail.com Mon Jun 15 01:53:31 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Mon Jun 15 01:36:53 2009 Subject: [Haskell-cafe] a now abandoned experimental extension to Haskell? Message-ID: <5ae4f2ba0906142253q104be542n5946abad03cb299d@mail.gmail.com> Hello, In some code that I am cabalizing I ran into: type DataLiteral = <<< ref RDFgraph defs >>> type URIReference = <<< ref RDFgraph defs >>> type NonNegativeInteger = <<< ??? >>> What is this? Kind regards, Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/8d19f6a7/attachment.html From ashley at semantic.org Mon Jun 15 02:39:09 2009 From: ashley at semantic.org (Ashley Yakeley) Date: Mon Jun 15 02:22:32 2009 Subject: [Haskell-cafe] Logo In-Reply-To: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> Message-ID: <4A35EC8D.7030103@semantic.org> Thomas Davie wrote: > We had a lot of "fun" deciding Haskell's new logo, and while I don't > agree with the final result, it would be nice if we could now start > consistently using it. With that in mind, I realised that the Haskell > Platform's logo is totally different, and did a quick mock up of a > version reflecting the current Haskell logo. It needs someone with the > original vector graphics to have a play and improve it a little bit, but > hopefully you'll se a concept you like. I rather like the fact that the Haskell Platform logo is distinct from the Haskell logo. I think it helps prevent confusion (even though the Platform logo is based on one of the Haskell logo competition entrants). http://haskell.org/haskellwiki/Haskell_Platform By the way, when I came to replace the Haskell logo on the wiki site, since the colours had not and still have not been officially decided on, I just picked the same colours as the Haskell Platform logo. So for the time being, there is a visual link between the two logos. -- Ashley Yakeley From ttencate at gmail.com Mon Jun 15 03:15:32 2009 From: ttencate at gmail.com (Thomas ten Cate) Date: Mon Jun 15 02:58:53 2009 Subject: [Haskell-cafe] slow code In-Reply-To: <9621AF5D-5C87-43A6-B8A2-103109570416@aracnet.com> References: <9621AF5D-5C87-43A6-B8A2-103109570416@aracnet.com> Message-ID: How much output does this generate? Does it matter if you send the output to /dev/null? This looks as if the bottleneck might well be in I/O operations, not in the code itself. To find this out, you could rewrite the code in C and see if that makes a difference? Thomas On Sun, Jun 14, 2009 at 20:44, brian wrote: > Haskell Gurus, > > I have tried to use profiling to tell me what's going on here, but it hasn't > helped much, probably because I'm not interpreting the results correctly. > > Empirically I have determined that the show's are pretty slow, so an > alternative to them would be helpful. ?I replaced the show's with "", and > compiled with -O2 and not much improvement. > > I need to write _a lot_ of code in this style. ?A few words about how best > to do this would be helpful. ?Laziness, infinite lists, uvector ?? > > Help... > > Thanks, > > Brian > > > import Complex > import System.IO > > genData :: Double -> Int -> (Double -> Complex Double) -> ([Double], > [Complex Double]) > genData tstop n f = > ? ?let deltat = tstop / (fromIntegral n) > ? ? ? ?t = [ fromIntegral(i) * deltat | i <- [0..n-1]] > ? ?in > ? ? ?(t, map f t) > > main = > ? ?do let (t, y) = genData 100.0E-6 (2 ^ 15) (\x -> x :+ 0.0) > ? ? ? h <- openFile "data.txt" WriteMode > ? ? ? mapM_ (\(x, y) -> > ? ? ? ? ? ? ? ? ?do hPutStr h (show t) > ? ? ? ? ? ? ? ? ? ? hPutStr h " " > ? ? ? ? ? ? ? ? ? ? hPutStrLn h (show (realPart y))) > ? ? ? ? ? ? ? ? (zip t y) > ? ? ? hClose h > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From ttencate at gmail.com Mon Jun 15 03:18:01 2009 From: ttencate at gmail.com (Thomas ten Cate) Date: Mon Jun 15 03:01:25 2009 Subject: Fwd: [Haskell-cafe] curious about sum In-Reply-To: <4A354E14.7070205@functor.nl> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <4A33B318.7090203@functor.nl> <7b501d5c0906130717k1b6ff394x3abe866aa84d2fa2@mail.gmail.com> <4A354E14.7070205@functor.nl> Message-ID: On Sun, Jun 14, 2009 at 21:23, Jochem Berndsen wrote: > Alberto G. Corona wrote: >> Once more I forgot to send my messages to the haskell cafe list. All the >> rest of the list which I=E3=B7 suscribed to, send the mail replies to t= he list >> automatically, but this doesn=90=D4. Please, can this be changed?. > > This comes up every so often, but I would be against this. Your e-mail > client should support mailing lists. This list does not fill out the Reply-To header. Many other lists do. I am all for adding it, if there's no specific reason not to. Thomas From miguelimo38 at yandex.ru Mon Jun 15 03:22:36 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Mon Jun 15 03:06:58 2009 Subject: Fwd: [Haskell-cafe] curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <4A33B318.7090203@functor.nl> <7b501d5c0906130717k1b6ff394x3abe866aa84d2fa2@mail.gmail.com> <4A354E14.7070205@functor.nl> Message-ID: <4A35F6BC.4060804@yandex.ru> Again: what if somebody wants to answer to the original author privately? It's easier to just use "Reply" for private answers and "Reply all" for list answers. Thomas ten Cate wrote on 15.06.2009 11:18: > On Sun, Jun 14, 2009 at 21:23, Jochem Berndsen wrote: >> Alberto G. Corona wrote: >>> Once more I forgot to send my messages to the haskell cafe list. All the >>> rest of the list which Iã· suscribed to, send the mail replies to the list >>> automatically, but this doesnÔ. Please, can this be changed?. >> This comes up every so often, but I would be against this. Your e-mail >> client should support mailing lists. > > This list does not fill out the Reply-To header. Many other lists do. > I am all for adding it, if there's no specific reason not to. > > Thomas > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From roma at ro-che.info Mon Jun 15 03:30:05 2009 From: roma at ro-che.info (Roman Cheplyaka) Date: Mon Jun 15 03:13:29 2009 Subject: [Haskell-cafe] [cabal] How to deal with build-depency that not under cabal's control? In-Reply-To: <3bd412d40906141901w36636822va512f24cb6484f14@mail.gmail.com> References: <3bd412d40906140230rb7a0525v40a806f64196fe21@mail.gmail.com> <20090614102542.GA1182@flit> <3bd412d40906140348m35a40a18se29cb980c49dfa95@mail.gmail.com> <20090614105258.GA4604@flit> <3bd412d40906141901w36636822va512f24cb6484f14@mail.gmail.com> Message-ID: <20090615073005.GA24792@flit> I'm CC:ing Duncan, probably he can help. * Magicloud Magiclouds [2009-06-15 10:01:03+0800] > # ghc-pkg list gtk > /var/lib/ghc-6.10.3/./package.conf: > /home/shidaw/.ghc/i386-linux-6.10.3/package.conf: > gtk-0.10.1 > Well, still, I have the problem.... > > On Sun, Jun 14, 2009 at 6:52 PM, Roman Cheplyaka wrote: > > * Magicloud Magiclouds [2009-06-14 18:48:26+0800] > >> My gtk2hs is install manually, `configure && make && make install`. So > > > > It's okay. > > > >> when I add gtk to build-dependency, it tells me > >> Setup.hs: At least the following dependencies are missing: > >> gtk -any > > > > Installation of gtk2hs registers these packages for you. > > Again, check `ghc-pkg list gtk`. If you installed gtk2hs, it must be > > there. If you, say, upgraded your ghc after you installed gtk2hs, you > > have to reinstall gtk2hs. > > > >> How to register my manual-installed gtk2hs to cabal? > >> > >> On Sun, Jun 14, 2009 at 6:25 PM, Roman Cheplyaka wrote: > >> > * Magicloud Magiclouds [2009-06-14 17:30:33+0800] > >> >> Hi, > >> >> ? I use gtk2hs in linux. Well, I have no idea how to install gtk2hs by > >> >> cabal, but my program needs it, and I want my program cabalized. So > >> >> how to do this? > >> >> Thanks. > >> > > >> > gtk2hs consists of several cabal packages, e.g. gtk, glib and so on. > >> > (See `ghc-pkg list`) > >> > Specify those of them you need as dependencies in cabal file. > >> > > >> > -- > >> > Roman I. Cheplyaka :: http://ro-che.info/ > >> > "Don't let school get in the way of your education." - Mark Twain > >> > _______________________________________________ > >> > Haskell-Cafe mailing list > >> > Haskell-Cafe@haskell.org > >> > http://www.haskell.org/mailman/listinfo/haskell-cafe > >> > > >> > >> > >> > >> -- > >> ??????? > >> ??????? > > > > -- > > Roman I. Cheplyaka :: http://ro-che.info/ > > "Don't let school get in the way of your education." - Mark Twain > > > > > > -- > ??????? > ??????? -- Roman I. Cheplyaka :: http://ro-che.info/ "Don't let school get in the way of your education." - Mark Twain From lrpalmer at gmail.com Mon Jun 15 03:54:32 2009 From: lrpalmer at gmail.com (Luke Palmer) Date: Mon Jun 15 03:37:53 2009 Subject: [Haskell-cafe] Performance of functional priority queues In-Reply-To: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> References: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> Message-ID: <7ca3f0160906150054l3379fbcej5349bf95b86ad438@mail.gmail.com> On Sun, Jun 14, 2009 at 9:18 PM, Richard O'Keefe wrote: > There's a current thread in the Erlang mailing list about > priority queues. I'm aware of, for example, the Brodal/Okasaki > paper and the David King paper. I'm also aware of James Cook's > priority queue package in Hackage, have my own copy of Okasaki's > book, and have just spent an hour searching the web. > > One of the correspondents in that thread claims that it is > provably impossible to have an efficient priority queue implementation > without mutability. If he so claims, maybe you can challenge him by asking for a proof? Such a proof would probably only involve asymptotics, since it's very hard to *prove* anything when actual raw speed is involved. If that's the case, you can use Okasaki to back yourself up (or back him up; I am not familiar with the results in this area). I've seen in a few programming circles now that "provably" is used as a weasel word. Provably, eh? Where's the proof? Luke > I think he's cuckoo. But I'd like to have some > numbers to back me up. > > Can anyone point me to some actual benchmark results comparing > priority queue performance *with* mutation and priority queue > performance *without* mutation, in the same functional or > mostly-functional language? > > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/19a88207/attachment.html From alp at mestan.fr Mon Jun 15 03:58:03 2009 From: alp at mestan.fr (Alp Mestan) Date: Mon Jun 15 03:41:27 2009 Subject: [Haskell-cafe] Backpropagation implementation for a neural net library Message-ID: Dear List, I'm working with a friend of mine on a Neural Net library in Haskell. There are 3 files : neuron.hs, layer.hs and net.hs. neuron.hs defines the Neuron data type and many utility functions, all of which have been tested and work well. layer.hs defines layer-level functions (computing the output of a whole layer of neurons, etc). Tested and working. net.hs defines net-level functions (computing the output of a whole neural net) and the famous -- but annoying -- back-propagation algorithm. You can find them there : http://mestan.fr/haskell/nn/html/ The problem is that here when I ask for final_net or test_output (anything after the train call, in net.hs), it seems to loop and loop around, as if it never gets the error under 0.1. So I was just wondering if there was one or more Neural Nets and Haskell wizard in there to check the back-propagation implementation, given in net.hs, that seems to be wrong. Thanks a lot ! -- Alp Mestan -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/867b339c/attachment.html From lrpalmer at gmail.com Mon Jun 15 04:19:56 2009 From: lrpalmer at gmail.com (Luke Palmer) Date: Mon Jun 15 04:03:20 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? In-Reply-To: References: Message-ID: <7ca3f0160906150119x5ce3b3f0gd90cb5637a8d8425@mail.gmail.com> On Sun, Jun 14, 2009 at 5:42 PM, Paul Chiusano wrote: > > Note that I'm not suggesting Haskell should do anything like this. I'm > playing around with the ideas because I'm interesting in creating a lazy > language and I was hoping to have strictness analysis be very predictable > and uniform, something the programmer can count on and use to simply reason > about space usage ... which might be hopelessly unrealistic goal! > Others have commented on the undecidability of your problem. I can't come up with a reasonable definition of "perfect" which is decidable (but that may be due to lack of imagination on my part). However, there is nothing undecidable about your larger goal of creating a lazy language with easy space reasoning. I wholeheartedly support this effort, and hope you will continue to blog about your ideas in this area. Luke -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/ef37de7d/attachment.html From duncan.coutts at worc.ox.ac.uk Mon Jun 15 04:20:32 2009 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Mon Jun 15 04:03:56 2009 Subject: [Haskell-cafe] [cabal] How to deal with build-depency that not under cabal's control? In-Reply-To: <20090615073005.GA24792@flit> References: <3bd412d40906140230rb7a0525v40a806f64196fe21@mail.gmail.com> <20090614102542.GA1182@flit> <3bd412d40906140348m35a40a18se29cb980c49dfa95@mail.gmail.com> <20090614105258.GA4604@flit> <3bd412d40906141901w36636822va512f24cb6484f14@mail.gmail.com> <20090615073005.GA24792@flit> Message-ID: <1245054032.26313.991.camel@localhost> http://haskell.org/cabal/FAQ.html#runghc-setup-complains-of-missing-packages On Mon, 2009-06-15 at 10:30 +0300, Roman Cheplyaka wrote: > I'm CC:ing Duncan, probably he can help. > > * Magicloud Magiclouds [2009-06-15 10:01:03+0800] > > # ghc-pkg list gtk > > /var/lib/ghc-6.10.3/./package.conf: > > /home/shidaw/.ghc/i386-linux-6.10.3/package.conf: > > gtk-0.10.1 > > Well, still, I have the problem.... > > > > On Sun, Jun 14, 2009 at 6:52 PM, Roman Cheplyaka wrote: > > > * Magicloud Magiclouds [2009-06-14 18:48:26+0800] > > >> My gtk2hs is install manually, `configure && make && make install`. So > > > > > > It's okay. > > > > > >> when I add gtk to build-dependency, it tells me > > >> Setup.hs: At least the following dependencies are missing: > > >> gtk -any > > > > > > Installation of gtk2hs registers these packages for you. > > > Again, check `ghc-pkg list gtk`. If you installed gtk2hs, it must be > > > there. If you, say, upgraded your ghc after you installed gtk2hs, you > > > have to reinstall gtk2hs. > > > > > >> How to register my manual-installed gtk2hs to cabal? > > >> > > >> On Sun, Jun 14, 2009 at 6:25 PM, Roman Cheplyaka wrote: > > >> > * Magicloud Magiclouds [2009-06-14 17:30:33+0800] > > >> >> Hi, > > >> >> I use gtk2hs in linux. Well, I have no idea how to install gtk2hs by > > >> >> cabal, but my program needs it, and I want my program cabalized. So > > >> >> how to do this? > > >> >> Thanks. > > >> > > > >> > gtk2hs consists of several cabal packages, e.g. gtk, glib and so on. > > >> > (See `ghc-pkg list`) > > >> > Specify those of them you need as dependencies in cabal file. > > >> > > > >> > -- > > >> > Roman I. Cheplyaka :: http://ro-che.info/ > > >> > "Don't let school get in the way of your education." - Mark Twain > > >> > _______________________________________________ > > >> > Haskell-Cafe mailing list > > >> > Haskell-Cafe@haskell.org > > >> > http://www.haskell.org/mailman/listinfo/haskell-cafe > > >> > > > >> > > >> > > >> > > >> -- > > >> ??????? > > >> ??????? > > > > > > -- > > > Roman I. Cheplyaka :: http://ro-che.info/ > > > "Don't let school get in the way of your education." - Mark Twain > > > > > > > > > > > -- > > ??????? > > ??????? > From ketil at malde.org Mon Jun 15 04:24:11 2009 From: ketil at malde.org (Ketil Malde) Date: Mon Jun 15 04:07:34 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <7ca3f0160906121529r13efcb38r1ea0392c63af8165@mail.gmail.com> (Luke Palmer's message of "Fri\, 12 Jun 2009 16\:29\:54 -0600") References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <6f9f8f4a0906120127x2c1cce01x6abf6cae17f7ee19@mail.gmail.com> <02E3B702-2B26-4513-B5E9-EFDB95E4C4ED@gmail.com> <317ca7670906120147x68e3be10p873f6be9a790aed9@mail.gmail.com> <7b501d5c0906120157w78cb299dj1ab7a5a5189329f1@mail.gmail.com> <7b501d5c0906120215t2f79a7ebi4396f94dc85e11a1@mail.gmail.com> <6DD7CAD2-585C-4CE2-B8C8-1A4E99995011@gmail.com> <7ca3f0160906121529r13efcb38r1ea0392c63af8165@mail.gmail.com> Message-ID: <87tz2hdhw4.fsf@malde.org> Luke Palmer writes: > Nice work, I love this one. :-) Yes, very nice. I do find the lambda and > too fat, but I presume that's the way the Haskell logo looks. Also, I think the right edges of the thick part of the batteries should be aligned, so that the little "knob" on the + extends further than the flat end of the -. -k -- If I haven't seen further, it is by standing in the footprints of giants From lrpalmer at gmail.com Mon Jun 15 04:33:48 2009 From: lrpalmer at gmail.com (Luke Palmer) Date: Mon Jun 15 04:17:12 2009 Subject: [Haskell-cafe] I need a hint in list processing In-Reply-To: <1d5d51400906140106n3b391c5au3a1cfda421509e1d@mail.gmail.com> References: <1d5d51400906140106n3b391c5au3a1cfda421509e1d@mail.gmail.com> Message-ID: <7ca3f0160906150133l35d1afa5w237d320bed8151e9@mail.gmail.com> On Sun, Jun 14, 2009 at 2:06 AM, Fernan Bolando wrote: > Hi all > > If I have a number of list > example > list1 = [2,3] > list2 = [1,2] > list3 = [2,3,4] > list4 = [1,2,3] > > I want to create a list from the list above with n elements, > non-repeating and each elements index represents 1 of the elements > from the corresponding list so for the above input I would get. > > a = [3,2,4,1] > > ofcourse there may be several set that will satisfy the problem, so a > list of list that satisfies would be good. I will rephrase the problem, since some folks seem to be having a hard time understanding it. You want a list of four elements. The first element comes from list1, the second from list2, .... And there should be no duplicates in the solution. To start you off, here is a selection function, which computes all such lists, but does not remove duplicates. select :: [[a]] -> [[a]] select [] = [[]] select (xs:xss) = [ x:rest | y <- xs; rest <- select xss ] Filtering out the duplicate-free lists should not be a problem. Note: this is not an efficient solution, it is just to get you started. Making it efficient will require understanding and modifying the above select function, which ought to be an educational experience :-) Luke > > How do I do this in haskell? or is there a code snippet that seems to > work similarly? > > thanks > fernan > > -- > http://www.fernski.com > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/3fe839d5/attachment.html From miguelimo38 at yandex.ru Mon Jun 15 04:39:45 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Mon Jun 15 04:24:07 2009 Subject: [Haskell-cafe] Parametrized monads Message-ID: <4A3608D1.3010405@yandex.ru> Hi! Suppose I want to create a specific monad as a combination of monad transformers - something like "StateT smth1 (ReaderT smth2 Identity)". As you can see, each transformer is parametrized with a type of kind *. I want to abstract these parameters, so that instead of "StateT smth..." I can write something like Zip (ConsT StateT (ConsT ReaderT NilT)) (ConsA smth1 (ConsA smth2 NilA)) Identity and it would be a type isomorphic to the first one. I mean, I want (ConsT StateT (ConsT ReaderT NilT))" to be a separate entity of fixed kind, so that I can, say, create a class instance for it or something. I'd be quite happy if list length appears as a separate parameter, like Zip (Succ (Succ Zero)) (ConsT ... I would NOT be happy with something like Zip (List_2 StateT ReaderT) (Arg_2 smth1 smth2) If haskell had polymorphic kinds, I'd be able to do it easily; unfortunately, it doesn't have them. Thanks From lrpalmer at gmail.com Mon Jun 15 05:03:36 2009 From: lrpalmer at gmail.com (Luke Palmer) Date: Mon Jun 15 04:46:58 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: <24023759.post@talk.nabble.com> References: <24022673.post@talk.nabble.com> <24023759.post@talk.nabble.com> Message-ID: <7ca3f0160906150203w53a42530wca7f8578527d82fb@mail.gmail.com> On Sun, Jun 14, 2009 at 11:14 AM, Gjuro Chensen wrote: > > Gjuro Chensen wrote: > > > > > > /cut > > > > > > I dont know everyone will see this, but I would like thank everyone who > found time to help, and not spam too much doing it:D. > Well, I did it! Its not great (especially comparing to those one line > solutions, wow!), but it works. Nice work. For fun, I'm going to semi-formally transform your solution into the one-liner that was given (multiple times). Systematic transformation is one of the great joys of functional programming. I don't know if you'll find this interesting, but I do, so here goes: myIsUpper = isUpper for ASCII, so let's just assume that. > module Main where > > startsWithUpper :: String -> Bool > startsWithUpper []= False > startsWithUpper string = > if myIsUpper(head(string)) then True > else False We can transform this to: startsWithUpper string = isUpper (head string) Under the precondition that the input is not []. So this function has become less general. Now a few systematic transformations to make this smaller: startsWithUpper string = isUpper (head string) startsWithUpper = \string -> isUpper (head string) startsWithUpper = isUpper . head That last step because: f . g = \x -> f (g x) checkAll string = check (words string) checkAll = \string -> check (words string) checkAll = check . words For the same reason as above. check :: [String] -> Bool > check []=False > check x = > if all startsWithUpper x then True > else False Rewriting the second clause after observing that "if p then True else False" is the same as "p". check [] = False check x = all startsWithUpper x I'm going to take Jochem's suggestion and change the empty clause to True: "all words start with an upper case letter" is equivalent to "there is no word which does not start with an upper case letter", which is true for an empty list. check [] = True check x = all startsWithUpper x Now, in ghci: ghci> all undefined [] True Since this returned True for undefined, it will return True for any argument whatsoever there (this is called the "monotone" property, and all Haskell functions obey it). Therefore, we can remove the empty list clause: check x = all startsWithUpper x And systematic transformations: check = \x -> all startsWithUpper x check = all startsWithUpper So that leaves us with: starsWithUpper = isUpper . head checkAll = check . words check = all startsWithUpper Substituting the local definitions: checkAll = all (isUpper . head) . words The last thing: we made startsWithUpper less general in the process; it is undefined for empty strings. We need to verify that words never returns any empty strings. I did this using SmallCheck: ghci> import Test.SmallCheck ghci> smallCheck 10 $ \string -> all (not . null) (words string) Depth 0: Completed 1 test(s) without failure. Depth 1: Completed 2 test(s) without failure. Depth 2: Completed 5 test(s) without failure. Depth 3: Completed 16 test(s) without failure. Depth 4: Completed 65 test(s) without failure. Depth 5: Completed 326 test(s) without failure. Depth 6: Completed 1957 test(s) without failure. Depth 7: Completed 13700 test(s) without failure. Depth 8: Completed 109601 test(s) without failure. Depth 9: Completed 986410 test(s) without failure. Depth 10: Completed 9864101 test(s) without failure. So I am reasonably confident that words never gives me any empty strings. Tada! Your solution is almost exactly the same as the one-liners! :-) Luke -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/2cd55418/attachment.html From lrpalmer at gmail.com Mon Jun 15 05:11:35 2009 From: lrpalmer at gmail.com (Luke Palmer) Date: Mon Jun 15 04:54:56 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: <7ca3f0160906150203w53a42530wca7f8578527d82fb@mail.gmail.com> References: <24022673.post@talk.nabble.com> <24023759.post@talk.nabble.com> <7ca3f0160906150203w53a42530wca7f8578527d82fb@mail.gmail.com> Message-ID: <7ca3f0160906150211p7d4ee633ydf183cd98683a23@mail.gmail.com> On Mon, Jun 15, 2009 at 3:03 AM, Luke Palmer wrote: > > The last thing: we made startsWithUpper less general in the process; it is > undefined for empty strings. We need to verify that words never returns any > empty strings. I did this using SmallCheck: > > ghci> import Test.SmallCheck > ghci> smallCheck 10 $ \string -> all (not . null) (words string) > 'Course, it turns out that SmallCheck never generates any spaces... ever. Some verifier that is. By careful inspection of the definition of words, I can see that it never returns an empty string. I couldn't find a better way to convince myself of this (I like to avoid looking at definitions when possible). Luke > Depth 0: > Completed 1 test(s) without failure. > Depth 1: > Completed 2 test(s) without failure. > Depth 2: > Completed 5 test(s) without failure. > Depth 3: > Completed 16 test(s) without failure. > Depth 4: > Completed 65 test(s) without failure. > Depth 5: > Completed 326 test(s) without failure. > Depth 6: > Completed 1957 test(s) without failure. > Depth 7: > Completed 13700 test(s) without failure. > Depth 8: > Completed 109601 test(s) without failure. > Depth 9: > Completed 986410 test(s) without failure. > Depth 10: > Completed 9864101 test(s) without failure. > > So I am reasonably confident that words never gives me any empty strings. > > Tada! Your solution is almost exactly the same as the one-liners! :-) > > Luke > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/0e249480/attachment.html From sebastian.sylvan at gmail.com Mon Jun 15 05:40:32 2009 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Mon Jun 15 05:23:55 2009 Subject: [Haskell-cafe] Performance of functional priority queues In-Reply-To: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> References: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> Message-ID: <3d96ac180906150240m3ee9f02ey7263a4b18a2debb3@mail.gmail.com> On Mon, Jun 15, 2009 at 4:18 AM, Richard O'Keefe wrote: > There's a current thread in the Erlang mailing list about > priority queues. I'm aware of, for example, the Brodal/Okasaki > paper and the David King paper. I'm also aware of James Cook's > priority queue package in Hackage, have my own copy of Okasaki's > book, and have just spent an hour searching the web. > > One of the correspondents in that thread claims that it is > provably impossible to have an efficient priority queue implementation A priority queue based on skewed binomial heaps is asymptotically optimal (O(1) for everything except deleteMin which is O(log n)), so if that's what he means by "efficient" then he's most definitely wrong. If he's talking about "small constant factors" then it's harder to understand what he's referring to more precisely, and therefore what he means by "provably". -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/e39453c5/attachment.html From daniel.is.fischer at web.de Mon Jun 15 05:56:54 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Jun 15 05:41:04 2009 Subject: [Haskell-cafe] Haskell - string to list isusses, and more In-Reply-To: <7ca3f0160906150203w53a42530wca7f8578527d82fb@mail.gmail.com> References: <24022673.post@talk.nabble.com> <24023759.post@talk.nabble.com> <7ca3f0160906150203w53a42530wca7f8578527d82fb@mail.gmail.com> Message-ID: <200906151156.54383.daniel.is.fischer@web.de> Am Montag 15 Juni 2009 11:03:36 schrieb Luke Palmer: > We can transform this to: > > startsWithUpper string = isUpper (head string) > > Under the precondition that the input is not []. ?So this function has > become less general. What about all isUpper . take 1 ? But of course the source reveals that words never puts an empty string into the list. From ttencate at gmail.com Mon Jun 15 05:59:57 2009 From: ttencate at gmail.com (Thomas ten Cate) Date: Mon Jun 15 05:43:19 2009 Subject: [Haskell-cafe] Logo fun In-Reply-To: <87tz2hdhw4.fsf@malde.org> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <6f9f8f4a0906120127x2c1cce01x6abf6cae17f7ee19@mail.gmail.com> <02E3B702-2B26-4513-B5E9-EFDB95E4C4ED@gmail.com> <317ca7670906120147x68e3be10p873f6be9a790aed9@mail.gmail.com> <7b501d5c0906120157w78cb299dj1ab7a5a5189329f1@mail.gmail.com> <7b501d5c0906120215t2f79a7ebi4396f94dc85e11a1@mail.gmail.com> <6DD7CAD2-585C-4CE2-B8C8-1A4E99995011@gmail.com> <7ca3f0160906121529r13efcb38r1ea0392c63af8165@mail.gmail.com> <87tz2hdhw4.fsf@malde.org> Message-ID: On Mon, Jun 15, 2009 at 10:24, Ketil Malde wrote: > Luke Palmer writes: > >> Nice work, I love this one. ?:-) > > Yes, very nice. > > I do find the lambda and > too fat, but I presume that's the way the > Haskell logo looks. Also, I think the right edges of the thick part of > the batteries should be aligned, so that the little "knob" on the + > extends further than the flat end of the -. For purely aestethic reasons, I agree, and that's how I originally did it. But then I realized that this does not make sense. Open any battery compartment and you'll see that the end of the knob on the + side is aligned with the flat end of the ?? side. Moreover, in this way the original width of the logo remains exactly the same. I'm not sure if that really matters, though. Thomas From Malcolm.Wallace at cs.york.ac.uk Mon Jun 15 06:07:25 2009 From: Malcolm.Wallace at cs.york.ac.uk (Malcolm Wallace) Date: Mon Jun 15 06:07:54 2009 Subject: [Haskell-cafe] graphical user interface library for editing graphs? In-Reply-To: <4A326E92.2090203@goto10.org> References: <4A326E92.2090203@goto10.org> Message-ID: <20090615110725.6cf19dcd.Malcolm.Wallace@cs.york.ac.uk> Claude Heiland-Allen wrote: > My question: can you suggest a library that would make implementing > this specification relatively painless? > > OpenGL-based would be preferable, as I would like to scale the graph > under construction automatically to fit the display, and > launchMissiles will require something with fast rendering. There was a Haskell-written graph editor in Dazzle, which the authors kindly open-sourced, to become the rudimentary application Blobs: http://www.cs.york.ac.uk/fp/darcs/Blobs/ The GUI is implemented in wxHaskell, graphs are saved as XML files. Some of the code may have bit-rotted since the days of ghc-6.4. As distributed, the functionality for doing things with the graph after drawing it is (intentionally) rather limited, since many of the potential backends are in fact closed-source. However, the backend is the part that is going to be different for every client of the library anyway. Regards, Malcolm From fernanbolando at mailc.net Mon Jun 15 07:02:33 2009 From: fernanbolando at mailc.net (Fernan Bolando) Date: Mon Jun 15 06:45:54 2009 Subject: [Haskell-cafe] I need a hint in list processing In-Reply-To: References: <1d5d51400906140106n3b391c5au3a1cfda421509e1d@mail.gmail.com> Message-ID: <1d5d51400906150402u17d612f5y4151c6b198e19ff@mail.gmail.com> On Sun, Jun 14, 2009 at 4:51 PM, Miguel Mitrofanov wrote: > ghci> map reverse $ foldM (\answer list -> [x:answer | x <- list, not $ x > `elem` answer]) [] [[2,3], [1,2], [2,3,4], [1,2,3]] > [[2,1,4,3],[3,1,4,2],[3,2,4,1]] > > On 14 Jun 2009, at 12:06, Fernan Bolando wrote: > >> Hi all >> >> If I have a number of list >> example >> list1 = [2,3] >> list2 = [1,2] >> list3 = [2,3,4] >> list4 = [1,2,3] >> >> I want to create a list from the list above with n elements, >> non-repeating and each elements index represents 1 of the elements >> from the corresponding list so for the above input I would get. >> >> a = [3,2,4,1] >> >> ofcourse there may be several set that will satisfy the problem, so a >> list of list that satisfies would be good. >> >> How do I do this in haskell? or is there a code snippet that seems to >> work similarly? >> >> thanks >> fernan >> >> -- >> http://www.fernski.com >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe > > thanks miguel this is the one that I needed. thanks also to everyone fernan -- http://www.fernski.com From mads_lindstroem at yahoo.dk Mon Jun 15 05:50:15 2009 From: mads_lindstroem at yahoo.dk (Mads =?ISO-8859-1?Q?Lindstr=F8m?=) Date: Mon Jun 15 07:00:28 2009 Subject: [Haskell-cafe] Utrecht Attribute Grammar and Emacs Message-ID: <1245059415.4345.3.camel@supermule.opasia.dk> Hi Has anybody implemented an Emacs mode for the Utrecht Attribute Grammar System (UUAG), and is willing to share it ? Greetings, Mads Lindstr?m -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/c94405fb/attachment.bin From si at fh-wedel.de Mon Jun 15 08:36:44 2009 From: si at fh-wedel.de (Uwe Schmidt) Date: Mon Jun 15 08:16:19 2009 Subject: [Haskell-cafe] Documentation on hackage Message-ID: <200906151436.44909.si@fh-wedel.de> Dear Haskellers, who needs this kind of documentation? http://hackage.haskell.org/packages/archive/tfp/0.2/doc/html/Types-Data-Num-Decimal-Literals.html isn't this a kind of spam? Cheers, Uwe From noteed at gmail.com Mon Jun 15 08:35:31 2009 From: noteed at gmail.com (minh thu) Date: Mon Jun 15 08:19:12 2009 Subject: [Haskell-cafe] Documentation on hackage In-Reply-To: <200906151436.44909.si@fh-wedel.de> References: <200906151436.44909.si@fh-wedel.de> Message-ID: <40a414c20906150535i431f365dse5ff220e91cd3c15@mail.gmail.com> 2009/6/15 Uwe Schmidt : > Dear Haskellers, > > who needs this kind of documentation? > > http://hackage.haskell.org/packages/archive/tfp/0.2/doc/html/Types-Data-Num-Decimal-Literals.html > > isn't this a kind of spam? Hi, This is Template Haskell generated code... Cheers, Thu From deniz.a.m.dogan at gmail.com Mon Jun 15 08:53:48 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Mon Jun 15 08:37:09 2009 Subject: [Haskell-cafe] Documentation on hackage In-Reply-To: <40a414c20906150535i431f365dse5ff220e91cd3c15@mail.gmail.com> References: <200906151436.44909.si@fh-wedel.de> <40a414c20906150535i431f365dse5ff220e91cd3c15@mail.gmail.com> Message-ID: <7b501d5c0906150553g3a043cbfh829e4c83aaa5df81@mail.gmail.com> 2009/6/15 minh thu : > 2009/6/15 Uwe Schmidt : >> Dear Haskellers, >> >> who needs this kind of documentation? >> >> http://hackage.haskell.org/packages/archive/tfp/0.2/doc/html/Types-Data-Num-Decimal-Literals.html >> >> isn't this a kind of spam? > > Hi, > > This is Template Haskell generated code... > > Cheers, > Thu Not only can this webpage potentially crash the visitor's browser, I also don't think anyone anywhere would find that piece of documentation useful. -- Deniz Dogan From miguelimo38 at yandex.ru Mon Jun 15 08:56:14 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Mon Jun 15 08:40:25 2009 Subject: [Haskell-cafe] Documentation on hackage In-Reply-To: <7b501d5c0906150553g3a043cbfh829e4c83aaa5df81@mail.gmail.com> References: <200906151436.44909.si@fh-wedel.de> <40a414c20906150535i431f365dse5ff220e91cd3c15@mail.gmail.com> <7b501d5c0906150553g3a043cbfh829e4c83aaa5df81@mail.gmail.com> Message-ID: <4A3644EE.2080708@yandex.ru> But some of us would definitely find it amusing. Deniz Dogan wrote on 15.06.2009 16:53: > 2009/6/15 minh thu : >> 2009/6/15 Uwe Schmidt : >>> Dear Haskellers, >>> >>> who needs this kind of documentation? >>> >>> http://hackage.haskell.org/packages/archive/tfp/0.2/doc/html/Types-Data-Num-Decimal-Literals.html >>> >>> isn't this a kind of spam? >> Hi, >> >> This is Template Haskell generated code... >> >> Cheers, >> Thu > > Not only can this webpage potentially crash the visitor's browser, I > also don't think anyone anywhere would find that piece of > documentation useful. > From lennart at augustsson.net Mon Jun 15 09:12:17 2009 From: lennart at augustsson.net (Lennart Augustsson) Date: Mon Jun 15 08:55:38 2009 Subject: [Haskell-cafe] Performance of functional priority queues In-Reply-To: <3d96ac180906150240m3ee9f02ey7263a4b18a2debb3@mail.gmail.com> References: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> <3d96ac180906150240m3ee9f02ey7263a4b18a2debb3@mail.gmail.com> Message-ID: A priority queue can't have all operations being O(1), because then you would be able to sort in O(n) time. So O(log n) deleteMin and O(1) for the rest is as good as it gets. On Mon, Jun 15, 2009 at 10:40 AM, Sebastian Sylvan wrote: > > > On Mon, Jun 15, 2009 at 4:18 AM, Richard O'Keefe wrote: >> >> There's a current thread in the Erlang mailing list about >> priority queues. ?I'm aware of, for example, the Brodal/Okasaki >> paper and the David King paper. I'm also aware of James Cook's >> priority queue package in Hackage, have my own copy of Okasaki's >> book, and have just spent an hour searching the web. >> >> One of the correspondents in that thread claims that it is >> provably impossible to have an efficient priority queue implementation > > > A priority queue based on skewed binomial heaps is asymptotically optimal > (O(1) for everything except deleteMin which is O(log n)), so if that's what > he means by "efficient" then he's most definitely wrong. If he's talking > about "small constant factors" then it's harder to understand what he's > referring to more precisely, and therefore what he means by "provably". > > -- > Sebastian Sylvan > +44(0)7857-300802 > UIN: 44640862 > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From briqueabraque at yahoo.com Mon Jun 15 09:29:10 2009 From: briqueabraque at yahoo.com (=?ISO-8859-1?Q?Maur=ED=ADcio?=) Date: Mon Jun 15 09:12:44 2009 Subject: [Haskell-cafe] Re: Documentation on hackage In-Reply-To: <200906151436.44909.si@fh-wedel.de> References: <200906151436.44909.si@fh-wedel.de> Message-ID: > who needs this kind of documentation? > > http://hackage.haskell.org/packages/archive/tfp/0.2/doc/html/Types-Data-Num-Decimal-Literals.html The code below is shown under 'Source' links in that documentation. I don't understand it, but it seems everything is generated automatically. What should the author do to avoid those comments? Maur?cio -- module Types.Data.Num.Decimal.Literals where import Types.Data.Num.Decimal.Literals.TH import Types.Data.Num.Decimal.Digits import Types.Data.Num.Ops $( decLiteralsD "D" "d" (-10000) (10000) ) -- From sebastian.sylvan at gmail.com Mon Jun 15 09:43:00 2009 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Mon Jun 15 09:26:21 2009 Subject: [Haskell-cafe] Performance of functional priority queues In-Reply-To: References: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> <3d96ac180906150240m3ee9f02ey7263a4b18a2debb3@mail.gmail.com> Message-ID: <3d96ac180906150643k517979e6qdceb3200f290de52@mail.gmail.com> Is that not what I said? On Mon, Jun 15, 2009 at 2:12 PM, Lennart Augustsson wrote: > A priority queue can't have all operations being O(1), because then > you would be able to sort in O(n) time. So O(log n) deleteMin and > O(1) for the rest is as good as it gets. > > On Mon, Jun 15, 2009 at 10:40 AM, Sebastian > Sylvan wrote: > > > > > > On Mon, Jun 15, 2009 at 4:18 AM, Richard O'Keefe > wrote: > >> > >> There's a current thread in the Erlang mailing list about > >> priority queues. I'm aware of, for example, the Brodal/Okasaki > >> paper and the David King paper. I'm also aware of James Cook's > >> priority queue package in Hackage, have my own copy of Okasaki's > >> book, and have just spent an hour searching the web. > >> > >> One of the correspondents in that thread claims that it is > >> provably impossible to have an efficient priority queue implementation > > > > > > A priority queue based on skewed binomial heaps is asymptotically optimal > > (O(1) for everything except deleteMin which is O(log n)), so if that's > what > > he means by "efficient" then he's most definitely wrong. If he's talking > > about "small constant factors" then it's harder to understand what he's > > referring to more precisely, and therefore what he means by "provably". > > > > -- > > Sebastian Sylvan > > +44(0)7857-300802 > > UIN: 44640862 > > > > _______________________________________________ > > Haskell-Cafe mailing list > > Haskell-Cafe@haskell.org > > http://www.haskell.org/mailman/listinfo/haskell-cafe > > > > > -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/4e61d3e2/attachment.html From dons at galois.com Mon Jun 15 09:49:08 2009 From: dons at galois.com (Don Stewart) Date: Mon Jun 15 09:34:28 2009 Subject: [Haskell-cafe] Documentation on hackage In-Reply-To: <200906151436.44909.si@fh-wedel.de> References: <200906151436.44909.si@fh-wedel.de> Message-ID: <20090615134908.GA31715@whirlpool.galois.com> si: > Dear Haskellers, > > who needs this kind of documentation? > > http://hackage.haskell.org/packages/archive/tfp/0.2/doc/html/Types-Data-Num-Decimal-Literals.html > > isn't this a kind of spam? > Seems like a good case for the haddock -hide option. -- Don From trin.cz at gmail.com Mon Jun 15 11:04:20 2009 From: trin.cz at gmail.com (Trin Trin) Date: Mon Jun 15 10:47:42 2009 Subject: [Haskell-cafe] Backpropagation implementation for a neural net library In-Reply-To: References: Message-ID: <6baa99930906150804t35666826rba7e35a7b49815a3@mail.gmail.com> Hi Alp, - even with correctly programmed back-propagation, it is usually hard to make the net converge. - usually you initialize neuron weights with somewhat random values, when working with back-propagation. - do some debug prints of the net error while training to see how it is going - xor function cannot be trained with a single layer neural net !!! Cheers, Martin PS: I did not check the back-propagation algorithm itself. On Mon, Jun 15, 2009 at 9:58 AM, Alp Mestan wrote: > Dear List, > > I'm working with a friend of mine on a Neural Net library in Haskell. > > There are 3 files : neuron.hs, layer.hs and net.hs. > neuron.hs defines the Neuron data type and many utility functions, all of > which have been tested and work well. > layer.hs defines layer-level functions (computing the output of a whole > layer of neurons, etc). Tested and working. > net.hs defines net-level functions (computing the output of a whole neural > net) and the famous -- but annoying -- back-propagation algorithm. > > You can find them there : http://mestan.fr/haskell/nn/html/ > > The problem is that here when I ask for final_net or test_output (anything > after the train call, in net.hs), it seems to loop and loop around, as if it > never gets the error under 0.1. > > So I was just wondering if there was one or more Neural Nets and Haskell > wizard in there to check the back-propagation implementation, given in > net.hs, that seems to be wrong. > > Thanks a lot ! > > -- > Alp Mestan > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/3bce038a/attachment.html From dons at galois.com Mon Jun 15 11:14:24 2009 From: dons at galois.com (Don Stewart) Date: Mon Jun 15 10:59:34 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> Message-ID: <20090615151424.GG31863@whirlpool.galois.com> keithshep: > Is there any reason that sum isn't strict? I can't think of any case > where that is a good thing. > > Prelude> sum [0 .. 1000000] > *** Exception: stack overflow > It is strict when subject to strictness analysis (try compiling it). -- Don From haskell at list.mightyreason.com Mon Jun 15 11:24:44 2009 From: haskell at list.mightyreason.com (Chris Kuklewicz) Date: Mon Jun 15 11:08:20 2009 Subject: [Haskell-cafe] ANN: Haskell protocol-buffers version 1.5.0 Message-ID: <4A3667BC.2090801@list.mightyreason.com> Hello all, I have just uploaded version 1.5.0 of the Haskell version to hackage. The links for the three pieces are: http://hackage.haskell.org/package/protocol-buffers http://hackage.haskell.org/package/protocol-buffers-descriptor http://hackage.haskell.org/package/hprotoc This catches up to Google's version 2.1.0, as described below: * Support for "repeated" fields for primitive type (good arrays!). Note that using on an invalid field type will generate an error. * NO support yet for the *_FIELD_NUMBER style constants * It is now an error to define a default value for a repeated field. * Fields can now be marked deprecated (does nothing) * The type name resolver will no longer resolve type names to fields. Note that this applies to type of normal and extension fields. A lexer bug was founds and fixed by George van den Driessche, when a numeric literal in a proto file was followed immediately by a newline character. Cheers, Chris From alp at mestan.fr Mon Jun 15 11:40:59 2009 From: alp at mestan.fr (Alp Mestan) Date: Mon Jun 15 11:24:21 2009 Subject: [Haskell-cafe] Backpropagation implementation for a neural net library In-Reply-To: <6baa99930906150800k56c765c9q200a69016d45a5a@mail.gmail.com> References: <6baa99930906150800k56c765c9q200a69016d45a5a@mail.gmail.com> Message-ID: On Mon, Jun 15, 2009 at 5:00 PM, Trin Trin wrote: > Hi Alp, > - even with correctly programmed back-propagation, it is usually hard to > make the net converge. > Yeah, I know, that's why we're training it until the quadratic error goes under 0.1. > - usually you initialize neuron weights with somewhat random values, when > working with back-propagation. > Yeah, that'll be done too, once the algorithm will be ready. I'll provide fancy and easy functions to create a neural net just giving the numbers of layers and their sizes. > - do some debug prints of the net error while training to see how it is > going > Good idea, yeah. > - xor function cannot be trained with a single layer neural net !!! > That's why there are 2 layers there, one hidden and the output one. I consider the "inputs" as ... inputs, not as a first layer of the NN. Thanls for your time. If you have any clues when reading the code, don't hesitate of course. -- Alp Mestan http://blog.mestan.fr/ http://alp.developpez.com/ -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/0556d67e/attachment.html From nrolle at web.de Mon Jun 15 12:46:00 2009 From: nrolle at web.de (Nico Rolle) Date: Mon Jun 15 12:29:23 2009 Subject: [Haskell-cafe] force evaluation beginners question Message-ID: <45fccde20906150946o1b683d85k6d32befbd9cf9323@mail.gmail.com> Hi there I'm trying to compile a code snipped that i've go from a tutorial which uses the function "force". But when I'm trying to compile it ghc reports an error that it couldn't find the defenition of force. my ghc verion is 6.10.3 Did they moved force out of Prelude in one of the latest updates? regards From chaddai.fouche at gmail.com Mon Jun 15 13:11:12 2009 From: chaddai.fouche at gmail.com (=?UTF-8?B?Q2hhZGRhw68gRm91Y2jDqQ==?=) Date: Mon Jun 15 12:54:33 2009 Subject: [Haskell-cafe] force evaluation beginners question In-Reply-To: <45fccde20906150946o1b683d85k6d32befbd9cf9323@mail.gmail.com> References: <45fccde20906150946o1b683d85k6d32befbd9cf9323@mail.gmail.com> Message-ID: On Mon, Jun 15, 2009 at 6:46 PM, Nico Rolle wrote: > Hi there > > I'm trying to compile a code snipped that i've go from a tutorial > which uses the function "force". > But when I'm trying to compile it ghc reports an error that it > couldn't find the defenition of force. > my ghc verion is 6.10.3 > Did they moved force out of Prelude in one of the latest updates? > As far as I know there never was a "force" function in the Prelude of Haskell98, this is probably a function specific to your tutorial, we could help more if we had the code snippet or at least the tutorial name. By the way, while it's absolutely not inappropriate to post this question here, there is a haskell-beginner mailing list more suited to this kind of thing (you could also get very fast and friendly help from the #haskell channel on irc.freenode.net). -- Jeda? From claus.reinke at talk21.com Mon Jun 15 13:39:00 2009 From: claus.reinke at talk21.com (Claus Reinke) Date: Mon Jun 15 13:22:28 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? References: Message-ID: > I was recently trying to figure out if there was a way, at runtime, to do > better strictness analysis for polymorphic HOFs, for which the strictness of > some arguments might depend on the strictness of the strictness of function > types that are passed as arguments [1]. As an example, consider foldl. The > 'seed' parameter of foldl can be made strict as long as the binary function > used for the fold is strict in its arguments. Unfortunately, because > strictness analysis is done statically, Haskell can't assume anything about > the strictness of the binary function - assuming we only compile one > instance of foldl, it must be the most conservative version possible, and > that means making the seed parameter lazy. :-( As has been pointed out, strictness analysis is not decidable. That doesn't mean it is undecidable - running the code and seeing what it does gives a naive semi-decision procedure. So strictness analysis can be made more precise by using more and more runtime information; unfortunately it also becomes less and less useful as a static analysis in the process (in practice, not just termination is important, but also efficiency of the analyses, so an analysis would tend to become unusable before it became possibly non- terminating - there are trade-offs between precision and efficiency). For typical higher-order functions, there's a simple workaround, already employed in the libraries, namely to split the definition into a simple front that may be inlined, and a recursive back where the parameter function is no longer a parameter. Then, after inlining the front at the call site, the back can be compiled and analysed with knowledge of the parameter function. See the comment above foldl: http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/GHC-List.html#foldl Claus From claus.reinke at talk21.com Mon Jun 15 13:49:59 2009 From: claus.reinke at talk21.com (Claus Reinke) Date: Mon Jun 15 13:33:22 2009 Subject: [Haskell-cafe] Re: Documentation on hackage References: <200906151436.44909.si@fh-wedel.de> Message-ID: <7ADC519ED2F64840969E682E1C40D43F@cr3lt> >> who needs this kind of documentation? >> >> http://hackage.haskell.org/packages/archive/tfp/0.2/doc/html/Types-Data-Num-Decimal-Literals.html > > The code below is shown under 'Source' links > in that documentation. I don't understand it, > but it seems everything is generated automatically. > What should the author do to avoid those comments? Older versions of haddock used to define a CPP constant that could be used to tweak the code for haddock. Since newer versions nominally support every feature that GHC supports, that CPP support was dropped. (a) it would be nice if haddock still identified itself via CPP, just like GHC does. Then users would at least have the option to work around current limitations / bugs in haddock, as well as present tweaked presentations of their interfaces. (b) it seems sensible for haddock to provide two options for handling template Haskell code: - document the TH code - document the code generated by TH In this case, the first option would seem more suited. Claus > module Types.Data.Num.Decimal.Literals where > > import Types.Data.Num.Decimal.Literals.TH > > import Types.Data.Num.Decimal.Digits > import Types.Data.Num.Ops > > $( decLiteralsD "D" "d" (-10000) (10000) ) > > -- > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From gwern0 at gmail.com Mon Jun 15 13:52:16 2009 From: gwern0 at gmail.com (Gwern Branwen) Date: Mon Jun 15 13:35:40 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: <1245086323.3817.2.camel@glastonbury> References: <1244822326.28941.29.camel@flippa-eee> <4A35B78C.3040809@semantic.org> <1245086323.3817.2.camel@glastonbury> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On Mon, Jun 15, 2009 at 1:18 PM, Ashley Yakeley wrote: > For requesting accounts: who would receive the email, and which person > would create the account? > Why not just list everyone's email and let the requester pick who to send the request to? - -- gwern -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEAREKAAYFAko2ik8ACgkQvpDo5Pfl1oK4fwCeJvNQpc0ubJl0AmfDebmudxUq UrEAn3rwVLmLRl1RIcJLpZET6SjrssYD =Mhng -----END PGP SIGNATURE----- From nrolle at web.de Mon Jun 15 13:59:28 2009 From: nrolle at web.de (Nico Rolle) Date: Mon Jun 15 13:42:49 2009 Subject: [Haskell-cafe] force evaluation beginners question In-Reply-To: References: <45fccde20906150946o1b683d85k6d32befbd9cf9323@mail.gmail.com> Message-ID: <45fccde20906151059w16c0238eqb1c4a2e41077beaa@mail.gmail.com> big sry. this function was defined by the tutorial guys 2009/6/15 Chadda? Fouch? : > On Mon, Jun 15, 2009 at 6:46 PM, Nico Rolle wrote: >> Hi there >> >> I'm trying to compile a code snipped that i've go from a tutorial >> which uses the function "force". >> But when I'm trying to compile it ghc reports an error that it >> couldn't find the defenition of force. >> my ghc verion is 6.10.3 >> Did they moved force out of Prelude in one of the latest updates? >> > > As far as I know there never was a "force" function in the Prelude of > Haskell98, this is probably a function specific to your tutorial, we > could help more if we had the code snippet or at least the tutorial > name. > > By the way, while it's absolutely not inappropriate to post this > question here, there is a haskell-beginner mailing list more suited to > this kind of thing (you could also get very fast and friendly help > from the #haskell channel on irc.freenode.net). > > -- > Jeda? > From flippa at flippac.org Mon Jun 15 14:08:35 2009 From: flippa at flippac.org (Philippa Cowderoy) Date: Mon Jun 15 13:52:04 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: References: <1244822326.28941.29.camel@flippa-eee> <4A35B78C.3040809@semantic.org> <1245086323.3817.2.camel@glastonbury> Message-ID: <1245089315.5131.5.camel@flippa-eee> On Mon, 2009-06-15 at 13:52 -0400, Gwern Branwen wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA512 > > On Mon, Jun 15, 2009 at 1:18 PM, Ashley Yakeley wrote: > > For requesting accounts: who would receive the email, and which person > > would create the account? > > > > Why not just list everyone's email and let the requester pick who to > send the request to? > A mailing list, possibly attached to a ticketing/queue system, seems a good idea? If it's just a list, admins should ack when they've added someone to avoid duplicated effort. -- Philippa Cowderoy From lennart at augustsson.net Mon Jun 15 14:11:03 2009 From: lennart at augustsson.net (Lennart Augustsson) Date: Mon Jun 15 13:54:25 2009 Subject: [Haskell-cafe] Performance of functional priority queues In-Reply-To: <3d96ac180906150643k517979e6qdceb3200f290de52@mail.gmail.com> References: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> <3d96ac180906150240m3ee9f02ey7263a4b18a2debb3@mail.gmail.com> <3d96ac180906150643k517979e6qdceb3200f290de52@mail.gmail.com> Message-ID: I wasn't contradicting you, just clarifying that this is indeed the optimal asymtotic complexity. On Mon, Jun 15, 2009 at 3:43 PM, Sebastian Sylvan wrote: > Is that not what I said? > > On Mon, Jun 15, 2009 at 2:12 PM, Lennart Augustsson > wrote: >> >> A priority queue can't have all operations being O(1), because then >> you would be able to sort in O(n) time. ?So O(log n) deleteMin and >> O(1) for the rest is as good as it gets. >> >> On Mon, Jun 15, 2009 at 10:40 AM, Sebastian >> Sylvan wrote: >> > >> > >> > On Mon, Jun 15, 2009 at 4:18 AM, Richard O'Keefe >> > wrote: >> >> >> >> There's a current thread in the Erlang mailing list about >> >> priority queues. ?I'm aware of, for example, the Brodal/Okasaki >> >> paper and the David King paper. I'm also aware of James Cook's >> >> priority queue package in Hackage, have my own copy of Okasaki's >> >> book, and have just spent an hour searching the web. >> >> >> >> One of the correspondents in that thread claims that it is >> >> provably impossible to have an efficient priority queue implementation >> > >> > >> > A priority queue based on skewed binomial heaps is asymptotically >> > optimal >> > (O(1) for everything except deleteMin which is O(log n)), so if that's >> > what >> > he means by "efficient" then he's most definitely wrong. If he's talking >> > about "small constant factors" then it's harder to understand what he's >> > referring to more precisely, and therefore what he means by "provably". >> > >> > -- >> > Sebastian Sylvan >> > +44(0)7857-300802 >> > UIN: 44640862 >> > >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > Haskell-Cafe@haskell.org >> > http://www.haskell.org/mailman/listinfo/haskell-cafe >> > >> > > > > > -- > Sebastian Sylvan > +44(0)7857-300802 > UIN: 44640862 > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From magnus at therning.org Mon Jun 15 14:44:07 2009 From: magnus at therning.org (Magnus Therning) Date: Mon Jun 15 14:27:33 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: <1245089315.5131.5.camel@flippa-eee> References: <1244822326.28941.29.camel@flippa-eee> <4A35B78C.3040809@semantic.org> <1245086323.3817.2.camel@glastonbury> <1245089315.5131.5.camel@flippa-eee> Message-ID: <4A369677.2010500@therning.org> Philippa Cowderoy wrote: > On Mon, 2009-06-15 at 13:52 -0400, Gwern Branwen wrote: >> -----BEGIN PGP SIGNED MESSAGE----- >> Hash: SHA512 >> >> On Mon, Jun 15, 2009 at 1:18 PM, Ashley Yakeley wrote: >>> For requesting accounts: who would receive the email, and which person >>> would create the account? >>> >> Why not just list everyone's email and let the requester pick who to >> send the request to? >> > > A mailing list, possibly attached to a ticketing/queue system, seems a > good idea? If it's just a list, admins should ack when they've added > someone to avoid duplicated effort. That seems like a good, simple solution! /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 197 bytes Desc: OpenPGP digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/731f66be/signature.bin From paul.chiusano at gmail.com Mon Jun 15 15:22:01 2009 From: paul.chiusano at gmail.com (Paul Chiusano) Date: Mon Jun 15 15:05:22 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? In-Reply-To: References: Message-ID: Thanks for replies everyone. :) I had not heard of Rice's theorem but it's not too surprising. A couple thoughts I had: 1. In general determining whether a function is strict is undecideable. But a conservative approximation can certainly be guaranteed to terminate. And what is stopping us from having our conservative analysis continue at runtime, as terms are evaluated by the running program? I think I could formulate some notion of having the running program incorporate all available information from terms that have already been evaluated into its analysis. This could be considered the best possible analysis that doesn't affect the termination properties of the program. (Since it does not affect evaluation order of the program or what terms are evaluated.) Of course, like Claus says there are tradeoffs here since a more accurate analysis might not be efficient enough timewise to be useful. But like I said, we already have a "budget" for doing some analysis at runtime since unnecessary memory allocation of thunks also incurs a runtime cost. 2. Having to rewrite higher-order functions so they can be inlined and specialized isn't really a general solution, IMO. It's too fragile, can't be counted on to apply in 100% of all relevant cases, and places additional conceptual burden on the programmer. You have to explicitly unpack the concept and reason about it in each case. I'd rather be able to write the most natural, idiomatic code, and have the compiler/runtime be a bit smarter! Of course, if you are just looking to eek out performance from your available tools, ad hoc solutions like this are fine. But I am asking if we could do better! So, right now it sounds like I should maybe explore this problem a bit more to see what I find out, but tread carefully... Best, Paul On Mon, Jun 15, 2009 at 1:39 PM, Claus Reinke wrote: > I was recently trying to figure out if there was a way, at runtime, to do >> better strictness analysis for polymorphic HOFs, for which the strictness >> of >> some arguments might depend on the strictness of the strictness of >> function >> types that are passed as arguments [1]. As an example, consider foldl. The >> 'seed' parameter of foldl can be made strict as long as the binary >> function >> used for the fold is strict in its arguments. Unfortunately, because >> strictness analysis is done statically, Haskell can't assume anything >> about >> the strictness of the binary function - assuming we only compile one >> instance of foldl, it must be the most conservative version possible, and >> that means making the seed parameter lazy. :-( >> > > As has been pointed out, strictness analysis is not decidable. That doesn't > mean it is undecidable - running the code and seeing what it does gives a > naive semi-decision procedure. So strictness analysis can be made more > precise by using more and more runtime information; unfortunately it also > becomes less and less useful as a static analysis in the process (in > practice, > not just termination is important, but also efficiency of the analyses, so > an > analysis would tend to become unusable before it became possibly non- > terminating - there are trade-offs between precision and efficiency). > > For typical higher-order functions, there's a simple workaround, already > employed in the libraries, namely to split the definition into a simple > front > that may be inlined, and a recursive back where the parameter function is > no longer a parameter. Then, after inlining the front at the call site, the > back can be compiled and analysed with knowledge of the parameter > function. See the comment above foldl: > > > http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/GHC-List.html#foldl > > Claus > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/08bbf105/attachment.html From ashley at semantic.org Mon Jun 15 15:38:02 2009 From: ashley at semantic.org (Ashley Yakeley) Date: Mon Jun 15 15:21:24 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: <4A369677.2010500@therning.org> References: <1244822326.28941.29.camel@flippa-eee> <4A35B78C.3040809@semantic.org> <1245086323.3817.2.camel@glastonbury> <1245089315.5131.5.camel@flippa-eee> <4A369677.2010500@therning.org> Message-ID: <4A36A31A.10504@semantic.org> Magnus Therning wrote: > Philippa Cowderoy wrote: >> On Mon, 2009-06-15 at 13:52 -0400, Gwern Branwen wrote: >>> -----BEGIN PGP SIGNED MESSAGE----- >>> Hash: SHA512 >>> >>> On Mon, Jun 15, 2009 at 1:18 PM, Ashley Yakeley wrote: >>>> For requesting accounts: who would receive the email, and which person >>>> would create the account? >>>> >>> Why not just list everyone's email and let the requester pick who to >>> send the request to? >>> >> >> A mailing list, possibly attached to a ticketing/queue system, seems a >> good idea? If it's just a list, admins should ack when they've added >> someone to avoid duplicated effort. > > That seems like a good, simple solution! OK, so who wants to create accounts? What are your haskell.org usernames? -- Ashley From magnus at therning.org Mon Jun 15 15:47:48 2009 From: magnus at therning.org (Magnus Therning) Date: Mon Jun 15 15:31:11 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: <4A36A31A.10504@semantic.org> References: <1244822326.28941.29.camel@flippa-eee> <4A35B78C.3040809@semantic.org> <1245086323.3817.2.camel@glastonbury> <1245089315.5131.5.camel@flippa-eee> <4A369677.2010500@therning.org> <4A36A31A.10504@semantic.org> Message-ID: <4A36A564.4080805@therning.org> Ashley Yakeley wrote: > Magnus Therning wrote: >> Philippa Cowderoy wrote: >>> On Mon, 2009-06-15 at 13:52 -0400, Gwern Branwen wrote: >>>> -----BEGIN PGP SIGNED MESSAGE----- >>>> Hash: SHA512 >>>> >>>> On Mon, Jun 15, 2009 at 1:18 PM, Ashley Yakeley wrote: >>>>> For requesting accounts: who would receive the email, and which person >>>>> would create the account? >>>>> >>>> Why not just list everyone's email and let the requester pick who to >>>> send the request to? >>>> >>> >>> A mailing list, possibly attached to a ticketing/queue system, seems a >>> good idea? If it's just a list, admins should ack when they've added >>> someone to avoid duplicated effort. >> >> That seems like a good, simple solution! > > OK, so who wants to create accounts? What are your haskell.org usernames? Wiki & hackage username: MagnusTherning /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 197 bytes Desc: OpenPGP digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/90778c2a/signature.bin From robgreayer at gmail.com Mon Jun 15 16:38:33 2009 From: robgreayer at gmail.com (Robert Greayer) Date: Mon Jun 15 16:21:54 2009 Subject: Fwd: [Haskell-cafe] Logo In-Reply-To: <4ec472cb0906151239r7f8b42bfl348fa8d3e8ed3f03@mail.gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <4A35EC8D.7030103@semantic.org> <4ec472cb0906151239r7f8b42bfl348fa8d3e8ed3f03@mail.gmail.com> Message-ID: <4ec472cb0906151338t45e4ed05y46e4be7cd4bfd455@mail.gmail.com> Meant this to go to the list... ---------- Forwarded message ---------- From: Robert Greayer To: Ashley Yakeley For anyone concerned the Hackage icon (http://hackage.haskell.org/favicon.ico) is still the old blue lambda, not the sparkling new icon (http://haskell.org/favicon.ico). On Mon, Jun 15, 2009 at 2:39 AM, Ashley Yakeley wrote: > Thomas Davie wrote: >> >> We had a lot of "fun" deciding Haskell's new logo, and while I don't agree >> with the final result, it would be nice if we could now start consistently >> using it. ?With that in mind, I realised that the Haskell Platform's logo is >> totally different, and did a quick mock up of a version reflecting the >> current Haskell logo. ?It needs someone with the original vector graphics to >> have a play and improve it a little bit, but hopefully you'll se a concept >> you like. > > I rather like the fact that the Haskell Platform logo is distinct from the > Haskell logo. I think it helps prevent confusion (even though the Platform > logo is based on one of the Haskell logo competition entrants). > > http://haskell.org/haskellwiki/Haskell_Platform > > By the way, when I came to replace the Haskell logo on the wiki site, since > the colours had not and still have not been officially decided on, I just > picked the same colours as the Haskell Platform logo. So for the time being, > there is a visual link between the two logos. > > -- > Ashley Yakeley > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From ashley at semantic.org Mon Jun 15 17:03:10 2009 From: ashley at semantic.org (Ashley Yakeley) Date: Mon Jun 15 16:46:32 2009 Subject: [Haskell-cafe] Re: Fwd: Logo In-Reply-To: <4ec472cb0906151338t45e4ed05y46e4be7cd4bfd455@mail.gmail.com> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <4A35EC8D.7030103@semantic.org> <4ec472cb0906151239r7f8b42bfl348fa8d3e8ed3f03@mail.gmail.com> <4ec472cb0906151338t45e4ed05y46e4be7cd4bfd455@mail.gmail.com> Message-ID: <4A36B70E.6020301@semantic.org> Robert Greayer wrote: > For anyone concerned the Hackage icon > (http://hackage.haskell.org/favicon.ico) is still the old blue lambda, > not the sparkling new icon (http://haskell.org/favicon.ico). That's on a different machine. See http://haskell.org/haskellwiki/Haskell.org_domain for which machine does what. -- Ashley Yakeley From ashley at semantic.org Mon Jun 15 17:25:49 2009 From: ashley at semantic.org (Ashley Yakeley) Date: Mon Jun 15 17:09:10 2009 Subject: [Haskell-cafe] Re: Parametrized monads In-Reply-To: <4A3608D1.3010405@yandex.ru> References: <4A3608D1.3010405@yandex.ru> Message-ID: <4A36BC5D.6080605@semantic.org> Miguel Mitrofanov wrote: > Suppose I want to create a specific monad as a combination of monad > transformers - something like "StateT smth1 (ReaderT smth2 Identity)". > As you can see, each transformer is parametrized with a type of kind *. > I want to abstract these parameters, so that instead of "StateT smth..." > I can write something like > > Zip (ConsT StateT (ConsT ReaderT NilT)) (ConsA smth1 (ConsA smth2 NilA)) > Identity > > and it would be a type isomorphic to the first one. I mean, I want > (ConsT StateT (ConsT ReaderT NilT))" to be a separate entity of fixed > kind, so that I can, say, create a class instance for it or something. > > I'd be quite happy if list length appears as a separate parameter, like > > Zip (Succ (Succ Zero)) (ConsT ... > > I would NOT be happy with something like > > Zip (List_2 StateT ReaderT) (Arg_2 smth1 smth2) > > If haskell had polymorphic kinds, I'd be able to do it easily; > unfortunately, it doesn't have them. I think the "type families" extension can do this. -- Ashley Yakeley From miguelimo38 at yandex.ru Mon Jun 15 18:00:25 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Mon Jun 15 17:43:55 2009 Subject: [Haskell-cafe] Re: Parametrized monads In-Reply-To: <4A36BC5D.6080605@semantic.org> References: <4A3608D1.3010405@yandex.ru> <4A36BC5D.6080605@semantic.org> Message-ID: <5FDDBD61-BDB6-4F9C-9B33-776C733810B0@yandex.ru> Probably. I have two objections against using type families. Both are pretty much theoretical. First, it seems to me that using type families would require some other extensions. Multi-parameter type classes are OK, but, in my experience, the road from them to the darkness of undecidable instances is quite short, and I don't feel very safe on these grounds. Maybe it's just me, but I can't help imagining myself adding just one element to the already long list, and the compiler throwing tons of cryptic error messages on my head because the derivation of necessary instances is just too long. It happened before, and I still don't know how to prevent it. Secondly, type families are one thing that I have no idea of how to abstract if needed. I know how to abstract a usual type class - by passing the dictionary explicitly, for example; there are some more sophisticated methods like higher-level monad - but it seems almost impossible to abstract a class that can have an associated data type. I don't see any reason to do this - yet; and for me, "yet" is enough to make me nervous. On 16 Jun 2009, at 01:25, Ashley Yakeley wrote: > Miguel Mitrofanov wrote: >> Suppose I want to create a specific monad as a combination of monad >> transformers - something like "StateT smth1 (ReaderT smth2 >> Identity)". As you can see, each transformer is parametrized with a >> type of kind *. I want to abstract these parameters, so that >> instead of "StateT smth..." I can write something like >> Zip (ConsT StateT (ConsT ReaderT NilT)) (ConsA smth1 (ConsA smth2 >> NilA)) Identity >> and it would be a type isomorphic to the first one. I mean, I want >> (ConsT StateT (ConsT ReaderT NilT))" to be a separate entity of >> fixed kind, so that I can, say, create a class instance for it or >> something. >> I'd be quite happy if list length appears as a separate parameter, >> like >> Zip (Succ (Succ Zero)) (ConsT ... >> I would NOT be happy with something like >> Zip (List_2 StateT ReaderT) (Arg_2 smth1 smth2) >> If haskell had polymorphic kinds, I'd be able to do it easily; >> unfortunately, it doesn't have them. > > I think the "type families" extension can do this. > > -- > Ashley Yakeley From ashley at semantic.org Mon Jun 15 18:16:26 2009 From: ashley at semantic.org (Ashley Yakeley) Date: Mon Jun 15 17:59:47 2009 Subject: [Haskell-cafe] Re: Parametrized monads In-Reply-To: <5FDDBD61-BDB6-4F9C-9B33-776C733810B0@yandex.ru> References: <4A3608D1.3010405@yandex.ru> <4A36BC5D.6080605@semantic.org> <5FDDBD61-BDB6-4F9C-9B33-776C733810B0@yandex.ru> Message-ID: <4A36C83A.3090303@semantic.org> Miguel Mitrofanov wrote: > First, it seems to me that using type families would require some other > extensions. Multi-parameter type classes are OK, but, in my experience, > the road from them to the darkness of undecidable instances is quite > short, and I don't feel very safe on these grounds. Actually, you can use type families without using classes or instances at all. -- Ashley Yakeley From bertram.felgenhauer at googlemail.com Mon Jun 15 19:49:55 2009 From: bertram.felgenhauer at googlemail.com (Bertram Felgenhauer) Date: Mon Jun 15 19:33:21 2009 Subject: [Haskell-cafe] Performance of functional priority queues In-Reply-To: <3d96ac180906150240m3ee9f02ey7263a4b18a2debb3@mail.gmail.com> References: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> <3d96ac180906150240m3ee9f02ey7263a4b18a2debb3@mail.gmail.com> Message-ID: <4a36de26.0702d00a.4ceb.2abb@mx.google.com> Sebastian Sylvan wrote: > On Mon, Jun 15, 2009 at 4:18 AM, Richard O'Keefe wrote: > > There's a current thread in the Erlang mailing list about > > priority queues. I'm aware of, for example, the Brodal/Okasaki > > paper and the David King paper. I'm also aware of James Cook's > > priority queue package in Hackage, have my own copy of Okasaki's > > book, and have just spent an hour searching the web. > > > > One of the correspondents in that thread claims that it is > > provably impossible to have an efficient priority queue implementation > > A priority queue based on skewed binomial heaps is asymptotically optimal > (O(1) for everything except deleteMin which is O(log n)), so if that's what > he means by "efficient" then he's most definitely wrong. What about decreaseKey in a purely functional setting? I suppose it's O(log n), based on the intuition of trees with limited branching factor. Fibonacci heaps can do it in O(1), which makes a difference for Dijkstra's algorithm, for example. regards, Bertram From mle+hs at mega-nerd.com Mon Jun 15 20:21:20 2009 From: mle+hs at mega-nerd.com (Erik de Castro Lopo) Date: Mon Jun 15 20:04:49 2009 Subject: [Haskell-cafe] Running Hoogle as a cgi script. In-Reply-To: <20090614200722.019c5e8c.mle+hs@mega-nerd.com> References: <20090614200722.019c5e8c.mle+hs@mega-nerd.com> Message-ID: <20090616102120.52239076.mle+hs@mega-nerd.com> Erik de Castro Lopo wrote: > I'd like to run my own version of Hoogle: > > http://hackage.haskell.org/package/hoogle > > as a CGI script much like this: > > http://www.haskell.org/hoogle/ > > but there doesn't seem to be any documentation on how to do this. Neil Mitchell (the hoogle author) informed me that the hoogle binary behaves like a CGI when the QUERY_STRING environment variable is set. Another problem with hoogle as a CGI is that it writes a log file to the current working directory which on Unix is probably not world writable. I'm working with Neil to make hoogle a little more Unix friendly :-). Cheers, Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/ From phil at beadling.co.uk Mon Jun 15 20:23:12 2009 From: phil at beadling.co.uk (Phil) Date: Mon Jun 15 20:06:37 2009 Subject: [Haskell-cafe] Catering for similar operations with and without state Message-ID: <89bc5e540906151723g1dadc094ledb3e3ad3123e387@mail.gmail.com> Hi, I'm trying to think around a problem which is causing me some difficulty in Haskell. I'm representing a stateful computation using a State Transform - which works fine. Problem is in order to add flexibility to my program I want to performs the same operation using different techniques - most of which require no state. My program at the moment is a stack of state monads/transforms. I have a random number generator as a state monad (seed=state), feeding a Box Muller (normal) generator implemented as a state transform (state is 'maybe' normal, so it only spits out 1 normal at a time), which in turn feeds another state machine. This all works fine, but I want to add flexibility so that I can chop and change the Box Muller algorithm with any number of other normal generators. Problem is most of them do not need to carry around state at all. This leaves me with a messy solution of implementing lots of state monads that don't actually have a state, if I want to maintain the current paradigm. This strikes me as really messy - so I'm hoping someone can point me in the direction of a more sensible approach? Currently I have my Box Muller implemented as below - this works: class NormalClass myType where generateNormal :: myType Double type BoxMullerStateT = StateT (Maybe Double) type BoxMullerRandomStateStack = BoxMullerStateT MyRngState instance NormalClass BoxMullerRandomStateStack where generateNormal = StateT $ \s -> case s of Just d -> return (d,Nothing) Nothing -> do qrnBaseList <- nextRand let (norm1,norm2) = boxMuller (head qrnBaseList) (head $ tail qrnBaseList) return (norm1,Just norm2) But say I have another instance of my NormalClass that doesn't need to be stateful, that is generateNormal() is a pure function. How can I represent this without breaking my whole stack? I've pretty much backed myself into a corner here as my main() code expects to evalStateT on my NormalClass: main = do let sumOfPayOffs = evalState normalState (1,[3,5]) -- (ranq1Init 981110) where mcState = execStateT (do replicateM_ iterations mc) 0 normalState = evalStateT mcState Nothing If it wasn't for this I was thinking about implementing the IdentityT transformer to provide a more elegant pass-through. I've never tried designing my own Monad from scratch but this crossed my mind as another possibillity - i.e. a Monad that either has a state of maybe double, or has no state at all? I may be talking rubbish here of course :-) I'm pretty daunted by where to even start - but I want to improve this as the quick and dirty solution of implementing a load of state monads with no state just to cater for the above method strikes me as very ugly, and as I can easily see ways of doing this in C or C++, I figure there must be a better approach in Haskell - I'm just thinking in the right way! Any advice or hints would be great, Cheers, Phil. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/8c81c749/attachment.html From keithshep at gmail.com Mon Jun 15 20:49:58 2009 From: keithshep at gmail.com (Keith Sheppard) Date: Mon Jun 15 20:33:19 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <20090615151424.GG31863@whirlpool.galois.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> Message-ID: <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> The answer is sometimes (only if you use an optimize flag): keith@sugarglider:~/temp/> cat sumtest.hs main = putStrLn . show . sum $ [0 .. 1000000] keith@sugarglider:~/temp/> ghc --make sumtest.hs [1 of 1] Compiling Main ( sumtest.hs, sumtest.o ) Linking sumtest ... keith@sugarglider:~/temp/> ./sumtest Stack space overflow: current size 8388608 bytes. Use `+RTS -Ksize' to increase it. keith@sugarglider:~/temp/> rm sumtest.hi sumtest.o sumtest keith@sugarglider:~/temp/> ghc --make -O2 sumtest.hs [1 of 1] Compiling Main ( sumtest.hs, sumtest.o ) Linking sumtest ... keith@sugarglider:~/temp/> ./sumtest 500000500000 keith@sugarglider:~/temp/> ghc --version The Glorious Glasgow Haskell Compilation System, version 6.10.1 But since hackage warns against using these flags when you upload packages I would think that most libraries would not be using a strict version of sum. On Mon, Jun 15, 2009 at 11:14 AM, Don Stewart wrote: > keithshep: >> Is there any reason that sum isn't strict? I can't think of any case >> where that is a good thing. >> >> Prelude> sum [0 .. 1000000] >> *** Exception: stack overflow >> > > It is strict when subject to strictness analysis (try compiling it). > > -- Don > > > -- keithsheppard.name From keithshep at gmail.com Mon Jun 15 21:02:09 2009 From: keithshep at gmail.com (Keith Sheppard) Date: Mon Jun 15 20:45:29 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <20090615151424.GG31863@whirlpool.galois.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> Message-ID: <92e42b740906151802v45e0bd19ga1de16343117412c@mail.gmail.com> I just realized... that was a statement not a question :-) anyway, thanks Keith On Mon, Jun 15, 2009 at 11:14 AM, Don Stewart wrote: > keithshep: >> Is there any reason that sum isn't strict? I can't think of any case >> where that is a good thing. >> >> Prelude> sum [0 .. 1000000] >> *** Exception: stack overflow >> > > It is strict when subject to strictness analysis (try compiling it). > > -- Don > > > -- keithsheppard.name From cetin.sert at gmail.com Mon Jun 15 23:14:01 2009 From: cetin.sert at gmail.com (Cetin Sert) Date: Mon Jun 15 22:57:41 2009 Subject: [Haskell-cafe] ANNOUNCE: clock 0.1 released Message-ID: <1ff5dedc0906152014q13cd7071vf26d3bcba9ceb002@mail.gmail.com> clock is a library published under a BSD3 license that provides bindings to clock_gettime and clock_getres for monotonic, realtime, processtime and threadtime clocks from time.h . It was implemented in response to a haskell-cafe discussion: http://www.mail-archive.com/haskell-cafe@haskell.org/msg51244.html Any suggestions for improvement, bug-fixes, joint-development offers are most welcome *^o^*!! Cetin Sert -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090615/a706156f/attachment.html From dons at galois.com Mon Jun 15 23:18:49 2009 From: dons at galois.com (Don Stewart) Date: Mon Jun 15 23:02:11 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> Message-ID: <20090616031849.GA5253@liouville.galois.com> keithshep: > The answer is sometimes (only if you use an optimize flag): You're turning on the strictness analyser. That's enabled with -O or -O2. But sum should be using a tail recursive foldl'. It's a bug in the H98 report, IMO. -- Don From briand at aracnet.com Mon Jun 15 23:39:42 2009 From: briand at aracnet.com (brian) Date: Mon Jun 15 23:23:03 2009 Subject: [Haskell-cafe] slow code In-Reply-To: References: <9621AF5D-5C87-43A6-B8A2-103109570416@aracnet.com> Message-ID: <00FDD473-F0DB-41F8-8410-C435CDF045C0@aracnet.com> I have included a new and improved version. Just to make the comparison a little more reasonable I re-wrote the program using ML and ran it with SMLNJ eal 0m3.175s user 0m0.935s sys 0m0.319s Here's the compiled haskell (ghc -O2 foo.hs -o foo): real 0m16.855s user 0m9.724s sys 0m0.495s OUCH. I verified to make sure they were both writing valid data files. I'm trying to learn how to fish, so I'm truly interested in finding out _how_ to optimize using profiling and other such tools. Here's the header of the foo.prof file: total time = 9.44 secs (472 ticks @ 20 ms) total alloc = 2,171,923,916 bytes (excludes profiling overheads) 2GB of allocation ??? with a base size of 131k. that seems excessive, which gets me back to the , I don't think I'm interpreting profiling stuff correctly. This line is a little more interesting: COST CENTRE MODULE no. entries %time %alloc %time %alloc main Main 178 1 98.7 99.1 98.7 99.1 So even though getData should be doing all of the allocation, main's using a lot of time and effort. I figured it was the show's that were slowing things up (how do I get profiling to show that detail ?), so I had it output just "\n". Well that finishes in no time at all. And yea, verily, the output of the .prof file. total time = 0.14 secs (7 ticks @ 20 ms) total alloc = 65,562,824 bytes (excludes profiling overheads) So I guess it's the show's, but I can't seem to find more efficient float output. FFI to sprintf ? yuch. Brian foo.hs import Numeric import Complex import IO genData :: Double -> Int -> (Double -> Complex Double) -> ([Double], [Complex Double]) genData tstop n f = let deltat = tstop / (fromIntegral n) t = [ fromIntegral(i) * deltat | i <- [0..n-1]] in (t, map f t) main = do let (t, y) = genData 100.0E-6 (2 ^ 17) (\x -> x :+ 0.0) h <- openFile "/dev/null" WriteMode mapM_ (\(x, y) -> do hPutStr h ((showEFloat (Just 6) x) " ") hPutStr h (showEFloat (Just 6) (realPart y) "\n")) (zip t y) hClose h print "Done" foo.sml let fun genData tstop n f = let val deltat = tstop / (Real.fromInt n) val t = List.tabulate(n, fn i => Real.fromInt(i) * deltat) in (t, map f t) end val (t, y) = genData 100.0E~6 131072 (fn x => (x, 0.0)) val h = TextIO.openOut("data.txt") in List.app (fn (x, (a,b)) => (TextIO.output(h, Real.fmt (StringCvt.SCI(SOME 6)) x); TextIO.output(h, Real.fmt (StringCvt.SCI(SOME 6)) a ^ "\n"))) (ListPair.zip (t, y)); TextIO.closeOut(h); print "Done"; () end On Jun 15, 2009, at 12:15 AM, Thomas ten Cate wrote: > How much output does this generate? Does it matter if you send the > output to /dev/null? This looks as if the bottleneck might well be in > I/O operations, not in the code itself. To find this out, you could > rewrite the code in C and see if that makes a difference? > > Thomas > > On Sun, Jun 14, 2009 at 20:44, brian wrote: >> Haskell Gurus, >> >> I have tried to use profiling to tell me what's going on here, but >> it hasn't >> helped much, probably because I'm not interpreting the results >> correctly. >> >> Empirically I have determined that the show's are pretty slow, so an >> alternative to them would be helpful. I replaced the show's with >> "", and >> compiled with -O2 and not much improvement. >> >> I need to write _a lot_ of code in this style. A few words about >> how best >> to do this would be helpful. Laziness, infinite lists, uvector ?? >> >> Help... >> >> Thanks, >> >> Brian >> >> >> import Complex >> import System.IO >> >> genData :: Double -> Int -> (Double -> Complex Double) -> ([Double], >> [Complex Double]) >> genData tstop n f = >> let deltat = tstop / (fromIntegral n) >> t = [ fromIntegral(i) * deltat | i <- [0..n-1]] >> in >> (t, map f t) >> >> main = >> do let (t, y) = genData 100.0E-6 (2 ^ 15) (\x -> x :+ 0.0) >> h <- openFile "data.txt" WriteMode >> mapM_ (\(x, y) -> >> do hPutStr h (show t) >> hPutStr h " " >> hPutStrLn h (show (realPart y))) >> (zip t y) >> hClose h >> _______________________________________________ >> 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 miguelimo38 at yandex.ru Tue Jun 16 01:18:46 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Tue Jun 16 01:02:15 2009 Subject: [Haskell-cafe] Re: Parametrized monads In-Reply-To: <5FDDBD61-BDB6-4F9C-9B33-776C733810B0@yandex.ru> References: <4A3608D1.3010405@yandex.ru> <4A36BC5D.6080605@semantic.org> <5FDDBD61-BDB6-4F9C-9B33-776C733810B0@yandex.ru> Message-ID: <5166D6B4-03C2-4362-A077-7C5B7458F291@yandex.ru> And the third one I forgot at first: so far, all code I wrote could be easily ported to Hugs. On 16 Jun 2009, at 02:00, Miguel Mitrofanov wrote: > Probably. > > I have two objections against using type families. Both are pretty > much theoretical. > > First, it seems to me that using type families would require some > other extensions. Multi-parameter type classes are OK, but, in my > experience, the road from them to the darkness of undecidable > instances is quite short, and I don't feel very safe on these > grounds. Maybe it's just me, but I can't help imagining myself > adding just one element to the already long list, and the compiler > throwing tons of cryptic error messages on my head because the > derivation of necessary instances is just too long. It happened > before, and I still don't know how to prevent it. > > Secondly, type families are one thing that I have no idea of how to > abstract if needed. I know how to abstract a usual type class - by > passing the dictionary explicitly, for example; there are some more > sophisticated methods like higher-level monad - but it seems almost > impossible to abstract a class that can have an associated data > type. I don't see any reason to do this - yet; and for me, "yet" is > enough to make me nervous. > > On 16 Jun 2009, at 01:25, Ashley Yakeley wrote: > >> Miguel Mitrofanov wrote: >>> Suppose I want to create a specific monad as a combination of >>> monad transformers - something like "StateT smth1 (ReaderT smth2 >>> Identity)". As you can see, each transformer is parametrized with >>> a type of kind *. I want to abstract these parameters, so that >>> instead of "StateT smth..." I can write something like >>> Zip (ConsT StateT (ConsT ReaderT NilT)) (ConsA smth1 (ConsA smth2 >>> NilA)) Identity >>> and it would be a type isomorphic to the first one. I mean, I want >>> (ConsT StateT (ConsT ReaderT NilT))" to be a separate entity of >>> fixed kind, so that I can, say, create a class instance for it or >>> something. >>> I'd be quite happy if list length appears as a separate parameter, >>> like >>> Zip (Succ (Succ Zero)) (ConsT ... >>> I would NOT be happy with something like >>> Zip (List_2 StateT ReaderT) (Arg_2 smth1 smth2) >>> If haskell had polymorphic kinds, I'd be able to do it easily; >>> unfortunately, it doesn't have them. >> >> I think the "type families" extension can do this. >> >> -- >> Ashley Yakeley > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From miguelimo38 at yandex.ru Tue Jun 16 01:19:47 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Tue Jun 16 01:03:08 2009 Subject: [Haskell-cafe] Re: Parametrized monads In-Reply-To: <4A36C83A.3090303@semantic.org> References: <4A3608D1.3010405@yandex.ru> <4A36BC5D.6080605@semantic.org> <5FDDBD61-BDB6-4F9C-9B33-776C733810B0@yandex.ru> <4A36C83A.3090303@semantic.org> Message-ID: What do you mean, without instances? How do you call "data instance" declarations? On 16 Jun 2009, at 02:16, Ashley Yakeley wrote: > Miguel Mitrofanov wrote: >> First, it seems to me that using type families would require some >> other extensions. Multi-parameter type classes are OK, but, in my >> experience, the road from them to the darkness of undecidable >> instances is quite short, and I don't feel very safe on these >> grounds. > > Actually, you can use type families without using classes or > instances at all. > > -- > Ashley Yakeley From jules at jellybean.co.uk Tue Jun 16 06:38:12 2009 From: jules at jellybean.co.uk (Jules Bean) Date: Tue Jun 16 06:21:36 2009 Subject: [Haskell-cafe] Logo In-Reply-To: <4A35EC8D.7030103@semantic.org> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <4A35EC8D.7030103@semantic.org> Message-ID: <4A377614.9030700@jellybean.co.uk> Ashley Yakeley wrote: > I rather like the fact that the Haskell Platform logo is distinct from > the Haskell logo. I think it helps prevent confusion (even though the > Platform logo is based on one of the Haskell logo competition entrants). > > http://haskell.org/haskellwiki/Haskell_Platform Well, I disagree. Even though I do not like the new haskell logo, I prefer consistency. I like the black/gold version proposed. From lemming at henning-thielemann.de Tue Jun 16 07:10:20 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Tue Jun 16 06:54:19 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <4A33BF14.6000406@functor.nl> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <4A33B318.7090203@functor.nl> <7b501d5c0906130717k1b6ff394x3abe866aa84d2fa2@mail.gmail.com> <4A33BF14.6000406@functor.nl> Message-ID: <4A377D9C.7000300@henning-thielemann.de> Jochem Berndsen schrieb: > Deniz Dogan wrote: >> 2009/6/13 Jochem Berndsen : >>> Keith Sheppard wrote: >>>> Is there any reason that sum isn't strict? I can't think of any case >>>> where that is a good thing. >>>> >>>> Prelude> sum [0 .. 1000000] >>>> *** Exception: stack overflow >>> It is useful if the (+) is nonstrict; although I cannot think of any >>> useful mathematical structure where (+) would be nonstrict. >> I remember needing a non-strict sum at least once, but I do not >> remember the exact application. But imagine having a (very) long list >> of numbers and you want to do A if the sum exceeds a small number, >> otherwise B. >> >> if sum [0..100000] > 10 then A else B >> >> However, this idea didn't work, because of strictness. > > You can only do such things if you know that all entries of your list > are nonnegative. That requires a custom solution anyway (not to mention > the fact that to determine whether x > 10 or not, we need to explicitly > compute x). http://hackage.haskell.org/packages/archive/non-negative/0.0.5/doc/html/Numeric-NonNegative-Chunky.html From chris at eidhof.nl Tue Jun 16 07:16:36 2009 From: chris at eidhof.nl (Chris Eidhof) Date: Tue Jun 16 06:59:57 2009 Subject: [Haskell-cafe] Logo In-Reply-To: <4A35EC8D.7030103@semantic.org> References: <7513DBEE-BEF3-46A6-9E5D-ABA4DD79C07F@gmail.com> <4A35EC8D.7030103@semantic.org> Message-ID: <8E92CE60-2F62-4D3B-B481-72E32DA71E2A@eidhof.nl> Hey all, On 15 jun 2009, at 08:39, Ashley Yakeley wrote: > Thomas Davie wrote: >> We had a lot of "fun" deciding Haskell's new logo, and while I >> don't agree with the final result, it would be nice if we could now >> start consistently using it. With that in mind, I realised that >> the Haskell Platform's logo is totally different, and did a quick >> mock up of a version reflecting the current Haskell logo. It needs >> someone with the original vector graphics to have a play and >> improve it a little bit, but hopefully you'll se a concept you like. > > I rather like the fact that the Haskell Platform logo is distinct > from the Haskell logo. I think it helps prevent confusion (even > though the Platform logo is based on one of the Haskell logo > competition entrants). For new users, when they "install Haskell" they will install the Haskell Platform. I don't think we need to have a big distinction between that. Therefore, I think that the Haskell Platform should share the Haskell logo. I think the Haskell platform is an excellent name for internal communication, but to the outside world, it *is* Haskell. This is what you get when you install Haskell. Otherwise it will probably only confuse users. I think a typical new user would do something along the following lines: I want to play around with Haskell. I'll google for "install Haskell" or "download Haskell" (here, the Haskell Platform download page should be the #1 hit). There, the user sees the Haskell logo and doesn't have to know *anything* about the platform effort, cabal, ghc or whatever. Therefore, I think it should have the Haskell logo, not the platform logo. -chris From lemming at henning-thielemann.de Tue Jun 16 07:18:33 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Tue Jun 16 07:01:53 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <20090616031849.GA5253@liouville.galois.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> Message-ID: On Mon, 15 Jun 2009, Don Stewart wrote: > keithshep: >> The answer is sometimes (only if you use an optimize flag): > > You're turning on the strictness analyser. That's enabled with -O or > -O2. > > But sum should be using a tail recursive foldl'. It's a bug in the H98 > report, IMO. I can wrap an accumulator lazily: data Accum a = Accum a Then foldl' using (Accum a) instead of 'a' would be non-strict, again. Thus foldl' is not always strict. I think this 'seq' function is broken and there should have been a Seq class. Then you can choose the required depth of strictness. Btw. for lazy Peano numbers, sum would be better a foldr rather than foldl. From marlowsd at gmail.com Tue Jun 16 07:30:31 2009 From: marlowsd at gmail.com (Simon Marlow) Date: Tue Jun 16 07:13:53 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> Message-ID: <4A378257.9090405@gmail.com> On 14/06/2009 05:56, Judah Jacobson wrote: > On Sat, Jun 13, 2009 at 8:41 PM, Shu-yu Guo wrote: >> Hello all, >> >> It seems like getDirectoryContents applies codepage conversion based >> on the default program locale under Windows. What this means is that >> if my default codepage is some kind of Latin, Asian glyphs get >> returned as '?' in the filename. By '?' I don't mean that the font is >> lacking the glyph and rendering it as '?', but I mean 'show (head >> (getDirectoryContents "C:\\Music"))' returns something that looks like >> like "?? ????". >> >> This is a problem as I can't get the filenames of my music directory, >> some of which are in Japanese and Chinese, some of which have accents. >> If I change the default codepage to Japanese, say, then I get the >> Japanese filenames in Shift-JIS and I lose all the accented letters. >> >> I have filed this as a bug already, but is there a workaround in the >> meantime (I don't know the Win32 API, but didn't see anything that >> looked like it would help under System.Win32 anyways) that lets me >> gets the list of files in a directory that's encoded in some kind of >> Unicode? > > Try taking a look at the code in the following module, which uses FFI > to access the Unicode-aware Win32 APIs: > > http://code.haskell.org/haskeline/System/Console/Haskeline/Directory.hsc Care to submit a patch to put this in System.Directory, or better still put the relevant functionality in System.Win32 and use it in System.Directory? Cheers, Simon From tom.davie at gmail.com Tue Jun 16 07:31:53 2009 From: tom.davie at gmail.com (Thomas Davie) Date: Tue Jun 16 07:15:15 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <20090616031849.GA5253@liouville.galois.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> Message-ID: <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> On 16 Jun 2009, at 05:18, Don Stewart wrote: > keithshep: >> The answer is sometimes (only if you use an optimize flag): > > You're turning on the strictness analyser. That's enabled with -O or > -O2. > > But sum should be using a tail recursive foldl'. It's a bug in the H98 > report, IMO. Not at all, as discussed, there are legitimate uses for a lazy sum, and haskell is a lazy language by default. The only change here needs to be either claus' suggestion of generalizing functions over their application operator, or providing a strict sum'. Bob From bulat.ziganshin at gmail.com Tue Jun 16 07:42:31 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Tue Jun 16 07:26:13 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A378257.9090405@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> Message-ID: <645958025.20090616154231@gmail.com> Hello Simon, Tuesday, June 16, 2009, 3:30:31 PM, you wrote: > Care to submit a patch to put this in System.Directory, or better still > put the relevant functionality in System.Win32 and use it in > System.Directory? Simon, it will somewhat broke openFile. let's see. there are 3 types of filenames - 1) english (latin-1) only 2) including local (ansi code page) chars 3) including any other unicode chars now getDirectoryContents return ACP (ansi code page) names so openFile works for files 1) and 2) with such change getDirectoryContents will return correct unicode names, so openFile will work only with names in first group the right way is to fix ALL string-related calls in System.IO, System.Posix.Internals, System.Environment -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From marlowsd at gmail.com Tue Jun 16 08:34:29 2009 From: marlowsd at gmail.com (Simon Marlow) Date: Tue Jun 16 08:17:49 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <645958025.20090616154231@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> Message-ID: <4A379155.8030500@gmail.com> On 16/06/2009 12:42, Bulat Ziganshin wrote: > Hello Simon, > > Tuesday, June 16, 2009, 3:30:31 PM, you wrote: > >> Care to submit a patch to put this in System.Directory, or better still >> put the relevant functionality in System.Win32 and use it in >> System.Directory? > > Simon, it will somewhat broke openFile. let's see. there are 3 types > of filenames - > > 1) english (latin-1) only > 2) including local (ansi code page) chars > 3) including any other unicode chars > > now getDirectoryContents return ACP (ansi code page) names so openFile > works for files 1) and 2) > > with such change getDirectoryContents will return correct unicode > names, so openFile will work only with names in first group > > the right way is to fix ALL string-related calls in System.IO, > System.Posix.Internals, System.Environment You're right in that we really ought to fix everything. However, I'm happy to just fix some of these things, even if it introduces some inconsistencies in the meantime. We already have much of System.Directory working with Unicode FilePaths, so there are already inconsistencies here. Thanks for reminding me that openFile is also broken. It's easily fixed, so I'll look into that. Cheers, Simon From gale at sefer.org Tue Jun 16 08:46:12 2009 From: gale at sefer.org (Yitzchak Gale) Date: Tue Jun 16 08:29:51 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A379155.8030500@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> Message-ID: <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> Simon Marlow wrote: >>> Care to submit a patch to put this in System.Directory, or better still >>> put the relevant functionality in System.Win32 and use it in >>> System.Directory? Bulat Ziganshin wrote: >> now getDirectoryContents return ACP (ansi code page) names so openFile >> works for files 1) and 2). >> With such change getDirectoryContents will return correct unicode >> names, so openFile will work only with names in first group. >> The right way is to fix ALL string-related calls in System.IO, >> System.Posix.Internals, System.Environment. > You're right in that we really ought to fix everything. ?However, I'm happy > to just fix some of these things, even if it introduces some inconsistencies > in the meantime. ?We already have much of System.Directory working with > Unicode FilePaths, so there are already inconsistencies here. +1 for integrating Unicode file paths. Thanks, Bulat! I think the most important use cases that should not break are: o open/read/write a FilePath from getArgs o open/read/write a FilePath from getDirectoryContents There's not much we can do about non-Latin-1 ACP file paths hard coded in Strings. I hope there aren't too many of those in the wild. Regards, Yitz From bulat.ziganshin at gmail.com Tue Jun 16 08:54:50 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Tue Jun 16 08:39:54 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A379155.8030500@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> Message-ID: <1554927165.20090616165450@gmail.com> Hello Simon, Tuesday, June 16, 2009, 4:34:29 PM, you wrote: > Thanks for reminding me that openFile is also broken. It's easily > fixed, so I'll look into that. i fear that it will leave GHC libs in inconsistent state that can drive users mad. now at least there are some rules of brokeness. when some functions will be unicode-aware and some ansi codepaged, and this may chnage in every version, this "unicode" support will become completely useless. it will be like floating Base situation when it's impossible to write programs against Base since it's each time different also, i think that the best way to fix windows compatibility is to provide smth like this: #if WINDOWS type CWFilePath = LPCTSTR -- filename in C land type CWFileOffset = Int64 -- filesize or filepos in C land withCWFilePath = withTString -- FilePath->CWFilePath conversion peekCWFilePath = peekTString -- CWFilePath->FilePath conversion #else type CWFilePath = CString type CWFileOffset = COff withCWFilePath = withCString peekCWFilePath = peekCString #endif and then systematically rewrite all string-related OS API calls using these definitions how much meaning will be to have openFile and getDirContents unicode-aware, if deleteFile and even getFileStat aren't unicode-aware? i've attached my own internal module that makes this job for my own program - just for reference -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com -------------- next part -------------- A non-text attachment was scrubbed... Name: Win32Files.hs Type: application/octet-stream Size: 10631 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090616/a7b41302/Win32Files.obj From marlowsd at gmail.com Tue Jun 16 09:02:43 2009 From: marlowsd at gmail.com (Simon Marlow) Date: Tue Jun 16 08:46:04 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> Message-ID: <4A3797F3.2040707@gmail.com> On 16/06/2009 13:46, Yitzchak Gale wrote: > Simon Marlow wrote: >>>> Care to submit a patch to put this in System.Directory, or better still >>>> put the relevant functionality in System.Win32 and use it in >>>> System.Directory? > > Bulat Ziganshin wrote: >>> now getDirectoryContents return ACP (ansi code page) names so openFile >>> works for files 1) and 2). >>> With such change getDirectoryContents will return correct unicode >>> names, so openFile will work only with names in first group. >>> The right way is to fix ALL string-related calls in System.IO, >>> System.Posix.Internals, System.Environment. > >> You're right in that we really ought to fix everything. However, I'm happy >> to just fix some of these things, even if it introduces some inconsistencies >> in the meantime. We already have much of System.Directory working with >> Unicode FilePaths, so there are already inconsistencies here. > > +1 for integrating Unicode file paths. Thanks, Bulat! Excuse my ignorance, but... what Unicode file paths? > I think the most important use cases that should not break are: > > o open/read/write a FilePath from getArgs > o open/read/write a FilePath from getDirectoryContents > > There's not much we can do about non-Latin-1 ACP file paths > hard coded in Strings. I hope there aren't too many > of those in the wild. The following cases are currently broken: * Calling openFile on a literal Unicode FilePath (note, not ACP-encoded, just Unicode). * Reading a Unicode FilePath from a text file and then calling openFile on it I propose to fix these (on Windows). It will mean that your second case above will be broken, until someone fixes getDirectoryContents. Also currently broken: * calling removeFile on a FilePath you get from getDirectoryContents, amongst other System.Directory operations Fixing getDirectoryContents will fix these. I don't know how getArgs fits in here - should we be decoding argv using the ACP? Cheers, Simon From briqueabraque at yahoo.com Tue Jun 16 09:48:19 2009 From: briqueabraque at yahoo.com (=?ISO-8859-1?Q?Maur=ED=ADcio?=) Date: Tue Jun 16 09:31:50 2009 Subject: [Haskell-cafe] Could FFI support pass-by-value of structs? Message-ID: It's not usual, but it is allowed to have values of structs passed between functions directly instead of using pointers: /*****/ struct ex { int x; int y; int z; }; ex example_functions (ex p) { (...) } /*****/ Would it be possible to allow that in Haskell FFI by, say, allowing any instance of Storable to be used in a 'foreign' declaration? Like: -- data Ex = (...) instance Storable Ex where sizeOf _ = ... alignment = sizeOf (...) foreign import ccall "example_functions" exampleFunction :: Ex -> IO Ex -- Thanks, Maur?cio From bulat.ziganshin at gmail.com Tue Jun 16 09:56:30 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Tue Jun 16 09:40:13 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A3797F3.2040707@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> Message-ID: <1893812247.20090616175630@gmail.com> Hello Simon, Tuesday, June 16, 2009, 5:02:43 PM, you wrote: > Also currently broken: > * calling removeFile on a FilePath you get from getDirectoryContents, > amongst other System.Directory operations > Fixing getDirectoryContents will fix these. no. removeFile like anything else also uses ACP-based api > I don't know how getArgs fits in here - should we be decoding argv using > the ACP? well, the whole story: windows internally uses Unicode for handling strings. externally, it provides 2 API families: 1) A-family (such as CreateFileA) uses 8-bit char-based strings. these strings are encoded using current locale. First 128 chars are common for all codepages, providing ASCII char set, higher 128 chars are locale-specific. say, for German locale, it provides chars with umlauts, for Russian locale - cyrillic chars 2) W-family (such as CreateFileW) uses UTF-16 encoded 16-bit wchar-based strings, which are locale-independent Windows libraries emulates POSIX API (open, opendir, stat and so on) by translating these (char-based) calls into A-family. GHC libs are written Unix way, so these are effectively bundled to A-family of Win API Windows libraries also provides w* variant of POSIX API (wopen, wopendir, wstat...) that uses UTF-16 encoded 16-bit wchar-based strings, so for proper handling of Unicode strings (filenames, cmdline arguments) we should use these APIs my old proposal: http://haskell.org/haskellwiki/Library/IO -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From voigt at tcs.inf.tu-dresden.de Tue Jun 16 10:16:01 2009 From: voigt at tcs.inf.tu-dresden.de (Janis Voigtlaender) Date: Tue Jun 16 09:59:20 2009 Subject: [Haskell-cafe] PEPM'10 - First Call for Papers Message-ID: <4A37A921.6060000@tcs.inf.tu-dresden.de> =============================================================== CALL FOR PAPERS ACM SIGPLAN 2010 Workshop on Partial Evaluation and Program Manipulation (PEPM'10) Madrid, January 18-19, 2010 (Affiliated with POPL'10) http://www.program-transformation.org/PEPM10 =============================================================== IMPORTANT DATES: * Paper submission: Tue, October 6, 2009, 23:59, Apia time * Author notification: Thu, October 29, 2009 * Camera-ready papers: Mon, November 9, 2009 To facilitate smooth organization of the review process, authors are asked to submit a short abstract by October 1, 2009. SUBMISSION CATEGORIES: * Regular research papers (max. 10 pages in ACM Proceedings style) * Tool demonstration papers (max. 4 pages plus max. 6 pages appendix) SCOPE: The PEPM Symposium/Workshop series aims to bring together researchers and practitioners working in the areas of program manipulation, partial evaluation, and program generation. PEPM focuses on techniques, theory, tools, and applications of analysis and manipulation of programs. The 2010 PEPM workshop will be based on a broad interpretation of semantics-based program manipulation and continue previous years' effort to expand the scope of PEPM significantly beyond the traditionally covered areas of partial evaluation and specialization and include practical applications of program transformations such as refactoring tools, and practical implementation techniques such as rule-based transformation systems. In addition, the scope of PEPM covers manipulation and transformations of program and system representations such as structural and semantic models that occur in the context of model-driven development. In order to reach out to practitioners, there is a separate category of tool demonstration papers. Topics of interest for PEPM'10 include, but are not limited to: * Program and model manipulation techniques such as transformations driven by rules, patterns, or analyses, partial evaluation, specialization, program inversion, program composition, slicing, symbolic execution, refactoring, aspect weaving, decompilation, and obfuscation. * Program analysis techniques that are used to drive program/model manipulation such as abstract interpretation, static analysis, binding-time analysis, dynamic analysis, constraint solving, type systems, automated testing and test case generation. * Analysis and transformation for programs/models with advanced features such as objects, generics, ownership types, aspects, reflection, XML type systems, component frameworks, and middleware. * Techniques that treat programs/models as data objects including meta-programming, generative programming, deep embedded domain-specific languages, program synthesis by sketching and inductive programming, staged computation, and model-driven program generation and transformation. * Application of the above techniques including experimental studies, engineering needed for scalability, and benchmarking. Examples of application domains include legacy program understanding and transformation, DSL implementations, visual languages and end-user programming, scientific computing, middleware frameworks and infrastructure needed for distributed and web-based applications, resource-limited computation, and security. We especially encourage papers that break new ground including descriptions of how program/model manipulation tools can be integrated into realistic software development processes, descriptions of robust tools capable of effectively handling realistic applications, and new areas of application such as rapidly evolving systems, distributed and web-based programming including middleware manipulation, model-driven development, and on-the-fly program adaptation driven by run-time or statistical analysis. PROCEEDINGS: There will be formal proceedings published by ACM Press. In addition to printed proceedings, accepted papers will be included in the ACM Digital Library. Selected papers may later on be invited for a journal special issue dedicated to PEPM'10. SUBMISSION GUIDELINES: Papers should be submitted electronically via the workshop web site. Regular research papers must not exceed 10 pages in ACM Proceedings style. Tool demonstration papers must not exceed 4 pages in ACM Proceedings style, and authors will be expected to present a live demonstration of the described tool at the workshop (tool papers should include an additional appendix of up to 6 additional pages giving the outline, screenshots, examples, etc. to indicate the content of the proposed live demo at the workshop). Authors using Latex to prepare their submissions should use the new improved SIGPLAN proceedings style (sigplanconf.cls). PROGRAM CO-CHAIRS: * John Gallagher (Roskilde University, Denmark, and IMDEA Software, Spain) * Janis Voigtl?nder (Technische Universit?t Dresden, Germany) PROGRAM COMMITTEE MEMBERS: * Wei-Ngan Chin (National University of Singapore, Singapore) * Michael Codish (Ben-Gurion University of the Negev, Israel) * Jim Cordy (Queen's University, Canada) * Nate Foster (University of Pennsylvania, USA) * Haifeng Guo (University of Nebraska at Omaha, USA) * Patricia Johann (University of Strathclyde, UK) * Oleg Kiselyov (FNMOC, USA) * G?nter Kniesel (University of Bonn, Germany) * Viktor Kuncak (Ecole Polytechnique F?d?rale de Lausanne, Switzerland) * Yanhong Annie Liu (State University of New York at Stony Brook, USA) * Andres L?h (Utrecht University, Netherlands) * Jan Midtgaard (Roskilde University, Denmark) * David Monniaux (National Center for Scientific Research (CNRS) and VERIMAG laboratory, France) * Akimasa Morihata (University of Tokyo, Japan) * Alberto Pettorossi (Universit? di Roma Tor Vergata, Italy) * Jo?o Saraiva (Universidade do Minho, Portugal) * Ganesh Sittampalam (Credit Suisse, UK) * Fausto Spoto (Universit? di Verona, Italy) * Harald S?ndergaard (University of Melbourne, Australia) * Walid Taha (Rice University, USA) From byorgey at seas.upenn.edu Tue Jun 16 10:49:28 2009 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Tue Jun 16 10:32:45 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: <4A36A31A.10504@semantic.org> References: <1244822326.28941.29.camel@flippa-eee> <4A35B78C.3040809@semantic.org> <1245086323.3817.2.camel@glastonbury> <1245089315.5131.5.camel@flippa-eee> <4A369677.2010500@therning.org> <4A36A31A.10504@semantic.org> Message-ID: <20090616144928.GA12851@seas.upenn.edu> On Mon, Jun 15, 2009 at 12:38:02PM -0700, Ashley Yakeley wrote: > Magnus Therning wrote: >> Philippa Cowderoy wrote: >>> On Mon, 2009-06-15 at 13:52 -0400, Gwern Branwen wrote: >>>> -----BEGIN PGP SIGNED MESSAGE----- >>>> Hash: SHA512 >>>> >>>> On Mon, Jun 15, 2009 at 1:18 PM, Ashley Yakeley wrote: >>>>> For requesting accounts: who would receive the email, and which person >>>>> would create the account? >>>>> >>>> Why not just list everyone's email and let the requester pick who to >>>> send the request to? >>>> >>> >>> A mailing list, possibly attached to a ticketing/queue system, seems a >>> good idea? If it's just a list, admins should ack when they've added >>> someone to avoid duplicated effort. >> That seems like a good, simple solution! > > OK, so who wants to create accounts? What are your haskell.org usernames? I'm byorgey on haskell.org and on the wiki. -Brent From marlowsd at gmail.com Tue Jun 16 11:30:55 2009 From: marlowsd at gmail.com (Simon Marlow) Date: Tue Jun 16 11:14:16 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <1893812247.20090616175630@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <1893812247.20090616175630@gmail.com> Message-ID: <4A37BAAF.90600@gmail.com> On 16/06/2009 14:56, Bulat Ziganshin wrote: > Hello Simon, > > Tuesday, June 16, 2009, 5:02:43 PM, you wrote: > >> Also currently broken: > >> * calling removeFile on a FilePath you get from getDirectoryContents, >> amongst other System.Directory operations > >> Fixing getDirectoryContents will fix these. > > no. removeFile like anything else also uses ACP-based api What code are you looking at? Here is System.Directory.removeFile: removeFile :: FilePath -> IO () removeFile path = #if mingw32_HOST_OS System.Win32.deleteFile path #else System.Posix.removeLink path #endif and System.Win32.deleteFile: deleteFile :: String -> IO () deleteFile name = withTString name $ \ c_name -> failIfFalse_ "DeleteFile" $ c_DeleteFile c_name foreign import stdcall unsafe "windows.h DeleteFileW" c_DeleteFile :: LPCTSTR -> IO Bool note it's calling DeleteFileW, and using wide-char strings. > Windows libraries emulates POSIX API (open, opendir, stat and so on) > by translating these (char-based) calls into A-family. GHC libs are > written Unix way, so these are effectively bundled to A-family of Win > API Actually we use a mixture of CRT functions and native Windows API, gradually moving in the direction of the latter. Cheers, Simon From dons at galois.com Tue Jun 16 11:36:41 2009 From: dons at galois.com (Don Stewart) Date: Tue Jun 16 11:21:50 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> Message-ID: <20090616153641.GA4695@whirlpool.galois.com> tom.davie: > > On 16 Jun 2009, at 05:18, Don Stewart wrote: > >> keithshep: >>> The answer is sometimes (only if you use an optimize flag): >> >> You're turning on the strictness analyser. That's enabled with -O or >> -O2. >> >> But sum should be using a tail recursive foldl'. It's a bug in the H98 >> report, IMO. > > Not at all, as discussed, there are legitimate uses for a lazy sum, and > haskell is a lazy language by default. The only change here needs to be > either claus' suggestion of generalizing functions over their > application operator, or providing a strict sum'. Are the legitimate uses more common than the illegitimate uses? -- Don From bulat.ziganshin at gmail.com Tue Jun 16 11:44:34 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Tue Jun 16 11:27:57 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A37BAAF.90600@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <1893812247.20090616175630@gmail.com> <4A37BAAF.90600@gmail.com> Message-ID: <588951384.20090616194434@gmail.com> Hello Simon, Tuesday, June 16, 2009, 7:30:55 PM, you wrote: > Actually we use a mixture of CRT functions and native Windows API, > gradually moving in the direction of the latter. so file-related APIs are already unpredictable, and will remain in this state for unknown amount of ghc versions -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From marlowsd at gmail.com Tue Jun 16 11:54:02 2009 From: marlowsd at gmail.com (Simon Marlow) Date: Tue Jun 16 11:37:22 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <588951384.20090616194434@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <1893812247.20090616175630@gmail.com> <4A37BAAF.90600@gmail.com> <588951384.20090616194434@gmail.com> Message-ID: <4A37C01A.10905@gmail.com> On 16/06/2009 16:44, Bulat Ziganshin wrote: > Hello Simon, > > Tuesday, June 16, 2009, 7:30:55 PM, you wrote: > >> Actually we use a mixture of CRT functions and native Windows API, >> gradually moving in the direction of the latter. > > so file-related APIs are already unpredictable, and will remain in > this state for unknown amount of ghc versions Sometimes fixing everything at the same time is too hard :-) In fact there's not a lot left to convert in System.Directory, as you'll see if you look at the code. Feel like helping? Cheers, Simon From dons at galois.com Tue Jun 16 11:58:58 2009 From: dons at galois.com (Don Stewart) Date: Tue Jun 16 11:44:41 2009 Subject: [Haskell-cafe] slow code In-Reply-To: <00FDD473-F0DB-41F8-8410-C435CDF045C0@aracnet.com> References: <9621AF5D-5C87-43A6-B8A2-103109570416@aracnet.com> <00FDD473-F0DB-41F8-8410-C435CDF045C0@aracnet.com> Message-ID: <20090616155858.GE4695@whirlpool.galois.com> briand: > I have included a new and improved version. > > Just to make the comparison a little more reasonable I re-wrote the > program using ML and ran it with SMLNJ > > eal 0m3.175s > user 0m0.935s > sys 0m0.319s > > Here's the compiled haskell (ghc -O2 foo.hs -o foo): > > real 0m16.855s > user 0m9.724s > sys 0m0.495s > > OUCH. > > I verified to make sure they were both writing valid data files. > > I'm trying to learn how to fish, so I'm truly interested in finding out > _how_ to optimize using profiling and other such tools. > > Here's the header of the foo.prof file: > > total time = 9.44 secs (472 ticks @ 20 ms) > total alloc = 2,171,923,916 bytes (excludes profiling overheads) > > 2GB of allocation ??? with a base size of 131k. that seems excessive, > which gets me back to the , I don't > think I'm interpreting profiling stuff correctly. > > This line is a little more interesting: > > COST CENTRE MODULE > no. entries %time %alloc %time %alloc > main Main > 178 1 98.7 99.1 98.7 99.1 > > So even though getData should be doing all of the allocation, main's > using a lot of time and effort. I figured it > was the show's that were slowing things up (how do I get profiling to > show that detail ?), so I had it output just "\n". > Well that finishes in no time at all. > > And yea, verily, the output of the .prof file. > > total time = 0.14 secs (7 ticks @ 20 ms) > total alloc = 65,562,824 bytes (excludes profiling overheads) > > So I guess it's the show's, but I can't seem to find more efficient > float output. > FFI to sprintf ? yuch. Is your SMLNJ using lazy lists? :) Try hmatrix or uvector. -- Don From bulat.ziganshin at gmail.com Tue Jun 16 12:06:41 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Tue Jun 16 11:50:12 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A37C01A.10905@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <1893812247.20090616175630@gmail.com> <4A37BAAF.90600@gmail.com> <588951384.20090616194434@gmail.com> <4A37C01A.10905@gmail.com> Message-ID: <44614945.20090616200641@gmail.com> Hello Simon, Tuesday, June 16, 2009, 7:54:02 PM, you wrote: > In fact there's not a lot left to convert in System.Directory, as you'll > see if you look at the code. Feel like helping? these functions used there are ACP-only: c_stat c_chmod System.Win32.getFullPathName c_SearchPath c_SHGetFolderPath plus may be some more functions from System.Win32 package - i don't looked into it -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From briqueabraque at yahoo.com Tue Jun 16 13:26:53 2009 From: briqueabraque at yahoo.com (=?ISO-8859-1?Q?Maur=ED=ADcio?=) Date: Tue Jun 16 13:10:31 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: <1244822326.28941.29.camel@flippa-eee> References: <1244822326.28941.29.camel@flippa-eee> Message-ID: > I'm hearing reports of people having difficulty obtaining accounts on > the Haskell wiki, without which it is impossible to make edits. > Currently, account creation is disabled as an anti-spam measure, and the > idea is for people to mail the admin and request an account. (...) Maybe OpenID could help with spam problems without the need for manual intervention: http://www.mediawiki.org/wiki/Extension:OpenID Best, Maur?cio From ashley at semantic.org Tue Jun 16 14:52:29 2009 From: ashley at semantic.org (Ashley Yakeley) Date: Tue Jun 16 14:35:49 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: References: <1244822326.28941.29.camel@flippa-eee> Message-ID: <4A37E9ED.5040903@semantic.org> Maur??cio wrote: > Maybe OpenID could help with spam problems without > the need for manual intervention: > > http://www.mediawiki.org/wiki/Extension:OpenID Nope, can't install it on this version. http://haskell.org/haskellwiki/Special:Version -- Ashley Yakeley From flippa at flippac.org Tue Jun 16 14:58:04 2009 From: flippa at flippac.org (Philippa Cowderoy) Date: Tue Jun 16 14:41:28 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: References: <1244822326.28941.29.camel@flippa-eee> Message-ID: <1245178684.5131.8.camel@flippa-eee> [sent to the list as well this time] On Tue, 2009-06-16 at 14:26 -0300, Maur??cio wrote: > > I'm hearing reports of people having difficulty obtaining accounts on > > the Haskell wiki, without which it is impossible to make edits. > > Currently, account creation is disabled as an anti-spam measure, and the > > idea is for people to mail the admin and request an account. (...) > > Maybe OpenID could help with spam problems without > the need for manual intervention: > > http://www.mediawiki.org/wiki/Extension:OpenID I doubt it - I know LiveJournal has a problem with spambots gaining free accounts, and it provides OpenID. They may not be exploited for the OpenID account yet, but I imagine they will be sooner rather than later - OpenID is more useful to tie in people's existing identities. -- Philippa Cowderoy From bulat.ziganshin at gmail.com Tue Jun 16 16:19:45 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Tue Jun 16 16:03:09 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A3797F3.2040707@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> Message-ID: <1829193364.20090617001945@gmail.com> Hello Simon, Tuesday, June 16, 2009, 5:02:43 PM, you wrote: > I don't know how getArgs fits in here - should we be decoding argv using > the ACP? myGetArgs = do alloca $ \p_argc -> do p_argv_w <- commandLineToArgvW getCommandLineW p_argc argc <- peek p_argc argv_w <- peekArray (i argc) p_argv_w mapM peekTString argv_w >>= return.tail foreign import stdcall unsafe "windows.h GetCommandLineW" getCommandLineW :: LPTSTR foreign import stdcall unsafe "windows.h CommandLineToArgvW" commandLineToArgvW :: LPCWSTR -> Ptr CInt -> IO (Ptr LPWSTR) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From ravi at bluespec.com Tue Jun 16 17:51:30 2009 From: ravi at bluespec.com (Ravi Nanavati) Date: Tue Jun 16 17:34:48 2009 Subject: [Haskell-cafe] BostonHaskell: Next meeting - June 23rd at MIT CSAIL Reading Room (32-G882) Message-ID: <7b977d860906161451m684b559bnb09b1a6ac5d3d385@mail.gmail.com> I'm pleased to announce the second meeting of the Boston Area Haskell Users' Group. The meeting is scheduled for Tuesday, June 23rd from 6:30pm - 8:30pm (*). It will be held in the MIT CSAIL Reading Room (32-G882, i.e. a room on the 8th floor of the Gates Tower of the MIT's Stata Center at 32 Vassar St in Cambridge, MA). We have the following two talks scheduled (each intended to be 30-45 minutes each): "Automagic Font Conversion with Haskell Typeclasses" by Frank Berthold "Intermediate Language Representations via GADTs" by Nirav Dave As in the last meeting there will be a break between the talks for discussion and mingling. As we are an informal, unsponsored group, there are no current plans to provide refreshments during the break, but I encourage people to volunteer to provide them (please contact me at ravi@bluespec.com so I can keep track of what to expect). I'll make sure to appropriately thank any refreshment volunteers at the meeting. If you have any questions about the meeting please send them to the BostonHaskell mailing list: bostonhaskell@googlegroups.com or contact me directly. I look forward to seeing many Boston area Haskellers next Tuesday! - Ravi Nanavati (*) I interpreted the silence in response to my previous email proposing June 23rd as assent. If this was a bad time or date to pick, please send your scheduling comments to the BostonHaskell list (i.e. bostonhaskell@googlegroups.com) so we can do a better job of picking a date and time in the future. From dagit at codersbase.com Tue Jun 16 18:08:56 2009 From: dagit at codersbase.com (Jason Dagit) Date: Tue Jun 16 17:52:13 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: <1245178684.5131.8.camel@flippa-eee> References: <1244822326.28941.29.camel@flippa-eee> <1245178684.5131.8.camel@flippa-eee> Message-ID: On Tue, Jun 16, 2009 at 11:58 AM, Philippa Cowderoy wrote: > [sent to the list as well this time] > > On Tue, 2009-06-16 at 14:26 -0300, Maur??cio wrote: > > > I'm hearing reports of people having difficulty obtaining accounts on > > > the Haskell wiki, without which it is impossible to make edits. > > > Currently, account creation is disabled as an anti-spam measure, and > the > > > idea is for people to mail the admin and request an account. (...) > > > > Maybe OpenID could help with spam problems without > > the need for manual intervention: > > > > http://www.mediawiki.org/wiki/Extension:OpenID > > I doubt it - I know LiveJournal has a problem with spambots gaining free > accounts, and it provides OpenID. They may not be exploited for the > OpenID account yet, but I imagine they will be sooner rather than later > - OpenID is more useful to tie in people's existing identities. On that topic, as a future enhancement of the haskell wiki I would love to be able to use OpenID. Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090616/875f51a4/attachment.html From niklas.broberg at gmail.com Tue Jun 16 18:43:47 2009 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Tue Jun 16 18:27:03 2009 Subject: [Haskell-cafe] ANN: haskell-src-exts 1.0.0 rc1 (aka 0.5.2) Message-ID: Fellow Haskelleers, I'm pleased to report that I feel I have now completed the first milestone in my GSoC project for haskell-src-exts: Full Code Support. This means I feel ready to take that scary leap that means to drop the safe 0.x version numbering (experimental) and finally make the first stable release, version 1.0.0. But before I take that leap I want the library to be thoroughly tested, so I can with confidence say that it truly *is* stable. Therefore, I hereby announce the release on hackage of haskell-src-exts-0.5.2, which I consider (almost) a release candidate for 1.0.0. * Via cabal: cabal install haskell-src-exts * On Hackage: http://hackage.haskell.org/package/haskell-src-exts-0.5.2 * Via darcs: darcs get http://code.haskell.org/haskell-src-exts I would be delighted if as many as possible would consider testing it on their code, even those of you who feel that you may not have any immediate use of the library, just to cover as much code base as possible in the hunt for potential bugs and misfeatures. Testing it is really easy, four simple steps: > cabal install haskell-src-exts [...] > ghci [...] Prelude> :m Language.Haskell.Exts Prelude Language.Haskell.Exts> parseFile "YourFileHere.(l)hs" If you get a parse error on a file that you feel should have been accepted, let me know! If the parser gives you an AST result for a file that you feel it shouldn't have accepted, let me know! Here's the bug tracker: http://trac.haskell.org/haskell-src-exts/report/1 The reason I say it is "almost" a release candidate is that while I consider the functionality to be in place, I will tidy up the exports, add a few more convenient functions to export, and add a lot of documentation, before I make the actual release. If you have a request for a particularly conventient function to add to the list of exports from the package, it's thus not too late to get it into 1.0.0. :-) What's cool in haskell-src-exts-0.5.2: ============================ * Support for all syntactic extensions supported by GHC, with two exceptions: UnicodeSyntax and NewQualifiedOperators. These will likely be added in the next feature release. Exclusive support for the newly registered XmlSyntax and RegularPatterns extensions. No support (yet) for Hugs-specific extensions (RestrictedTypeSynonyms, ExtensibleRecords, HereDocuments). No support for CPP. Also does not support the GHC-specific relaxation of layout in do-blocks, which is an unregistered extension (that should be registered!). * Support for parametrising the parsing on what extensions it should recognise. With no extensions given, it assumes Haskell98. Note that 'parseFile' will look for language pragmas in your source file to decide what extensions to use when parsing. If you want to be explicit, you can use 'parseFileWithExts', or 'parseFileWithMode' that lets you set a few other things as well. I intend to add some convenient names of extension groups, such as 'ghcExtensions' and 'glasgowExts', this is one area where I would particularly welcome suggestions. * Support for correct fixities of infix operators. By default it uses the fixities defined in the Prelude, as well as in the current document (including local let-bound fixities). Use 'parseFileWithMode' to set a different set of fixities. Language.Haskell.Exts.Fixity defines preludeFixities and baseFixities (all fixities defined in the base package), as well as combinators for defining your own sets. Much thanks to Neil Mitchell for the meat of this code. * No (known) bugs! :-) Special note for users of HaRP/HSP: I've uploaded a new version of hsx, hsx-0.5.0, that works with haskell-src-exts-0.5.2. There is one known bug in this version though, it cannot handle 'proc' entities from the Arrows extensions, I'm still considering how to fix that. In the mean time you can use it just fine, as long as your files don't contain any 'proc' blocks (which the old version couldn't handle anyway). Cheers and happy Haskelling, /Niklas From ok at cs.otago.ac.nz Tue Jun 16 18:50:45 2009 From: ok at cs.otago.ac.nz (Richard O'Keefe) Date: Tue Jun 16 18:34:06 2009 Subject: [Haskell-cafe] Performance of functional priority queues In-Reply-To: <7ca3f0160906150054l3379fbcej5349bf95b86ad438@mail.gmail.com> References: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> <7ca3f0160906150054l3379fbcej5349bf95b86ad438@mail.gmail.com> Message-ID: On 15 Jun 2009, at 7:54 pm, Luke Palmer wrote: > One of the correspondents in that thread claims that it is > provably impossible to have an efficient priority queue implementation > without mutability. > > If he so claims, maybe you can challenge him by asking for a proof? He claims that the burden is on my end. > > > Such a proof would probably only involve asymptotics, since it's > very hard to prove anything when actual raw speed is involved. > If that's the case, you can use Okasaki to back yourself up (or > back him up; I am not familiar with the results in this area). He is aware of Okasaki's book, about which he was somewhat offensive. One thing that's clear is that he _isn't_ talking about asymptotics. > I've now done some benchmarks myself in C, Java, and Smalltalk, comparing "imperative" versions of leftist heaps with "functional" ones. For what it's worth, on a 2.16GHz Intel Core 2 Duo Mac, the coefficient in front of the log(n) part was C Java ST(A) ST(B) "Imperative" 40 70 150 1123 "Functional" 240 126 290 1895 where ST(A) was a native-code Smalltalk and ST(B) a byte-code one. The C/Functional case used the Boehm collector, untuned. Times are in nanoseconds. Values of n ranged from 2 to 100; the correspondent was saying that small sizes were important. It seems that a factor of 2 for *this* problem is credible; a factor of 10 is not. From ashley at semantic.org Tue Jun 16 19:16:28 2009 From: ashley at semantic.org (Ashley Yakeley) Date: Tue Jun 16 18:59:47 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: <4A36A31A.10504@semantic.org> References: <1244822326.28941.29.camel@flippa-eee> <4A35B78C.3040809@semantic.org> <1245086323.3817.2.camel@glastonbury> <1245089315.5131.5.camel@flippa-eee> <4A369677.2010500@therning.org> <4A36A31A.10504@semantic.org> Message-ID: <4A3827CC.50806@semantic.org> I wrote: > OK, so who wants to create accounts? What are your haskell.org usernames? Anyone else? Gwern? Philippa? -- Ashley Yakeley From pumpkingod at gmail.com Tue Jun 16 19:25:53 2009 From: pumpkingod at gmail.com (Daniel Peebles) Date: Tue Jun 16 19:09:10 2009 Subject: [Haskell-cafe] Performance of functional priority queues In-Reply-To: References: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> <7ca3f0160906150054l3379fbcej5349bf95b86ad438@mail.gmail.com> Message-ID: He sounds like a bit of a troll, but I agree the question itself is an interesting one and I'd be interested to see if anyone has an "answer" (although given the lack of criteria, it'll be hard to address his points exactly) On Tue, Jun 16, 2009 at 6:50 PM, Richard O'Keefe wrote: > > On 15 Jun 2009, at 7:54 pm, Luke Palmer wrote: >> >> One of the correspondents in that thread claims that it is >> provably impossible to have an efficient priority queue implementation >> without mutability. >> >> If he so claims, maybe you can challenge him by asking for a proof? > > He claims that the burden is on my end. >> >> >> Such a proof would probably only involve asymptotics, since it's very hard >> to prove anything when actual raw speed is involved. >> ?If that's the case, you can use Okasaki to back yourself up (or back him >> up; I am not familiar with the results in this area). > > He is aware of Okasaki's book, about which he was somewhat offensive. > One thing that's clear is that he _isn't_ talking about asymptotics. >> > > I've now done some benchmarks myself in C, Java, and Smalltalk, > comparing "imperative" versions of leftist heaps with "functional" ones. > For what it's worth, on a 2.16GHz Intel Core 2 Duo Mac, the > coefficient in front of the log(n) part was > > ? ? ? ? ? ? ? ?C ? ? ? Java ? ?ST(A) ? ST(B) > "Imperative" ? ?40 ? ? ? 70 ? ? 150 ? ? 1123 > "Functional" ? 240 ? ? ?126 ? ? 290 ? ? 1895 > > where ST(A) was a native-code Smalltalk and ST(B) a byte-code one. > The C/Functional case used the Boehm collector, untuned. > Times are in nanoseconds. ?Values of n ranged from 2 to 100; the > correspondent was saying that small sizes were important. > > It seems that a factor of 2 for *this* problem is credible; > a factor of 10 is not. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From gwern0 at gmail.com Tue Jun 16 19:57:23 2009 From: gwern0 at gmail.com (Gwern Branwen) Date: Tue Jun 16 19:40:40 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: <4A3827CC.50806@semantic.org> References: <1244822326.28941.29.camel@flippa-eee> <4A35B78C.3040809@semantic.org> <1245086323.3817.2.camel@glastonbury> <1245089315.5131.5.camel@flippa-eee> <4A369677.2010500@therning.org> <4A36A31A.10504@semantic.org> <4A3827CC.50806@semantic.org> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On Tue, Jun 16, 2009 at 7:16 PM, Ashley Yakeley wrote: > Anyone else? Gwern? Philippa? As usual, I am User:Gwern. On the side-topic of a mailing list - I really think that is too heavy-weight. We want people to create a login (for the ML) and go through the ML, just to get wiki access? A view I've long held is that wikis only work because they are easy to contribute to. When you ask someone for a favor, you don't make them jump through hoops. Even trivial extra steps cut down the # of people willing to do it. There must be methods that put as little a burden on eager would-be newbie editors. Just posting the emails of people with account-creation abilities is the easiest way I can think of. - -- gwern -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEAREKAAYFAko4MWIACgkQvpDo5Pfl1oKtagCfQNTxtn5dnTqwXxD5YP5zTO+w TjwAn2JAu09ackQs8xY44qPoe2p2g6v5 =oGcB -----END PGP SIGNATURE----- From daniel.is.fischer at web.de Tue Jun 16 20:03:55 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Tue Jun 16 19:48:01 2009 Subject: [Haskell-cafe] Performance of functional priority queues In-Reply-To: References: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> <7ca3f0160906150054l3379fbcej5349bf95b86ad438@mail.gmail.com> Message-ID: <200906170203.55688.daniel.is.fischer@web.de> Am Mittwoch 17 Juni 2009 00:50:45 schrieb Richard O'Keefe: > > One of the correspondents in that thread claims that it is > > provably impossible to have an efficient priority queue implementation > > without mutability. > > > > If he so claims, maybe you can challenge him by asking for a proof? > > He claims that the burden is on my end. Certainly not. He claims X is provable, so he has to either provide a proof himself (a sketch may suffice), or tell you where you can find a proof. The burden of proof is always on the claimant. From gue.schmidt at web.de Tue Jun 16 20:28:55 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Tue Jun 16 20:12:22 2009 Subject: [Haskell-cafe] Need some help with an infinite list Message-ID: Hi guys, I'd like to generate an infinite list, like ["a", "b", "c" .. "z", "aa", "ab", "ac" .. "az", "ba", "bb", "bc" .. "bz", "ca" ...] When I had set out to do this I thought, oh yeah no prob, in a heartbeat. Uhm. Help, pls! G?nther PS: I know this should be a no-brainer, sry From niklas.broberg at gmail.com Tue Jun 16 20:35:09 2009 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Tue Jun 16 20:18:26 2009 Subject: [Haskell-cafe] Re: ANN: haskell-src-exts 1.0.0 rc1 (aka 0.5.2) In-Reply-To: References: Message-ID: > * Via cabal: cabal install haskell-src-exts Thanks a lot to Brian Lewis for catching the first bug - cabal install doesn't even work for 0.5.2! The problem is that the cabal test machinery can't find the Language.Haskell.Exts modules, unless haskell-src-exts is already installed first... At any rate: I'm pleased to announce haskell-src-exts-0.5.3! Everything else from above still applies. :-) Cheers, /Niklas From pumpkingod at gmail.com Tue Jun 16 20:39:05 2009 From: pumpkingod at gmail.com (Daniel Peebles) Date: Tue Jun 16 20:22:21 2009 Subject: [Haskell-cafe] Need some help with an infinite list In-Reply-To: References: Message-ID: One (rather ugly) option is: tail . map (\y -> showIntAtBase 26 (\x -> chr (x + 96)) y "") $ [0..] but I'm sure there's a prettier one out there :) On Tue, Jun 16, 2009 at 8:28 PM, G??nther Schmidt wrote: > Hi guys, > > I'd like to generate an infinite list, like > > ["a", "b", "c" .. "z", "aa", "ab", "ac" .. "az", "ba", "bb", "bc" .. "bz", > "ca" ...] > > When I had set out to do this I thought, oh yeah no prob, in a heartbeat. > > Uhm. > > Help, pls! > > G?nther > > PS: I know this should be a no-brainer, sry > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From rmm-haskell at z.odi.ac Tue Jun 16 20:47:02 2009 From: rmm-haskell at z.odi.ac (Ross Mellgren) Date: Tue Jun 16 20:30:21 2009 Subject: [Haskell-cafe] Need some help with an infinite list In-Reply-To: References: Message-ID: Here's a way using list comprehensions: Prelude Data.List> take 1000 $ concat.concat $ [ [ replicate n c | c <- ['a'..'z'] ] | n <- [1..] ] "abcdefghijklmnopqrstuvwxyzaabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvw wxxyyzzaaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzzaaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzzaaaaabbbbbcccccdddddeeeeefffffggggghhhhhiiiiijjjjjkkkkklllllmmmmmnnnnnooooopppppqqqqqrrrrrssssstttttuuuuuvvvvvwwwwwxxxxxyyyyyzzzzzaaaaaabbbbbbccccccddddddeeeeeeffffffgggggghhhhhhiiiiiijjjjjjkkkkkkllllllmmmmmmnnnnnnooooooppppppqqqqqqrrrrrrssssssttttttuuuuuuvvvvvvwwwwwwxxxxxxyyyyyyzzzzzzaaaaaaabbbbbbbcccccccdddddddeeeeeeefffffffggggggghhhhhhhiiiiiiijjjjjjjkkkkkkklllllllmmmmmmmnnnnnnnooooooopppppppqqqqqqqrrrrrrrssssssstttttttuuuuuuuvvvvvvvwwwwwwwxxxxxxxyyyyyyyzzzzzzzaaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhhiiiiiiiijjjjjjjjkkkkkkkkllllllllmmmmmmmmnnnnnnnnooooooooppppppppqqqqqqqqrrrrrrrrssssssssttttttttuuuuuuuuvvvvvvvvwwwwwwwwxxxxxxxxyyyyyyyyzzzzzzzzaaaaaaaaabbbbbbbbbcccccccccdddddddddeeeeeeeeefffffffffgggggggggh" -Ross On Jun 16, 2009, at 8:39 PM, Daniel Peebles wrote: > One (rather ugly) option is: > > tail . map (\y -> showIntAtBase 26 (\x -> chr (x + 96)) y "") $ [0..] > > but I'm sure there's a prettier one out there :) > > On Tue, Jun 16, 2009 at 8:28 PM, G??nther > Schmidt wrote: >> Hi guys, >> >> I'd like to generate an infinite list, like >> >> ["a", "b", "c" .. "z", "aa", "ab", "ac" .. "az", "ba", "bb", >> "bc" .. "bz", >> "ca" ...] >> >> When I had set out to do this I thought, oh yeah no prob, in a >> heartbeat. >> >> Uhm. >> >> Help, pls! >> >> G?nther >> >> PS: I know this should be a no-brainer, sry >> >> _______________________________________________ >> 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 tom.davie at gmail.com Tue Jun 16 20:56:55 2009 From: tom.davie at gmail.com (Thomas Davie) Date: Tue Jun 16 20:40:14 2009 Subject: [Haskell-cafe] Need some help with an infinite list In-Reply-To: References: Message-ID: <71840F92-381B-44F1-9915-5C68503C9D7C@gmail.com> letterCombos = map (:[]) ['a'..'z'] ++ concatMap (\c -> map ((c++) . (: [])) ['a'..'z']) letterCombos Not hugely efficient, if you generate the strings in reverse then you can use (c:) rather than ((c++) . (:[])), but that may not be useful to you. Bob On 17 Jun 2009, at 02:28, G??nther Schmidt wrote: > Hi guys, > > I'd like to generate an infinite list, like > > ["a", "b", "c" .. "z", "aa", "ab", "ac" .. "az", "ba", "bb", "bc" .. > "bz", "ca" ...] > > When I had set out to do this I thought, oh yeah no prob, in a > heartbeat. > > Uhm. > > Help, pls! > > G?nther > > PS: I know this should be a no-brainer, sry > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From tom at pledger.gen.nz Tue Jun 16 21:09:52 2009 From: tom at pledger.gen.nz (Tom Pledger) Date: Tue Jun 16 20:53:25 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list References: Message-ID: G??nther Schmidt web.de> writes: > > Hi guys, > > I'd like to generate an infinite list, like > > ["a", "b", "c" .. "z", "aa", "ab", "ac" .. "az", "ba", "bb", "bc" .. > "bz", "ca" ...] If you're happy to have a "" before the "a", you can do this as a fairly cute one-liner in a similar style to this list of Fibonacci numbers. fib = 0:1:[m + n | (m, n) <- zip fib (tail fib)] Regards, Tom From hiena03 at gmail.com Tue Jun 16 21:15:36 2009 From: hiena03 at gmail.com (=?ISO-8859-1?Q?Jos=E9_Prous?=) Date: Tue Jun 16 20:58:55 2009 Subject: [Haskell-cafe] Need some help with an infinite list In-Reply-To: References: Message-ID: this appears to work: alphabet=map (\x->x:[]) ['a'..'z'] series=alphabet++[x++y|x<-series,y<-alphabet] On Tue, Jun 16, 2009 at 8:28 PM, G??nther Schmidt wrote: > Hi guys, > > I'd like to generate an infinite list, like > > ["a", "b", "c" .. "z", "aa", "ab", "ac" .. "az", "ba", "bb", "bc" .. "bz", > "ca" ...] > > When I had set out to do this I thought, oh yeah no prob, in a heartbeat. > > Uhm. > > Help, pls! > > G?nther > > PS: I know this should be a no-brainer, sry > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090616/1be0deb0/attachment.html From gue.schmidt at web.de Tue Jun 16 21:16:54 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Tue Jun 16 21:00:26 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list In-Reply-To: References: Message-ID: Dear Ross, thanks for your post, you got it almost right, I needed something like "aa", "ab", "ac" ... It seems that Thomas has figured it out. G?nther From gue.schmidt at web.de Tue Jun 16 21:18:08 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Tue Jun 16 21:03:19 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list In-Reply-To: <71840F92-381B-44F1-9915-5C68503C9D7C@gmail.com> References: <71840F92-381B-44F1-9915-5C68503C9D7C@gmail.com> Message-ID: Hi Thomas, thanks, it seems you found it. I find it a bit embarrassing that I was unable to figure this out myself. G?nther Thomas Davie schrieb: > letterCombos = map (:[]) ['a'..'z'] ++ concatMap (\c -> map ((c++) . > (:[])) ['a'..'z']) letterCombos > > Not hugely efficient, if you generate the strings in reverse then you > can use (c:) rather than ((c++) . (:[])), but that may not be useful to > you. > > Bob > > On 17 Jun 2009, at 02:28, G??nther Schmidt wrote: > >> Hi guys, >> >> I'd like to generate an infinite list, like >> >> ["a", "b", "c" .. "z", "aa", "ab", "ac" .. "az", "ba", "bb", "bc" .. >> "bz", "ca" ...] >> >> When I had set out to do this I thought, oh yeah no prob, in a heartbeat. >> >> Uhm. >> >> Help, pls! >> >> G?nther >> >> PS: I know this should be a no-brainer, sry >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe From rmm-haskell at z.odi.ac Tue Jun 16 21:23:38 2009 From: rmm-haskell at z.odi.ac (Ross Mellgren) Date: Tue Jun 16 21:07:03 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list In-Reply-To: References: Message-ID: <59007981-27A4-44BA-AEF3-3A304F404BCA@z.odi.ac> Oh sorry about that, misread the problem. -Ross On Jun 16, 2009, at 9:16 PM, G??nther Schmidt wrote: > Dear Ross, > > thanks for your post, you got it almost right, I needed something > like "aa", "ab", "ac" ... > > It seems that Thomas has figured it out. > > G?nther > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From gue.schmidt at web.de Tue Jun 16 21:20:44 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Tue Jun 16 21:08:20 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list In-Reply-To: References: Message-ID: Hi Tom, thanks for that. I remembered reading about that in my earliest haskell days, couldn't find it again and couldn't get it right by myself either. G?nther Tom Pledger schrieb: > G??nther Schmidt web.de> writes: > >> Hi guys, >> >> I'd like to generate an infinite list, like >> >> ["a", "b", "c" .. "z", "aa", "ab", "ac" .. "az", "ba", "bb", "bc" .. >> "bz", "ca" ...] > > > If you're happy to have a "" before the "a", you can do this as a fairly cute > one-liner in a similar style to this list of Fibonacci numbers. > > fib = 0:1:[m + n | (m, n) <- zip fib (tail fib)] > > Regards, > Tom From ok at cs.otago.ac.nz Tue Jun 16 21:42:48 2009 From: ok at cs.otago.ac.nz (Richard O'Keefe) Date: Tue Jun 16 21:26:09 2009 Subject: [Haskell-cafe] Performance of functional priority queues In-Reply-To: <4a36de26.0702d00a.4ceb.2abb@mx.google.com> References: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> <3d96ac180906150240m3ee9f02ey7263a4b18a2debb3@mail.gmail.com> <4a36de26.0702d00a.4ceb.2abb@mx.google.com> Message-ID: On 16 Jun 2009, at 11:49 am, Bertram Felgenhauer wrote: > What about decreaseKey in a purely functional setting? I suppose it's > O(log n), based on the intuition of trees with limited branching > factor. > Fibonacci heaps can do it in O(1), which makes a difference for > Dijkstra's algorithm, for example. The original poster in the Erlang thread on the subject didn't ask for decreaseKey. The problem with delete and decreaseKey is that they require a way of identifying en entry _within_ a priority queue. This is easy enough to do in C or Java: just hand out pointers to the internal nodes. It's less easy in a language where nodes don't _have_ identities, such as Haskell or Erlang. The Brodal and Okasaki paper suggests using an extra dictionary data structure for this purpose, roughly doubling the size of the whole thing. From briand at aracnet.com Tue Jun 16 21:47:12 2009 From: briand at aracnet.com (brian) Date: Tue Jun 16 21:30:31 2009 Subject: [Haskell-cafe] slow code In-Reply-To: <20090616155858.GE4695@whirlpool.galois.com> References: <9621AF5D-5C87-43A6-B8A2-103109570416@aracnet.com> <00FDD473-F0DB-41F8-8410-C435CDF045C0@aracnet.com> <20090616155858.GE4695@whirlpool.galois.com> Message-ID: <83C5F868-8806-4AD4-B9B9-AB9B81C79BA5@aracnet.com> On Jun 16, 2009, at 8:58 AM, Don Stewart wrote: >> So I guess it's the show's, but I can't seem to find more efficient >> float output. >> FFI to sprintf ? yuch. > > Is your SMLNJ using lazy lists? :) > strictly speaking : no. > Try hmatrix or uvector. > uvector is _probably_ the long term answer even after I solve the double -> string problem. However, I would like to reiterate that it's the double -> string which is really the time/memory sink. I verified this by printing a simple string based on the value (to make sure the value was evaluated) and it runs fast enough for me. Is there an efficient way to output double -> binary ? I typically write my data files as binary anyway, because it's faster for graph and the like to handle them anyway. Brian From ok at cs.otago.ac.nz Tue Jun 16 22:01:53 2009 From: ok at cs.otago.ac.nz (Richard O'Keefe) Date: Tue Jun 16 21:45:12 2009 Subject: [Haskell-cafe] Need some help with an infinite list In-Reply-To: References: Message-ID: <230AED6D-F69E-4B8E-BCED-BED620722B07@cs.otago.ac.nz> On 17 Jun 2009, at 12:28 pm, G??nther Schmidt wrote: > Hi guys, > > I'd like to generate an infinite list, like > > ["a", "b", "c" .. "z", "aa", "ab", "ac" .. "az", "ba", "bb", "bc" .. > "bz", "ca" ...] > > When I had set out to do this I thought, oh yeah no prob, in a > heartbeat. Let me change this slightly. ["0","1",...,"9","00","01",..,"99","000",..."999",...] Does that provide a hint? From gue.schmidt at web.de Tue Jun 16 22:16:51 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Tue Jun 16 22:00:21 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list In-Reply-To: <59007981-27A4-44BA-AEF3-3A304F404BCA@z.odi.ac> References: <59007981-27A4-44BA-AEF3-3A304F404BCA@z.odi.ac> Message-ID: Hi Ross, no problem at all, I certainly appreciate it. G?nther From pumpkingod at gmail.com Tue Jun 16 22:21:04 2009 From: pumpkingod at gmail.com (Daniel Peebles) Date: Tue Jun 16 22:04:20 2009 Subject: [Haskell-cafe] Need some help with an infinite list In-Reply-To: <230AED6D-F69E-4B8E-BCED-BED620722B07@cs.otago.ac.nz> References: <230AED6D-F69E-4B8E-BCED-BED620722B07@cs.otago.ac.nz> Message-ID: My solution attempted to exploit this using Numeric.showIntAtBase but failed because of the lack of 0 prefixes in the numbers. If you can find a simple way to fix it without duplicating the showIntAtBase code, I'd be interested! On Tue, Jun 16, 2009 at 10:01 PM, Richard O'Keefe wrote: > > On 17 Jun 2009, at 12:28 pm, G??nther Schmidt wrote: > >> Hi guys, >> >> I'd like to generate an infinite list, like >> >> ["a", "b", "c" .. "z", "aa", "ab", "ac" .. "az", "ba", "bb", "bc" .. "bz", >> "ca" ...] >> >> When I had set out to do this I thought, oh yeah no prob, in a heartbeat. > > Let me change this slightly. > > ["0","1",...,"9","00","01",..,"99","000",..."999",...] > > Does that provide a hint? > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From gue.schmidt at web.de Tue Jun 16 22:19:58 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Tue Jun 16 22:08:21 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list In-Reply-To: <230AED6D-F69E-4B8E-BCED-BED620722B07@cs.otago.ac.nz> References: <230AED6D-F69E-4B8E-BCED-BED620722B07@cs.otago.ac.nz> Message-ID: Hi Richard, I'd have to guess here :) Maybe, what you have in mind, is: generate an infinite list with numbers from [1 ..], "map" it to base 26? G?nther Richard O'Keefe schrieb: > > On 17 Jun 2009, at 12:28 pm, G??nther Schmidt wrote: > >> Hi guys, >> >> I'd like to generate an infinite list, like >> >> ["a", "b", "c" .. "z", "aa", "ab", "ac" .. "az", "ba", "bb", "bc" .. >> "bz", "ca" ...] >> >> When I had set out to do this I thought, oh yeah no prob, in a heartbeat. > > Let me change this slightly. > > ["0","1",...,"9","00","01",..,"99","000",..."999",...] > > Does that provide a hint? From gue.schmidt at web.de Tue Jun 16 22:25:20 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Tue Jun 16 22:13:24 2009 Subject: [Haskell-cafe] Re: Performance of functional priority queues In-Reply-To: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> References: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> Message-ID: Hi Richard, just a wiiild guess on this, but anyway. Maybe Oleg has something to say on this, in particular when it comes to his domain, ie. "delimited continuations". As I said, just a wild guess. G?nther Richard O'Keefe schrieb: > There's a current thread in the Erlang mailing list about > priority queues. I'm aware of, for example, the Brodal/Okasaki > paper and the David King paper. I'm also aware of James Cook's > priority queue package in Hackage, have my own copy of Okasaki's > book, and have just spent an hour searching the web. > > One of the correspondents in that thread claims that it is > provably impossible to have an efficient priority queue implementation > without mutability. I think he's cuckoo. But I'd like to have some > numbers to back me up. > > Can anyone point me to some actual benchmark results comparing > priority queue performance *with* mutation and priority queue > performance *without* mutation, in the same functional or > mostly-functional language? From ashley at semantic.org Tue Jun 16 23:36:19 2009 From: ashley at semantic.org (Ashley Yakeley) Date: Tue Jun 16 23:19:36 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: References: <1244822326.28941.29.camel@flippa-eee> <4A35B78C.3040809@semantic.org> <1245086323.3817.2.camel@glastonbury> <1245089315.5131.5.camel@flippa-eee> <4A369677.2010500@therning.org> <4A36A31A.10504@semantic.org> <4A3827CC.50806@semantic.org> Message-ID: <4A3864B3.5020000@semantic.org> OK, the people listed here have been given the ability to create accounts: http://haskell.org/haskellwiki/?title=Special%3AListusers&group=createaccount I'm willing to hand this ability out to pretty much anyone who seems unlikely to be a spammer. To create an account, go to the login page. http://haskell.org/haskellwiki/Special:Userlogin You should see five text boxes instead of two. Enter the desired username, and the person's email, and click on the "by email" button. You do not need to enter a password. Rules for usernames are the same as rules for particle titles, so the first character cannot be a lower-case letter (actually, it will get folded to upper-case). But spaces are OK. If you want to let people know that you can do this for them, add your email address here: http://haskell.org/haskellwiki/HaskellWiki:New_accounts -- Ashley Yakeley From dagit at codersbase.com Tue Jun 16 23:46:58 2009 From: dagit at codersbase.com (Jason Dagit) Date: Tue Jun 16 23:30:16 2009 Subject: [Haskell-cafe] slow code In-Reply-To: <83C5F868-8806-4AD4-B9B9-AB9B81C79BA5@aracnet.com> References: <9621AF5D-5C87-43A6-B8A2-103109570416@aracnet.com> <00FDD473-F0DB-41F8-8410-C435CDF045C0@aracnet.com> <20090616155858.GE4695@whirlpool.galois.com> <83C5F868-8806-4AD4-B9B9-AB9B81C79BA5@aracnet.com> Message-ID: On Tue, Jun 16, 2009 at 6:47 PM, brian wrote: > > On Jun 16, 2009, at 8:58 AM, Don Stewart wrote: > > So I guess it's the show's, but I can't seem to find more efficient >>> float output. >>> FFI to sprintf ? yuch. >>> >> >> Is your SMLNJ using lazy lists? :) >> >> > strictly speaking : no. > > Try hmatrix or uvector. >> >> > uvector is _probably_ the long term answer even after I solve the double -> > string problem. > > However, I would like to reiterate that it's the double -> string which is > really the time/memory sink. I verified this by printing a simple string > based on the value (to make sure the value was evaluated) and it runs fast > enough for me. You might want to look at the source and see if you can find a faster way to convert it: http://haskell.org/ghc/docs/latest/html/libraries/base/src/GHC-Float.html#showFloat Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090616/6834a469/attachment.html From haskell at brecknell.org Wed Jun 17 00:18:23 2009 From: haskell at brecknell.org (Matthew Brecknell) Date: Wed Jun 17 00:01:43 2009 Subject: [Haskell-cafe] Need some help with an infinite list In-Reply-To: <71840F92-381B-44F1-9915-5C68503C9D7C@gmail.com> References: <71840F92-381B-44F1-9915-5C68503C9D7C@gmail.com> Message-ID: <1245212303.8651.8.camel@localhost> Thomas Davie wrote: > letterCombos = map (:[]) ['a'..'z'] ++ concatMap (\c -> map ((c++) . (: > [])) ['a'..'z']) letterCombos > > Not hugely efficient, if you generate the strings in reverse then you > can use (c:) rather than ((c++) . (:[])), but that may not be useful > to you. > > Bob I think the following version increases the sharing between the generated strings, and so might be more space-efficient for consumers which hold on to a significant number of them: number :: [a] -> [[a]] number digits = expand [[]] where expand xss = expanded ++ expand expanded where expanded = concatMap (\d -> map (d:) xss) digits binary = number ['0'..'1'] decimal = number ['0'..'9'] alpha = number ['a'..'z'] Regards, Matthew From ok at cs.otago.ac.nz Wed Jun 17 00:25:53 2009 From: ok at cs.otago.ac.nz (Richard O'Keefe) Date: Wed Jun 17 00:09:13 2009 Subject: [Haskell-cafe] Need some help with an infinite list In-Reply-To: <230AED6D-F69E-4B8E-BCED-BED620722B07@cs.otago.ac.nz> References: <230AED6D-F69E-4B8E-BCED-BED620722B07@cs.otago.ac.nz> Message-ID: On 17 Jun 2009, at 2:01 pm, Richard O'Keefe wrote: On second thoughts, let strings = "" : [pref++[last] | pref <- strings, last <- ['a'..'z']] in tail strings seems more Haskellish than the stupidly clever counting-based code I had in mind. With this it's much easier to see what it's up to. From heringtonlacey at mindspring.com Wed Jun 17 00:45:56 2009 From: heringtonlacey at mindspring.com (Dean Herington) Date: Wed Jun 17 00:29:30 2009 Subject: [Haskell-cafe] Need some help with an infinite list In-Reply-To: References: <230AED6D-F69E-4B8E-BCED-BED620722B07@cs.otago.ac.nz> Message-ID: At 4:25 PM +1200 6/17/09, Richard O'Keefe wrote: >On 17 Jun 2009, at 2:01 pm, Richard O'Keefe wrote: >On second thoughts, > > let strings = "" : [pref++[last] | pref <- strings, last <- ['a'..'z']] > in tail strings > >seems more Haskellish than the stupidly clever counting-based >code I had in mind. With this it's much easier to see what it's up to. And here's a version along similar lines that avoids (++) for greater sharing and efficiency: let sss = [""] : [ [ c:s | c <- ['a'..'z'], s <- ss ] | ss <- sss ] in concat (tail sss) From rwbarton at math.harvard.edu Wed Jun 17 01:24:07 2009 From: rwbarton at math.harvard.edu (Reid Barton) Date: Wed Jun 17 01:07:39 2009 Subject: [Haskell-cafe] Need some help with an infinite list In-Reply-To: References: Message-ID: <20090617052407.GA3397@rwbarton.mit.edu> On Wed, Jun 17, 2009 at 02:28:55AM +0200, G??nther Schmidt wrote: > Hi guys, > > I'd like to generate an infinite list, like > > ["a", "b", "c" .. "z", "aa", "ab", "ac" .. "az", "ba", "bb", "bc" .. > "bz", "ca" ...] I'm surprised everyone is giving clever recursive solutions rather than concatMap (\n -> replicateM n ['a'..'z']) [1..] Regards, Reid From caseyh at istar.ca Wed Jun 17 01:24:56 2009 From: caseyh at istar.ca (Casey Hawthorne) Date: Wed Jun 17 01:07:43 2009 Subject: [Haskell-cafe] Need some help with an infinite list In-Reply-To: References: <230AED6D-F69E-4B8E-BCED-BED620722B07@cs.otago.ac.nz> Message-ID: On Wed, 17 Jun 2009 00:45:56 -0400, you wrote: >And here's a version along similar lines that avoids (++) for greater >sharing and efficiency: > > let sss = [""] : [ [ c:s | c <- ['a'..'z'], s <- ss ] | ss <- sss ] >in concat (tail sss) Sheer genius! I just inverted it since I like to see the main idea first. letterCombos = concat (tail sss) where sss = [""] : [ [ c:s | c <- ['a'..'z'], s <- ss ] | ss <- sss ] -- Regards, Casey From vigalchin at gmail.com Wed Jun 17 01:33:53 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Wed Jun 17 01:17:09 2009 Subject: [Haskell-cafe] Android and Haskell Message-ID: <5ae4f2ba0906162233g55806575h9dd83d0c8ee702f1@mail.gmail.com> Hello, I was just reading a Linux Mag article on Android and scripting. The underlying OS is Linux? Python is one of the scripting languages. http://code.google.com/p/android-scripting/ ... Is Python one of the supported languages simply because it (I think) has JVM bindings? My bottom line question is what is preventing Haskell98 from running on "Android" if Python can? Regards, Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090617/48b4268e/attachment.html From wren at freegeek.org Wed Jun 17 02:03:33 2009 From: wren at freegeek.org (wren ng thornton) Date: Wed Jun 17 01:46:50 2009 Subject: [Haskell-cafe] Performance of functional priority queues In-Reply-To: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> References: <02FD3DFE-9454-4F0C-8459-6D78B9118301@cs.otago.ac.nz> Message-ID: <4A388735.8010506@freegeek.org> Richard O'Keefe wrote: > There's a current thread in the Erlang mailing list about > priority queues. I'm aware of, for example, the Brodal/Okasaki > paper and the David King paper. I'm also aware of James Cook's > priority queue package in Hackage, have my own copy of Okasaki's > book, and have just spent an hour searching the web. > > One of the correspondents in that thread claims that it is > provably impossible to have an efficient priority queue implementation > without mutability. I think he's cuckoo. But I'd like to have some > numbers to back me up. Sounds cuckoo to me until I see a proof otherwise. I've seen a few proof sketches indicating that immutable approaches can always be no worse than a O(log n) multiple of imperative ones (by simulating main memory with your O(log n) map of choice). Between this and the provable asymptotic optimality of skewed binomial heap prioqueues, the argument sounds untenable. Though it really comes down to what they mean by "efficient". Asymptotic complexity is the name of the game for most folks in algorithms and datastructures, but that seems not to be what they're after. Shrinking the constant factors is frequently a game that can go on forever, or rather can seldom be proved not to, so the claim seems unlikely to be meaningful in this arena either (you'd have to prove you've found the smallest possible constant factor for any immutable approach, and then find a smaller one for some mutable approach). Also proofs about constant factors beyond basic thresholds aren't useful in practice due to hardware barriers like cache size and disk access times. There's also the difference between compilers that are designed to optimize immutable patterns, vs ones which aren't. For example, in certain circumstances and with suitable annotations Clean will take the immutable approach and convert it into a mutable variant for you, thus saving on allocation/collection/cache-miss overheads while maintaining the spirit of immutability. Is compiled code like this considered "mutable" or "immutable"? It all depends on the spirit of the question. > Can anyone point me to some actual benchmark results comparing > priority queue performance *with* mutation and priority queue > performance *without* mutation, in the same functional or > mostly-functional language? I'm always curious to see datastructure benchmarks though :) -- Live well, ~wren From mle+hs at mega-nerd.com Wed Jun 17 02:31:53 2009 From: mle+hs at mega-nerd.com (Erik de Castro Lopo) Date: Wed Jun 17 02:15:18 2009 Subject: [Haskell-cafe] Android and Haskell In-Reply-To: <5ae4f2ba0906162233g55806575h9dd83d0c8ee702f1@mail.gmail.com> References: <5ae4f2ba0906162233g55806575h9dd83d0c8ee702f1@mail.gmail.com> Message-ID: <20090617163153.cd1afe7a.mle+hs@mega-nerd.com> Vasili I. Galchin wrote: > I was just reading a Linux Mag article on Android and scripting. The > underlying OS is Linux? Yes, as is the OS for the new Palm Pre. > Python is one of the scripting languages. > http://code.google.com/p/android-scripting/ ... Is Python one of the > supported languages simply because it (I think) has JVM bindings? There is something called Jython which is Python on the JVM, but I don't think its widely used in comparison to standard Python which has its own VM written on C. I would be somewhat suprised if Python on andriod was Jython rather than native Python. > My bottom > line question is what is preventing Haskell98 from running on "Android" if > Python can? Well if the android phones have a JVM then something like OpenQuark should do the trick. http://openquark.org/Open_Quark/Welcome.html Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/ From haskell at brecknell.org Wed Jun 17 02:37:31 2009 From: haskell at brecknell.org (Matthew Brecknell) Date: Wed Jun 17 02:20:51 2009 Subject: [Haskell-cafe] Need some help with an infinite list In-Reply-To: <20090617052407.GA3397@rwbarton.mit.edu> References: <20090617052407.GA3397@rwbarton.mit.edu> Message-ID: <1245220651.8651.12.camel@localhost> Reid Barton wrote: > I'm surprised everyone is giving clever recursive solutions rather than > > concatMap (\n -> replicateM n ['a'..'z']) [1..] > > Regards, > Reid Well, you've lost efficient sharing with respect to my previous solution and one other. But it's a fair call, so... tail $ concat $ iterate (map (:) ['a'..'z'] <*>) [[]] Regards, Matthew From dagit at codersbase.com Wed Jun 17 02:38:26 2009 From: dagit at codersbase.com (Jason Dagit) Date: Wed Jun 17 02:21:43 2009 Subject: [Haskell-cafe] Catering for similar operations with and without state In-Reply-To: <89bc5e540906151723g1dadc094ledb3e3ad3123e387@mail.gmail.com> References: <89bc5e540906151723g1dadc094ledb3e3ad3123e387@mail.gmail.com> Message-ID: Hi Phil, On Mon, Jun 15, 2009 at 5:23 PM, Phil wrote: > Hi, > > I'm trying to think around a problem which is causing me some difficulty in > Haskell. > > I'm representing a stateful computation using a State Transform - which > works fine. Problem is in order to add flexibility to my program I want to > performs the same operation using different techniques - most of which > require no state. > > My program at the moment is a stack of state monads/transforms. I have a > random number generator as a state monad (seed=state), feeding a Box Muller > (normal) generator implemented as a state transform (state is 'maybe' > normal, so it only spits out 1 normal at a time), which in turn feeds > another state machine. > > This all works fine, but I want to add flexibility so that I can chop and > change the Box Muller algorithm with any number of other normal generators. > Problem is most of them do not need to carry around state at all. > This leaves me with a messy solution of implementing lots of state monads > that don't actually have a state, if I want to maintain the current > paradigm. > > This strikes me as really messy - so I'm hoping someone can point me in the > direction of a more sensible approach? I'm interested in how you solve this, but I didn't see any replies yet so I thought I would toss in my thoughts. > > > Currently I have my Box Muller implemented as below - this works: > > class NormalClass myType where > generateNormal :: myType Double > This type class might be at the heart of your difficulties. I think it requires myType to have kind * -> * and it doesn't specify what the input to generateNormal should be. I also notice you're not using it later in the example code which is another warning sign. > > type BoxMullerStateT = StateT (Maybe Double) > type BoxMullerRandomStateStack = BoxMullerStateT MyRngState You used 'type' here, but I bet you want 'newtype' with the newtype deriving feature/extension. Otherwise, this nice neat stack of transformers that you have is fixed to just one instance of NormalClass, but I suspet you may have multiple ways to generateNormal that use the same stack of transformers. > > > instance NormalClass BoxMullerRandomStateStack where > generateNormal = StateT $ \s -> case s of > Just d -> return (d,Nothing) > Nothing -> do qrnBaseList <- nextRand > let (norm1,norm2) = boxMuller (head > qrnBaseList) (head $ tail qrnBaseList) > return (norm1,Just norm2) > > > But say I have another instance of my NormalClass that doesn't need to be > stateful, that is generateNormal() is a pure function. How can I represent > this without breaking my whole stack? > > I've pretty much backed myself into a corner here as my main() code expects > to evalStateT on my NormalClass: > > main = do let sumOfPayOffs = evalState normalState (1,[3,5]) -- (ranq1Init > 981110) > where > mcState = execStateT (do replicateM_ iterations mc) 0 > normalState = evalStateT mcState Nothing If it is useful to define generateNormal, then why don't you use it here? What if we go back to your NormalClass type class and redesign it? If we add a parameter to the type class which depends on the way you implement generateNormal I think we'd be most of the way there. I'm also going to remove the explicit 'Double', and let that be part of the type of 'myType'. Untested, but I think this is the syntax for using multiparameter type classes and functional dependencies: class NormalClass seed myType | myType -> seed where generateNormal :: seed -> myType type Seed = ... -- Whatever type the seed has currently instance NormalClass Seed (Maybe Double) where generateNormal seed = evalState (StateT $ \s -> case s of Just d -> return (d,Nothing) Nothing -> do qrnBaseList <- nextRand let (norm1,norm2) = boxMuller (head qrnBaseList) (head $ tail qrnBaseList) return (norm1,Just norm2)) seed -- An arbitrary 'pure' example instance NormalClass () Double where generateNormal () = 1.0 Ah, now I see a problem with this approach. You'll end up putting a newtype on the return value of generateNormal just to allow different instances. I sort of feel like the way things are designed we are assuming we have subtyping, but Haskell doesn't have that. > > If it wasn't for this I was thinking about implementing the IdentityT > transformer to provide a more elegant pass-through. > I've never tried designing my own Monad from scratch but this crossed my > mind as another possibillity - i.e. a Monad that either has a state of maybe > double, or has no state at all? I have a feeling I'd just 'return' the pure computations into the state monad. My example code above seems weird and heavy weight to me. I'd love to see what you figure you. Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090617/360ba5bb/attachment.html From toby.hutton at gmail.com Wed Jun 17 02:43:18 2009 From: toby.hutton at gmail.com (Toby Hutton) Date: Wed Jun 17 02:26:53 2009 Subject: [Haskell-cafe] Android and Haskell In-Reply-To: <20090617163153.cd1afe7a.mle+hs@mega-nerd.com> References: <5ae4f2ba0906162233g55806575h9dd83d0c8ee702f1@mail.gmail.com> <20090617163153.cd1afe7a.mle+hs@mega-nerd.com> Message-ID: <711894390906162343o1aec6aedq1780f5ca0c6f3d3b@mail.gmail.com> On Wed, Jun 17, 2009 at 4:31 PM, Erik de Castro Lopo > wrote: > > Well if the android phones have a JVM then something like OpenQuark > should do the trick. > The Android phones actually have a different VM which essentially takes compiled/translated java bytecode. http://en.wikipedia.org/wiki/Dalvik_virtual_machine -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090617/e63670d2/attachment.html From magnus at therning.org Wed Jun 17 03:02:24 2009 From: magnus at therning.org (Magnus Therning) Date: Wed Jun 17 02:45:40 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: <4A3864B3.5020000@semantic.org> References: <1244822326.28941.29.camel@flippa-eee> <1245086323.3817.2.camel@glastonbury> <1245089315.5131.5.camel@flippa-eee> <4A369677.2010500@therning.org> <4A36A31A.10504@semantic.org> <4A3827CC.50806@semantic.org> <4A3864B3.5020000@semantic.org> Message-ID: On Wed, Jun 17, 2009 at 4:36 AM, Ashley Yakeley wrote: > OK, the people listed here have been given the ability to create accounts: > > http://haskell.org/haskellwiki/?title=Special%3AListusers&group=createaccount Thanks! > If you want to let people know that you can do this for them, add your email > address here: > > http://haskell.org/haskellwiki/HaskellWiki:New_accounts I've added my name on that page (and re-arranged it a little). /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe From wrwills at gmail.com Wed Jun 17 03:34:06 2009 From: wrwills at gmail.com (Robert Wills) Date: Wed Jun 17 03:17:24 2009 Subject: [Haskell-cafe] Android and Haskell In-Reply-To: <711894390906162343o1aec6aedq1780f5ca0c6f3d3b@mail.gmail.com> References: <5ae4f2ba0906162233g55806575h9dd83d0c8ee702f1@mail.gmail.com> <20090617163153.cd1afe7a.mle+hs@mega-nerd.com> <711894390906162343o1aec6aedq1780f5ca0c6f3d3b@mail.gmail.com> Message-ID: <4A389C6E.5020100@gmail.com> Right now you're best bet if you want to program Android in a functional style is to use Scala which has an Android target. > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From ketil at malde.org Wed Jun 17 03:38:56 2009 From: ketil at malde.org (Ketil Malde) Date: Wed Jun 17 03:22:14 2009 Subject: [Haskell-cafe] slow code In-Reply-To: <83C5F868-8806-4AD4-B9B9-AB9B81C79BA5@aracnet.com> (brian's message of "Tue\, 16 Jun 2009 18\:47\:12 -0700") References: <9621AF5D-5C87-43A6-B8A2-103109570416@aracnet.com> <00FDD473-F0DB-41F8-8410-C435CDF045C0@aracnet.com> <20090616155858.GE4695@whirlpool.galois.com> <83C5F868-8806-4AD4-B9B9-AB9B81C79BA5@aracnet.com> Message-ID: <87bpon8g33.fsf@malde.org> brian writes: > However, I would like to reiterate that it's the double -> string > which is really the time/memory sink. I verified this by printing a > simple string based on the value (to make sure the value was > evaluated) and it runs fast enough for me. > > Is there an efficient way to output double -> binary ? Not as far as I know. I had the same problem, and ended up building a array of float representations: farray :: Array Int ByteString farray = listArray (0,9999) [B.pack (showFFloat (Just 2) i "") | i <- [0,0.01..99.99::Double]] and using a lookup function to show the floats: fi :: Int -> ByteString fi f | f <= 9999 && f >= 0 = farray!f | otherwise = error ("Can't show a value of "++show f) This works for me, since I have a very limited range of Doubles to deal with (stored as fixed-precision Ints). Still, a fast and general way to output primitive data types would be quite welcome. -k -- If I haven't seen further, it is by standing in the footprints of giants From marlowsd at gmail.com Wed Jun 17 03:55:15 2009 From: marlowsd at gmail.com (Simon Marlow) Date: Wed Jun 17 03:38:34 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <1829193364.20090617001945@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <1829193364.20090617001945@gmail.com> Message-ID: <4A38A163.5070707@gmail.com> On 16/06/2009 21:19, Bulat Ziganshin wrote: > Hello Simon, > > Tuesday, June 16, 2009, 5:02:43 PM, you wrote: > >> I don't know how getArgs fits in here - should we be decoding argv using >> the ACP? > > myGetArgs = do > alloca $ \p_argc -> do > p_argv_w<- commandLineToArgvW getCommandLineW p_argc > argc<- peek p_argc > argv_w<- peekArray (i argc) p_argv_w > mapM peekTString argv_w>>= return.tail > > foreign import stdcall unsafe "windows.h GetCommandLineW" > getCommandLineW :: LPTSTR > > foreign import stdcall unsafe "windows.h CommandLineToArgvW" > commandLineToArgvW :: LPCWSTR -> Ptr CInt -> IO (Ptr LPWSTR) Right, so getArgs is already fine. Cheers, Simon From marlowsd at gmail.com Wed Jun 17 04:01:11 2009 From: marlowsd at gmail.com (Simon Marlow) Date: Wed Jun 17 03:44:31 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <44614945.20090616200641@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <1893812247.20090616175630@gmail.com> <4A37BAAF.90600@gmail.com> <588951384.20090616194434@gmail.com> <4A37C01A.10905@gmail.com> <44614945.20090616200641@gmail.com> Message-ID: <4A38A2C7.90907@gmail.com> On 16/06/2009 17:06, Bulat Ziganshin wrote: > Hello Simon, > > Tuesday, June 16, 2009, 7:54:02 PM, you wrote: > >> In fact there's not a lot left to convert in System.Directory, as you'll >> see if you look at the code. Feel like helping? > > these functions used there are ACP-only: > > c_stat c_chmod System.Win32.getFullPathName c_SearchPath c_SHGetFolderPath Yes, except for getFullPathName: foreign import stdcall unsafe "GetFullPathNameW" c_GetFullPathName :: LPCTSTR -> DWORD -> LPTSTR -> Ptr LPTSTR -> IO DWORD > plus may be some more functions from System.Win32 package - i don't > looked into it System.Win32 is using the wide-char APIs exclusively (ok, I haven't checked, but I don't know of any System.Win32 functions still using narrow strings). So as you can see, there's not much left to do. I'll fix openFile. Cheers, Simon From gale at sefer.org Wed Jun 17 04:38:23 2009 From: gale at sefer.org (Yitzchak Gale) Date: Wed Jun 17 04:22:01 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> Message-ID: <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> Thomas Davie wrote: > Not at all, as discussed, there are legitimate uses for a > lazy sum, and haskell is a lazy language by default. Haskell is lazy by default, and we have found that to be a big win in most cases. So we don't need to be embarrassed to use strictness when that is the right thing to do. While there are indeed certain very rare situations in which you want foldr or foldl for sum, they are both joltingly wrong as the default for typical usage. In practice, I find this to be a small annoyance that occurs so often that it becomes a major one. Can we please fix it already? Let it be noted that this discussion also applies to product. Thanks, Yitz From bulat.ziganshin at gmail.com Wed Jun 17 04:38:31 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Wed Jun 17 04:23:46 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A38A163.5070707@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <1829193364.20090617001945@gmail.com> <4A38A163.5070707@gmail.com> Message-ID: <964540996.20090617123831@gmail.com> Hello Simon, Wednesday, June 17, 2009, 11:55:15 AM, you wrote: > Right, so getArgs is already fine. it's what i've found in Jun15 sources: #ifdef __GLASGOW_HASKELL__ getArgs :: IO [String] getArgs = alloca $ \ p_argc -> alloca $ \ p_argv -> do getProgArgv p_argc p_argv p <- fromIntegral `liftM` peek p_argc argv <- peek p_argv peekArray (p - 1) (advancePtr argv 1) >>= mapM peekCString foreign import ccall unsafe "getProgArgv" getProgArgv :: Ptr CInt -> Ptr (Ptr CString) -> IO () it uses peekCString so by any means it cannot produce unicode chars -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From marlowsd at gmail.com Wed Jun 17 04:46:49 2009 From: marlowsd at gmail.com (Simon Marlow) Date: Wed Jun 17 04:30:08 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <964540996.20090617123831@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <1829193364.20090617001945@gmail.com> <4A38A163.5070707@gmail.com> <964540996.20090617123831@gmail.com> Message-ID: <4A38AD79.3000906@gmail.com> On 17/06/2009 09:38, Bulat Ziganshin wrote: > Hello Simon, > > Wednesday, June 17, 2009, 11:55:15 AM, you wrote: > >> Right, so getArgs is already fine. > > it's what i've found in Jun15 sources: > > #ifdef __GLASGOW_HASKELL__ > getArgs :: IO [String] > getArgs = > alloca $ \ p_argc -> > alloca $ \ p_argv -> do > getProgArgv p_argc p_argv > p<- fromIntegral `liftM` peek p_argc > argv<- peek p_argv > peekArray (p - 1) (advancePtr argv 1)>>= mapM peekCString > > > foreign import ccall unsafe "getProgArgv" > getProgArgv :: Ptr CInt -> Ptr (Ptr CString) -> IO () > > > it uses peekCString so by any means it cannot produce unicode chars I see, so you were previously quoting code from some other source. Where did the GetCommandLineW version come from? Do you know of any issues that would prevent us using it in GHC? Cheers, Simon From bulat.ziganshin at gmail.com Wed Jun 17 04:43:33 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Wed Jun 17 04:33:46 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A38A2C7.90907@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <1893812247.20090616175630@gmail.com> <4A37BAAF.90600@gmail.com> <588951384.20090616194434@gmail.com> <4A37C01A.10905@gmail.com> <44614945.20090616200641@gmail.com> <4A38A2C7.90907@gmail.com> Message-ID: <856191522.20090617124333@gmail.com> Hello Simon, Wednesday, June 17, 2009, 12:01:11 PM, you wrote: > foreign import stdcall unsafe "GetFullPathNameW" > c_GetFullPathName :: LPCTSTR -> DWORD -> LPTSTR -> Ptr LPTSTR -> IO DWORD you are right, i was troubled by unused GetFullPathNameA import in System.Directory: #if defined(mingw32_HOST_OS) foreign import stdcall unsafe "GetFullPathNameA" c_GetFullPathName :: CString -> CInt -> CString -> Ptr CString -> IO CInt #else foreign import ccall unsafe "realpath" c_realpath :: CString -> CString -> IO CString #endif > So as you can see, there's not much left to do. I'll fix openFile. c_stat is widely used here and there. it may be that half of System.Directory functions is broken due to direct or indirect calls to this function -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From bulat.ziganshin at gmail.com Wed Jun 17 04:52:52 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Wed Jun 17 04:36:16 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A38AD79.3000906@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <1829193364.20090617001945@gmail.com> <4A38A163.5070707@gmail.com> <964540996.20090617123831@gmail.com> <4A38AD79.3000906@gmail.com> Message-ID: <1599323923.20090617125252@gmail.com> Hello Simon, Wednesday, June 17, 2009, 12:46:49 PM, you wrote: > I see, so you were previously quoting code from some other source. from my program > Where did the GetCommandLineW version come from? Do you know of any > issues that would prevent us using it in GHC? it should be as fine as any other *W calls. the only thing is that we may prefer to include in into Win32 package as other routines and then call from there -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From lemming at henning-thielemann.de Wed Jun 17 05:17:12 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Wed Jun 17 05:00:29 2009 Subject: [Haskell-cafe] Need some help with an infinite list In-Reply-To: References: <230AED6D-F69E-4B8E-BCED-BED620722B07@cs.otago.ac.nz> Message-ID: On Wed, 17 Jun 2009, Richard O'Keefe wrote: > On 17 Jun 2009, at 2:01 pm, Richard O'Keefe wrote: > On second thoughts, > > let strings = "" : [pref++[last] | pref <- strings, last <- ['a'..'z']] > in tail strings last:pref instead of pref++[last] should do more sharing. You can also write it this way: let strings = "" : Monad.liftM2 (flip (:)) strings ['a'..'z'] in tail strings From DekuDekuplex at Yahoo.com Wed Jun 17 05:19:45 2009 From: DekuDekuplex at Yahoo.com (Benjamin L.Russell) Date: Wed Jun 17 05:03:14 2009 Subject: [Haskell-cafe] (fwd) Haskell logo fail Message-ID: On Tue, 16 Jun 2009 14:06:42 -0700 (PDT), in comp.lang.haskell Robert Hicks wrote: >http://blog.plover.com/prog/haskell/logo.html >From the site referenced at the above-mentioned URL: >Tue, 16 Jun 2009 > >Haskell logo fail >The Haskell folks have chosen a new logo. > > > > > >ouch The two logos do look disturbingly similar.... -- Benjamin L. Russell -- Benjamin L. Russell / DekuDekuplex at Yahoo dot com http://dekudekuplex.wordpress.com/ Translator/Interpreter / Mobile: +011 81 80-3603-6725 "Furuike ya, kawazu tobikomu mizu no oto." -- Matsuo Basho^ From lemming at henning-thielemann.de Wed Jun 17 05:20:18 2009 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Wed Jun 17 05:03:47 2009 Subject: [Haskell-cafe] Need some help with an infinite list In-Reply-To: <1245220651.8651.12.camel@localhost> References: <20090617052407.GA3397@rwbarton.mit.edu> <1245220651.8651.12.camel@localhost> Message-ID: On Wed, 17 Jun 2009, Matthew Brecknell wrote: > Reid Barton wrote: >> I'm surprised everyone is giving clever recursive solutions rather than >> >> concatMap (\n -> replicateM n ['a'..'z']) [1..] >> >> Regards, >> Reid > > Well, you've lost efficient sharing with respect to my previous solution > and one other. > > But it's a fair call, so... > > tail $ concat $ iterate (map (:) ['a'..'z'] <*>) [[]] cool From martijn at van.steenbergen.nl Wed Jun 17 05:29:07 2009 From: martijn at van.steenbergen.nl (Martijn van Steenbergen) Date: Wed Jun 17 05:12:27 2009 Subject: [Haskell-cafe] (fwd) Haskell logo fail In-Reply-To: References: Message-ID: <4A38B763.7080309@van.steenbergen.nl> Benjamin L.Russell wrote: >> >> >> >> >> ouch > > The two logos do look disturbingly similar.... This is nothing new. From [1]: > Amtrak changed their logo in 2000; the old logo looked like >>=. Martijn. [1] http://www.mail-archive.com/haskell-cafe@haskell.org/msg56376.html From patai_gergely at fastmail.fm Wed Jun 17 05:56:22 2009 From: patai_gergely at fastmail.fm (Patai Gergely) Date: Wed Jun 17 05:39:40 2009 Subject: [Haskell-cafe] Which windowing toolkit to use? Message-ID: <1245232582.7315.1320797515@webmail.messagingengine.com> Hi all, I intend to start coding the UI of the heap profiling toolkit I'm working on [1] soon. I'd be happy to get some advice on choosing the right windowing toolkit for this task. The main requirements are: - portability and native look & feel if possible - easy to distribute executables under Windows - relatively slow code rot - sane interface that doesn't need wild workarounds even if what I'm doing is not trivial or elementary - trouble-free source installation in case someone wants to contribute As I see, at the moment there's no serious alternative besides GTK and wx, so my question is which do you think is better suited to this task? I have absolutely no development experience with GTK, and while I used a bit of wx in the past (in C++), I'm not really familiar with it either, especially not the Haskell bindings. I noticed that installing the wx binding with user rights doesn't seem to work directly from hackage (doesn't pass --user to ghc-pkg?), but it looks like a problem that can be solved with some hand editing. I'm a bit more afraid of setting up a development environment under Windows; is there any major pain involved with either of these libraries if I use MinGW? And how about their interface? Is there any significant difference? I'd especially like to hear the opinion of someone who's reasonably familiar with both. Thanks, Gergely [1] http://code.google.com/p/hp2any/ -- http://www.fastmail.fm - Or how I learned to stop worrying and love email again From sebf at informatik.uni-kiel.de Wed Jun 17 06:13:11 2009 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Wed Jun 17 05:56:32 2009 Subject: [Haskell-cafe] Re: [Haskell] ANN: haskell-src-exts 1.0.0 rc1 (aka 0.5.2) In-Reply-To: References: Message-ID: <38E6B5B2-8590-4400-8AD3-178C8411B867@informatik.uni-kiel.de> On Jun 17, 2009, at 12:43 AM, Niklas Broberg wrote: > Testing it is > really easy, four simple steps: > >> cabal install haskell-src-exts > [...] >> ghci > [...] > Prelude> :m Language.Haskell.Exts > Prelude Language.Haskell.Exts> parseFile "YourFileHere.(l)hs" This script may even simplify testing of large code bases: ------- #! /usr/bin/env runhaskell > import System > import System.IO > import Data.Char > import Language.Haskell.Exts > > import Prelude hiding ( catch ) > import Control.Exception ( catch, SomeException ) > > main = getArgs >>= mapM_ parse > where parse file = do hSetBuffering stdout NoBuffering > putStr $ file ++ ": " > catch (parseFile file >>= putStr . check) $ > \e -> print (e :: SomeException) > where check (ParseOk _) = replicate (2+length file) '\b' > check (ParseFailed loc msg) = unlines [err] > where err = msg ++ " at " ++ > show (srcLine loc) ++ ":" ++ > show (srcColumn loc) ------- After making it executable you can run it as shell script and pass names of Haskell files -- (something like) this will check all Haskell files (literate or not) in your home directory: find ~ -name "*hs" | xargs parse-haskell.lhs Cheers, Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From stefan at cs.uu.nl Wed Jun 17 06:31:28 2009 From: stefan at cs.uu.nl (Stefan Holdermans) Date: Wed Jun 17 06:14:46 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? In-Reply-To: References: Message-ID: <57A134DD-CF18-4502-AC0D-C7B7265576AD@cs.uu.nl> Dear Paul, This thread as well as your blog post is very interesting. Hopefully I can add something more or less valuable to it. On your blog, you mention that your scheme for run-time strictness analysis doesn't work out because it'll have you force a function first before you can find out about its strictness. I guess this can be easily overcome by separating the function from the strictness information it carries. One way to do this, would be by storing strictness information in the type of a function. Actually, this is exactly what type-based approaches to strictness analyses do. So, for example, an extended type of the function const, const :: a -> b -> a const x y = x could read a -> {S} -> b ->{L} a Here, we have annotated the function-space constructor (->) with information about whether the corresponding function is strict or lazy in its argument. Indeed, const is lazy in its first argument and lazy in its second. (Note that this is very simple take on storing strictness information in types: there is plenty more to say about it, but I will refrain from that.) An annotated type like the one above can be easily inferred by a strictness analyser. But what exactly is type inference? Well, one way to look at it is a means to reconstruct typing information that was left out from the program. For example, if we infer the type a -> b -> a for the const function in Haskell, we are effectively completing the definition of const with explicit type information. This information can then be stored in the program. Using Java-like syntax: const (x :: a) (y :: b) = x So, now const takes two extra arguments, both of which are types rather than values. When, calling a polymorphic function, type inference then computes the type arguments for a specific instantiation of the polymorphic function: const 2 'x' becomes const 2 'x' While typing information can proof valuable to have around at compile type, we don't actually want types to be passed around at run time. Luckily, in Haskell no run-time decisions can be made based on these type arguments, so all these extra abstractions and applications can be erased when generating code for a program. Pretty much the same holds for the strictness annotations that are inferred by a strictness analyser. Inferring strictness can be thought of as decorating the program. For instance, for const we get something like: const (x :: a{S}) (y :: b{L}) = x where a {S} indicates strictness and {L} laziness. Viewing strictness annotations as types, a natural step is to allow functions to be polymorphic in their strictness annotations as well. This is especially useful for higher-order functions. The function apply, for example, apply :: (a -> b) -> a -> b apply f x = f x is supposed to work on both strict and lazy functions. Moreover, depending on whether we pass it a strict or a lazy function as its first argument, it becomes, respectively, strict or lazy in its second argument. This insight can be captured quite nicely by means of a type that is polymorphic in its strictness annotations: (a ->{i} b) ->{S} ->{i} b Here, i is a strictness variable that is to be instantiated with either S or L. Decorating the definition of apply may now yield something like apply {i} (f :: (a ->{i} b){S}) (x :: a{i}) Of course, just as with ordinary types, strictness annotations don't have to be passed around at run-time: they can be erased from the program and all that are made based on strictness information can then be made at compile time. But what if we don't erase these annotations? Then we can use strictness information to participate in run-time decisions as well--- just as you proposed. Let's explore that idea. Performing strictness analysis on foldl, foldl :: (b -> a -> b) -> b -> [a] -> b foldl f e [] = e foldl f e (x : xs) = foldl f (f e x) xs we find the annotated type (b ->{i} ->{j} b) ->{L} b ->{i} [a] ->{S} -> b Indeed, whether foldl is strict in its second argument depends on wether its first argument is strict in its own first argument. Let's decorate the definition of foldl accordingly: foldl {i} {j} (f :: (b ->{i} ->{j} b){L}) (e :: b{i}) (l :: [a]{S}) = case l of [] -> e x : xs -> foldl {i} {j} f (f e x) xs Allright, that's messy, but bear with me. (At this point, we could erase the type arguments and only keep the strictness arguments for we only want the latter to play a role at run time, but let's keep them both, just to be uniform.) Now, let's apply the foldl to (+), 0, and [1 .. 1000000] assuming that (+) is strict in both its arguments and specialised to Int, (+) :: Int ->{S} Int ->{S} Int and let's pass in the arguments in three steps. First we pass in the type arguments: foldl :: (Int ->{i} Int ->{j} Int) ->{L} Int ->{i} [Int] ->{S} Int Then the strictness arguments: foldl :: (Int ->{S} ->Int ->{S} Int) ->{L} Int - >{S} [Int] ->{S} Int Now we have obtained a specialised version of foldl that is lazy in its first argument and strict in its second and third argument! When passing in the remaining three arguments we can thus indeed evaluate the second argument before we pass it to foldl: foldl (+) (0) [1 .. 1000000] Moreover, this can be done for each recursive call as well, effectively having the computation require constant space. So, the on strictness information depending decision that is to made here, is to apply functions strictly or lazily. Funnily, if we are willing to do the static part of the strictness analysis by hand, we can already experiment a bit with this scheme in Haskell. (I've attached the source code.) First, let us abstract from function types annotated with S or L and introduce a type class: infixl 9 # class Fun f where lam :: (a -> b) -> f a b (#) :: f a b -> (a -> b) That is, functions are constructed by means of the method lam and applied (destructed) by means of (#). Haskell's built-in lazy function space (->) provides a natural implementation of the class: instance Fun (->) where lam = id (#) = ($) In addition, we provide a strict function-space constructor (:->): newtype a :-> b = S {unS :: a -> b} instance Fun (:->) where lam = S (#) = \f x -> unS f $! x Now we can have a "hand-annotated" version of foldl: foldl :: (Fun i, Fun j) => i b (j a b) -> i b ([a] :-> b) foldl = lam $ \f -> lam $ \e -> lam $ \l -> case l of [] -> e x : xs -> foldl # f # (f # e # x) # xs Note how the type arguments i and j play the roles of the strictness annotations from the explanation above. Furthermore we have replaced Haskell's lambda abstraction by means of abstraction through lam and Haskell's function application by application through (#). Apart from that, this is just your ordinary foldl. Well... :-) What's important to note is that the transformation from the "normal" definition of foldl to this annotated beast could be performed at compile time by a strictness analyser. Now, let's try it out. Say we have two versions of addition on integers: a lazy one (lplus) and a strict one (splus). Note the types: lplus :: Int -> Int -> Int lplus = (+) splus :: Int :-> Int :-> Int splus = lam $ \m -> lam $ \n -> ((+) $! m) $! n There we go: *Main> foldl # lplus # 0 # [1 .. 1000000] *** Exception: stack overflow *Main> foldl # splus # 0 # [1 .. 1000000] 1784293664 Isn't that neat? Of course, whether this scheme would work out in practice depends on whether the cost of lazy evaluation really outweighs the cost of passing around strictness information. I'm not so sure, but I would be interested to see the results of experiments with this idea. An important factor seems to be how much strictness information that is passed around in a naive implementation of this scheme can be eliminated by "normal" compiler optimisations. Well, just my two cents. :-) Cheers, Stefan -------------- next part -------------- A non-text attachment was scrubbed... Name: RuntimeSA.hs Type: application/octet-stream Size: 610 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090617/710b89ec/RuntimeSA-0001.obj -------------- next part -------------- From agocorona at gmail.com Wed Jun 17 06:32:21 2009 From: agocorona at gmail.com (Alberto G. Corona ) Date: Wed Jun 17 06:15:38 2009 Subject: [Haskell-cafe] Which windowing toolkit to use? In-Reply-To: <1245232582.7315.1320797515@webmail.messagingengine.com> References: <1245232582.7315.1320797515@webmail.messagingengine.com> Message-ID: Web - HTML 2009/6/17 Patai Gergely > Hi all, > > I intend to start coding the UI of the heap profiling toolkit I'm > working on [1] soon. I'd be happy to get some advice on choosing the > right windowing toolkit for this task. The main requirements are: > > - portability and native look & feel if possible > - easy to distribute executables under Windows > - relatively slow code rot > - sane interface that doesn't need wild workarounds even if what I'm > doing is not trivial or elementary > - trouble-free source installation in case someone wants to contribute > > As I see, at the moment there's no serious alternative besides GTK and > wx, so my question is which do you think is better suited to this task? > I have absolutely no development experience with GTK, and while I used a > bit of wx in the past (in C++), I'm not really familiar with it either, > especially not the Haskell bindings. I noticed that installing the wx > binding with user rights doesn't seem to work directly from hackage > (doesn't pass --user to ghc-pkg?), but it looks like a problem that can > be solved with some hand editing. I'm a bit more afraid of setting up a > development environment under Windows; is there any major pain involved > with either of these libraries if I use MinGW? > > And how about their interface? Is there any significant difference? I'd > especially like to hear the opinion of someone who's reasonably familiar > with both. > > Thanks, > > Gergely > > [1] http://code.google.com/p/hp2any/ > > -- > http://www.fastmail.fm - Or how I learned to stop worrying and > love email again > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090617/2937610a/attachment.html From magnus at therning.org Wed Jun 17 06:39:55 2009 From: magnus at therning.org (Magnus Therning) Date: Wed Jun 17 06:23:14 2009 Subject: [Haskell-cafe] Which windowing toolkit to use? In-Reply-To: References: <1245232582.7315.1320797515@webmail.messagingengine.com> Message-ID: 2009/6/17 Alberto G. Corona : > Web - HTML I'd agree with that. It would be really nice for X-platform. Maybe it's possible to use JQuery (or Flapjax) to get some nice dynamic/interacitivity? /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe From noteed at gmail.com Wed Jun 17 06:57:14 2009 From: noteed at gmail.com (minh thu) Date: Wed Jun 17 06:40:49 2009 Subject: [Haskell-cafe] Which windowing toolkit to use? In-Reply-To: References: <1245232582.7315.1320797515@webmail.messagingengine.com> Message-ID: <40a414c20906170357u39aa9b2byadfd7ec0da320cd1@mail.gmail.com> 2009/6/17 Magnus Therning : > 2009/6/17 Alberto G. Corona : >> Web - HTML > > I'd agree with that. It would be really nice for X-platform. Maybe > it's possible to use JQuery (or Flapjax) to get some nice > dynamic/interacitivity? Does someone know if it possible to make an application which embed webkit with: - webkit used for rendering and running javascript - javascript function calling haskell code ? Cheers, Thu From niklas.broberg at gmail.com Wed Jun 17 07:00:33 2009 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Wed Jun 17 06:43:48 2009 Subject: [Haskell-cafe] Re: [Haskell] ANN: haskell-src-exts 1.0.0 rc1 (aka 0.5.2) In-Reply-To: <7D9668D5-949B-4AF0-A4E8-B00FAA6B0441@sebfisch.de> References: <7D9668D5-949B-4AF0-A4E8-B00FAA6B0441@sebfisch.de> Message-ID: Hi Sebastian, > This script may even simplify testing of large code bases: Thanks a lot, very useful! I'll add that to the darcs repository if you don't mind. :-) Cheers, /Niklas From hjgtuyl at chello.nl Wed Jun 17 07:07:41 2009 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Wed Jun 17 06:50:41 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> Message-ID: On Wed, 17 Jun 2009 10:38:23 +0200, Yitzchak Gale wrote: > > While there are indeed certain very rare situations in which > you want foldr or foldl for sum, they are both joltingly wrong > as the default for typical usage. > > In practice, I find this to be a small annoyance that occurs > so often that it becomes a major one. Can we please fix it > already? > > Let it be noted that this discussion also applies to product. > > Thanks, > Yitz I have done some research on functions in the base libraries, whether they can handle large lists; I didn't check them all, because there are so many of them. sum and product are certainly not the only ones having problems. For example: Hugs> reverse [1 .. 999999] ERROR - C stack overflow An improved reverse function: reverse' = foldl' (flip (:)) [] There is no need for reverse to be lazy, so this one could replace the original one. reverse' is not too strict: Data.List> let reverse' = foldl' (flip (:)) [] in head $ reverse' [undefined, 1] 1 Some of the other functions that have problems with large lists are: foldM maximum minimum scanl scanr scanr1 iterate take (in GHCi, not in Hugs) drop (in GHCi, not in Hugs) splitAt (in GHCi, not in Hugs) inits By the way, sum and product are implemented with foldl' in Hugs. -- Met vriendelijke groet, Henk-Jan van Tuyl -- http://functor.bamikanarie.com http://Van.Tuyl.eu/ -- From bulat.ziganshin at gmail.com Wed Jun 17 07:15:22 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Wed Jun 17 07:06:33 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> Message-ID: <305200659.20090617151522@gmail.com> Hello Henk-Jan, Wednesday, June 17, 2009, 3:07:41 PM, you wrote: > I have done some research on functions in the base libraries, whether they > can handle large lists long time ago i had problems with filterM, may be it's still fails -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From max.rabkin at gmail.com Wed Jun 17 07:25:32 2009 From: max.rabkin at gmail.com (Max Rabkin) Date: Wed Jun 17 07:09:07 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> Message-ID: On Wed, Jun 17, 2009 at 1:07 PM, Henk-Jan van Tuyl wrote: > On Wed, 17 Jun 2009 10:38:23 +0200, Yitzchak Gale wrote: > An improved reverse function: > ? ?reverse' = foldl' (flip (:)) [] > There is no need for reverse to be lazy, so this one could replace the > original one. > reverse' is not too strict: > ? ?Data.List> let reverse' = foldl' (flip (:)) [] in head $ reverse' > [undefined, 1] > ? ?1 Since reverse' is polymorphic in the type of list elements, the only way it could be strict in the *elements* is if it applied seq to them. --Max From gue.schmidt at web.de Wed Jun 17 07:30:59 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Wed Jun 17 07:14:31 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list - Ouch In-Reply-To: References: Message-ID: Hi all, you have come up with so many solutions it's embarrassing to admit that I didn't come up with even one. G?nther G??nther Schmidt schrieb: > Hi guys, > > I'd like to generate an infinite list, like > > ["a", "b", "c" .. "z", "aa", "ab", "ac" .. "az", "ba", "bb", "bc" .. > "bz", "ca" ...] > > When I had set out to do this I thought, oh yeah no prob, in a heartbeat. > > Uhm. > > Help, pls! > > G?nther > > PS: I know this should be a no-brainer, sry From gale at sefer.org Wed Jun 17 07:32:40 2009 From: gale at sefer.org (Yitzchak Gale) Date: Wed Jun 17 07:16:16 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> Message-ID: <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> Henk-Jan van Tuyl wrote: > reverse > maximum > minimum Oh yes, please fix those also! > scanl > scanr > scanr1 > iterate > take > drop > splitAt > inits Hmm, I use those all the time with large lists. They are lazy as expected, and seem to work fine. Do you have examples of problems with them? > foldM > fliterM (Bulat) No opinion, I hardly use those. Thanks, Yitz From flippa at flippac.org Wed Jun 17 07:54:31 2009 From: flippa at flippac.org (Philippa Cowderoy) Date: Wed Jun 17 07:37:55 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: References: <1244822326.28941.29.camel@flippa-eee> <4A35B78C.3040809@semantic.org> <1245086323.3817.2.camel@glastonbury> <1245089315.5131.5.camel@flippa-eee> <4A369677.2010500@therning.org> <4A36A31A.10504@semantic.org> <4A3827CC.50806@semantic.org> Message-ID: <1245239671.5131.835.camel@flippa-eee> On Tue, 2009-06-16 at 19:57 -0400, Gwern Branwen wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA512 > > On Tue, Jun 16, 2009 at 7:16 PM, Ashley Yakeley wrote: > > Anyone else? Gwern? Philippa? > > As usual, I am User:Gwern. > > On the side-topic of a mailing list - I really think that is too > heavy-weight. We want people to create a login (for the ML) and go > through the ML, just to get wiki access? > Who said anything about creating mailing list logins? Probably the easiest-for-user thing us a form that sends the mail for them. -- Philippa Cowderoy From patai_gergely at fastmail.fm Wed Jun 17 08:12:56 2009 From: patai_gergely at fastmail.fm (Patai Gergely) Date: Wed Jun 17 07:56:11 2009 Subject: [Haskell-cafe] Which windowing toolkit to use? In-Reply-To: References: <1245232582.7315.1320797515@webmail.messagingengine.com> Message-ID: <1245240776.4282.1320818147@webmail.messagingengine.com> > > Web - HTML > > I'd agree with that. It would be really nice for X-platform. Maybe > it's possible to use JQuery (or Flapjax) to get some nice > dynamic/interacitivity? I'm not sure if a web interface is really a good fit here, but I'll think about it. Gergely -- http://www.fastmail.fm - Access all of your messages and folders wherever you are From gale at sefer.org Wed Jun 17 08:21:07 2009 From: gale at sefer.org (Yitzchak Gale) Date: Wed Jun 17 08:04:42 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A3797F3.2040707@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> Message-ID: <2608b8a80906170521k70ec3269k992b0db1fca4e5ec@mail.gmail.com> I wrote: >> I think the most important use cases that should not break are: >> >> o open/read/write a FilePath from getArgs >> o open/read/write a FilePath from getDirectoryContents Simon Marlow wrote: > The following cases are currently broken: > > ?* Calling openFile on a literal Unicode FilePath (note, not > ? ACP-encoded, just Unicode). > > ?* Reading a Unicode FilePath from a text file and then calling > ? openFile on it > > I propose to fix these (on Windows). ?It will mean that your second case > above will be broken, until someone fixes getDirectoryContents. Why only on Windows? > I don't know how getArgs fits in here - should we be decoding argv using the > ACP? And why not also on Unix? On any platform, the expected behavior should be that you type a file path at the command line, read it using getArgs, and open the file using that. For comparison, Python works that way, even though the variable is called "argv" there. The current behavior on Unix of returning, say, UTF-8 encoding characters in a String as if they were individual Unicode characters, is queer. Given your fantastic work so far to rid System.IO of those kinds of oddities, perhaps now is the time to finish the job. If you think we really need to provide access to the raw argv bytes, we could add another platform-independent function that does that. Thanks, Yitz From agocorona at gmail.com Wed Jun 17 08:23:07 2009 From: agocorona at gmail.com (Alberto G. Corona ) Date: Wed Jun 17 08:06:23 2009 Subject: [Haskell-cafe] Which windowing toolkit to use? In-Reply-To: <40a414c20906170357u39aa9b2byadfd7ec0da320cd1@mail.gmail.com> References: <1245232582.7315.1320797515@webmail.messagingengine.com> <40a414c20906170357u39aa9b2byadfd7ec0da320cd1@mail.gmail.com> Message-ID: I use Haskell server pages and HJScript. HJScript includes ajax capabilities. and embed haskell code in HTML much like ASP and JSP embed VB and Java. The client side haskell code is converted to javascript and with ajax you can call Haskell server code. 2009/6/17 minh thu > 2009/6/17 Magnus Therning : > > 2009/6/17 Alberto G. Corona : > >> Web - HTML > > > > I'd agree with that. It would be really nice for X-platform. Maybe > > it's possible to use JQuery (or Flapjax) to get some nice > > dynamic/interacitivity? > > Does someone know if it possible to make an application which embed webkit > with: > - webkit used for rendering and running javascript > - javascript function calling haskell code > ? > > Cheers, > Thu > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090617/d3f3c51a/attachment.html From sebf at informatik.uni-kiel.de Wed Jun 17 08:38:49 2009 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Wed Jun 17 08:22:12 2009 Subject: [Haskell-cafe] Re: [Haskell] ANN: haskell-src-exts 1.0.0 rc1 (aka 0.5.2) In-Reply-To: References: <7D9668D5-949B-4AF0-A4E8-B00FAA6B0441@sebfisch.de> Message-ID: <77946D36-6F49-4823-A3C2-044A59DA899C@informatik.uni-kiel.de> On Jun 17, 2009, at 1:00 PM, Niklas Broberg wrote: > Thanks a lot, very useful! I'll add that to the darcs repository if > you don't mind. :-) feel free! Here is a cleaned-up and updated version that can also read from stdin: #! /usr/bin/env runhaskell > import Language.Haskell.Exts > > import System ( getArgs ) > import System.IO ( hGetContents, stdin ) > import Prelude hiding ( catch ) > import Control.Exception ( catch, SomeException ) > > main :: IO () > main = do args <- getArgs > input <- hGetContents stdin > mapM_ parse (args ++ lines input) > where parse file = catch (parseFile file >>= check) $ > \e -> putStrLn $ file ++ ": " ++ show (e::SomeException) > > check :: ParseResult a -> IO () > check (ParseOk _) = return () > check (ParseFailed loc msg) = putStrLn err > where err = srcFilename loc ++ ": " ++ msg ++ " at " ++ > show (srcLine loc) ++ ":" ++ > show (srcColumn loc) -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 163 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090617/14b6d9a4/PGP.bin From marlowsd at gmail.com Wed Jun 17 08:46:55 2009 From: marlowsd at gmail.com (Simon Marlow) Date: Wed Jun 17 08:30:13 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <2608b8a80906170521k70ec3269k992b0db1fca4e5ec@mail.gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <2608b8a80906170521k70ec3269k992b0db1fca4e5ec@mail.gmail.com> Message-ID: <4A38E5BF.8080005@gmail.com> On 17/06/2009 13:21, Yitzchak Gale wrote: > I wrote: >>> I think the most important use cases that should not break are: >>> >>> o open/read/write a FilePath from getArgs >>> o open/read/write a FilePath from getDirectoryContents > > Simon Marlow wrote: >> The following cases are currently broken: >> >> * Calling openFile on a literal Unicode FilePath (note, not >> ACP-encoded, just Unicode). >> >> * Reading a Unicode FilePath from a text file and then calling >> openFile on it >> >> I propose to fix these (on Windows). It will mean that your second case >> above will be broken, until someone fixes getDirectoryContents. > > Why only on Windows? Just because it's a lot easier on Windows - all the OS APIs take Unicode file paths, so it's obvious what to do. In contrast on Unix I don't have a clear idea of how to proceed. On Unix, all file APIs take [Word8] rather than [Char]. By convention, the [Word8] is usually assumed to be a string in the locale encoding, but that's only a user-space convention. So we should probably be converting from FilePath to [Word8] by encoding using the current locale. This raises various complications (what about encoding errors, and what if encode.decode is not the identity due to normalisation, etc.). But you don't have to wait for me to fix this stuff (I'm feeling a bit Unicoded-out right now :) If someone else has a good understanding of what needs done, please wade in. >> I don't know how getArgs fits in here - should we be decoding argv using the >> ACP? > > And why not also on Unix? On any platform, the expected behavior should > be that you type a file path at the command line, read it using getArgs, > and open the file using that. Right. On Unix it works at the moment because we neither decode argv nor encode FilePaths, so the bytes get passed through unchanged. Same with getDirectoryContents. But I agree it's broken and needs to be fixed. Cheers, Simon From ketil at malde.org Wed Jun 17 09:36:34 2009 From: ketil at malde.org (Ketil Malde) Date: Wed Jun 17 09:19:52 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A38E5BF.8080005@gmail.com> (Simon Marlow's message of "Wed\, 17 Jun 2009 13\:46\:55 +0100") References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <2608b8a80906170521k70ec3269k992b0db1fca4e5ec@mail.gmail.com> <4A38E5BF.8080005@gmail.com> Message-ID: <873a9z6kyl.fsf@malde.org> Simon Marlow writes: >> Why only on Windows? > Just because it's a lot easier on Windows - all the OS APIs take > Unicode file paths, so it's obvious what to do. In contrast on Unix I > don't have a clear idea of how to proceed. > On Unix, all file APIs take [Word8] rather than [Char]. By > convention, the [Word8] is usually assumed to be a string in the > locale encoding, but that's only a user-space convention. If we want to incorporate a translation layer, I think it's fair to only support UTF-8 (ignoring locales), but provide a workaround for invalid characters.=20 >From http://en.wikipedia.org/wiki/UTF-8: | Therefore many modern UTF-8 converters translate errors to | something "safe". Only one byte is changed into the error | replacement and parsing starts again at the next byte, otherwise | concatenating strings could change good characters into | errors. Popular replacements for each byte are:=20 | | * nothing (the bytes vanish) | * '?' or '=BF' | * The replacement character (U+FFFD) | * The byte from ISO-8859-1 or CP1252 | * An invalid Unicode code point, usually U+DCxx where xx is the byte's= value How about using the last one? This would allow 'readFile' to work on FilePaths provided by 'getDirectoryContents', while allowing for real Unicode string literals. -k --=20 If I haven't seen further, it is by standing in the footprints of giants From gale at sefer.org Wed Jun 17 10:03:14 2009 From: gale at sefer.org (Yitzchak Gale) Date: Wed Jun 17 09:46:49 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A38E5BF.8080005@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <2608b8a80906170521k70ec3269k992b0db1fca4e5ec@mail.gmail.com> <4A38E5BF.8080005@gmail.com> Message-ID: <2608b8a80906170703h2985bd0ai5622fc1ddda6adf@mail.gmail.com> Simon Marlow wrote: >>> The following cases are currently broken... >>> I propose to fix these (on Windows). ?It will mean that your second case >>> above will be broken, until someone fixes getDirectoryContents... > ...it's a lot easier on Windows... > on Unix I don't have a clear idea of how to proceed... > If someone else has a good understanding of what > needs done, please wade in. >>> I don't know how getArgs fits in here... > I agree it's broken and needs to be fixed. OK, would you like me to reflect this discussion in tickets? Let's see, so far we have #3300, I don't see anything else. Do you want two tickets, one each for WIndows/Unix? Or four, separating the FilePath and getArgs issues? > On Unix, all file APIs take [Word8]... > So we should probably be converting from FilePath to > [Word8] by encoding using the current locale... > what about encoding errors, Where relevant, we should emulate what the common shells do. In general, I don't see why they should be different than any other file operation error. > and what if encode.decode is not the identity due to normalisation Well, is it common for people using typical input methods and common shells to create file paths containing text that decodes to non-normalized Unicode? I'm guessing not. If that's the case, then we don't really have to worry about it. People who went out of their way to create a weird file name will have the same troubles they have always had with that in Unix. But perhaps a better solution would be to make the underlying type of FilePath platform-dependent - e.g., String on Windows and [Word8] on Unix - and let it support platform- independent methods such as to/from String, to/from Bytes, setEncoding (defaulting to the current locale). That way, pass-through file paths will always work flawlessly on any platform, and applications have complete flexibility to deal with any other scenario however they choose. It's a breaking change though. Thanks, Yitz From gale at sefer.org Wed Jun 17 10:07:50 2009 From: gale at sefer.org (Yitzchak Gale) Date: Wed Jun 17 09:51:25 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <873a9z6kyl.fsf@malde.org> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <2608b8a80906170521k70ec3269k992b0db1fca4e5ec@mail.gmail.com> <4A38E5BF.8080005@gmail.com> <873a9z6kyl.fsf@malde.org> Message-ID: <2608b8a80906170707w7b382435wa5a803734cc6b077@mail.gmail.com> Ketil Malde wrote: > If we want to incorporate a translation layer, I think it's fair to > only support UTF-8 (ignoring locales), but provide a workaround for > invalid characters. I disagree. Shells and GUI dialogs use the current locale. I think most other modern programming languages do too, but correct me if I am wrong. Still, your ideas about dealing with decoding errors sound useful. Regards, Yitz From rvdalen at yahoo.co.uk Wed Jun 17 10:15:43 2009 From: rvdalen at yahoo.co.uk (Rouan van Dalen) Date: Wed Jun 17 09:58:58 2009 Subject: [Haskell-cafe] Tree Semantics and efficiency Message-ID: <296381.66639.qm@web23701.mail.ird.yahoo.com> Hi everyone. I would like to confirm the following semantics. I want a tree which can be traversed both downwards and upwards. To do this i need to store the following for each node: o) a reference to the parent node (so we can traverse up the tree). This must be a reference as i dont want to copy the parent node each time) o) a list of child nodes that belong to this node. It is important to store only a reference to the parent and not a copy of the entire parent for efficiency. How would one write this in Haskell so that it has the above mentioned semantics. Or does GHC do that automatically for me so I don't need to do it explicitly? I am thinking of writing something like this (naive implementation) : Tree = TreeNode String Tree [Tree] -- TreeNode OR (implementation using IORef for parentNode reference) Tree = TreeNode String (IORef Tree) [Tree] -- TreeNode Thanks in advance Rouan. From marlowsd at gmail.com Wed Jun 17 10:18:01 2009 From: marlowsd at gmail.com (Simon Marlow) Date: Wed Jun 17 10:01:18 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <2608b8a80906170703h2985bd0ai5622fc1ddda6adf@mail.gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <2608b8a80906170521k70ec3269k992b0db1fca4e5ec@mail.gmail.com> <4A38E5BF.8080005@gmail.com> <2608b8a80906170703h2985bd0ai5622fc1ddda6adf@mail.gmail.com> Message-ID: <4A38FB19.5080704@gmail.com> On 17/06/2009 15:03, Yitzchak Gale wrote: > Simon Marlow wrote: >>>> The following cases are currently broken... >>>> I propose to fix these (on Windows). It will mean that your second case >>>> above will be broken, until someone fixes getDirectoryContents... >> ...it's a lot easier on Windows... >> on Unix I don't have a clear idea of how to proceed... >> If someone else has a good understanding of what >> needs done, please wade in. >>>> I don't know how getArgs fits in here... >> I agree it's broken and needs to be fixed. > > OK, would you like me to reflect this discussion in tickets? > Let's see, so far we have #3300, I don't see anything else. > > Do you want two tickets, one each for WIndows/Unix? Or > four, separating the FilePath and getArgs issues? One for each issue is usually better, so four. Thanks! >> On Unix, all file APIs take [Word8]... >> So we should probably be converting from FilePath to >> [Word8] by encoding using the current locale... >> what about encoding errors, > > Where relevant, we should emulate what the common > shells do. In general, I don't see why they should be different > than any other file operation error. > >> and what if encode.decode is not the identity due to normalisation > > Well, is it common for people using typical input methods > and common shells to create file paths containing > text that decodes to non-normalized Unicode? > > I'm guessing not. If that's the case, then we don't really have > to worry about it. People who went out of their way to create > a weird file name will have the same troubles they have > always had with that in Unix. > > But perhaps a better solution would be to make the underlying > type of FilePath platform-dependent - e.g., String on Windows > and [Word8] on Unix - and let it support platform- > independent methods such as to/from String, to/from Bytes, > setEncoding (defaulting to the current locale). That way, > pass-through file paths will always work flawlessly on any > platform, and applications have complete flexibility > to deal with any other scenario however they choose. It's a > breaking change though. Yes, we coud do a lot better if FilePath was an abstract type, but sadly it is not, and we can't change that without breaking Haskell 98 compatibility, not to mention tons of existing code. Cheers, Simon From miguelimo38 at yandex.ru Wed Jun 17 10:24:44 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Wed Jun 17 10:08:52 2009 Subject: [Haskell-cafe] Tree Semantics and efficiency In-Reply-To: <296381.66639.qm@web23701.mail.ird.yahoo.com> References: <296381.66639.qm@web23701.mail.ird.yahoo.com> Message-ID: <4A38FCAC.4090406@yandex.ru> You can use the standart "tying the knot"-technique. For example: data Tree = TreeNode String (Maybe Tree) [Tree] -- what's the parent of the root node? test :: Tree test = let parent = TreeNode "I'm parent" Nothing [child1, child2] child1 = TreeNode "I'm child1" (Just parent) [] child2 = TreeNode "I'm child2" (Just parent) [] in parent But there are other possibilities worth considering. Zippers, for example, would be likely useful. IORefs are most certainly an overkill. Rouan van Dalen wrote on 17.06.2009 18:15: > Hi everyone. > > I would like to confirm the following semantics. > > I want a tree which can be traversed both downwards and upwards. > To do this i need to store the following for each node: > > o) a reference to the parent node (so we can traverse up the tree). This must be a reference as i dont want to copy the parent node each time) > o) a list of child nodes that belong to this node. > > It is important to store only a reference to the parent and not a copy of the entire parent for efficiency. > > How would one write this in Haskell so that it has the above mentioned semantics. > Or does GHC do that automatically for me so I don't need to do it explicitly? > > I am thinking of writing something like this (naive implementation) : > > Tree = TreeNode String Tree [Tree] -- TreeNode > > OR (implementation using IORef for parentNode reference) > > Tree = TreeNode String (IORef Tree) [Tree] -- TreeNode > > > Thanks in advance > > Rouan. > > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From aslatter at gmail.com Wed Jun 17 10:38:12 2009 From: aslatter at gmail.com (Antoine Latter) Date: Wed Jun 17 10:21:27 2009 Subject: [Haskell-cafe] Tree Semantics and efficiency In-Reply-To: <4A38FCAC.4090406@yandex.ru> References: <296381.66639.qm@web23701.mail.ird.yahoo.com> <4A38FCAC.4090406@yandex.ru> Message-ID: <694519c50906170738h40811fa9m4c954b881601887a@mail.gmail.com> On Wed, Jun 17, 2009 at 9:24 AM, Miguel Mitrofanov wrote: > You can use the standart "tying the knot"-technique. For example: > > data Tree = TreeNode String (Maybe Tree) [Tree] -- what's the parent of the > root node? > > test :: Tree > test = > ? let parent = TreeNode "I'm parent" Nothing [child1, child2] > ? ? ? child1 = TreeNode "I'm child1" (Just parent) [] > ? ? ? child2 = TreeNode "I'm child2" (Just parent) [] > ? in parent > > But there are other possibilities worth considering. Zippers, for example, > would be likely useful. The advantage zippers have over knot-tying is that I can create updates of zipper-viewed data structures. It looks like there's already something on HAckage for this: http://hackage.haskell.org/packages/archive/rosezipper/0.1/doc/html/Data-Tree-Zipper.html The idea is that you can use the following function to created the zipper-view of your tree: > fromTree :: Tree a -> TreeLoc a and then use the functions on 'TreeLoc' types to traverse and modify the tree, and then call > toTree :: TreeLoc a -> Tree a to go back to the 'Tree a' representation of your data. Antoine From jake.mcarthur at gmail.com Wed Jun 17 10:44:14 2009 From: jake.mcarthur at gmail.com (Jake McArthur) Date: Wed Jun 17 10:27:12 2009 Subject: [Haskell-cafe] Tree Semantics and efficiency In-Reply-To: <296381.66639.qm@web23701.mail.ird.yahoo.com> References: <296381.66639.qm@web23701.mail.ird.yahoo.com> Message-ID: <4A39013E.1060004@gmail.com> Rouan van Dalen wrote: > It is important to store only a reference to the parent and not a copy of the entire parent for efficiency. Others have already recommended the rosezipper package, which gives you what you want, but I want to address one thing. foo = bar = foo In most implementations (including GHC, which I assume you are using), `bar` will *not* be an actual copy of `foo`. In fact, GHC will not make a deep copy of a structure unless you pattern match all the way down and reconstruct it all the way back up yourself. If you use a zipper, like Data.Tree.Zipper mentioned already, moving around will not create and destroy tons of data. It will only create and destroy the spine of the tree local to the current "pointer" into the tree, which is not a lot of data. If you are holding on to older versions of the zipper, of course, they won't even be destroyed. - Jake From matthias.goergens at googlemail.com Wed Jun 17 11:02:36 2009 From: matthias.goergens at googlemail.com (=?ISO-8859-1?Q?Matthias_G=F6rgens?=) Date: Wed Jun 17 10:45:51 2009 Subject: [Haskell-cafe] slow code In-Reply-To: <87bpon8g33.fsf@malde.org> References: <9621AF5D-5C87-43A6-B8A2-103109570416@aracnet.com> <00FDD473-F0DB-41F8-8410-C435CDF045C0@aracnet.com> <20090616155858.GE4695@whirlpool.galois.com> <83C5F868-8806-4AD4-B9B9-AB9B81C79BA5@aracnet.com> <87bpon8g33.fsf@malde.org> Message-ID: > Still, a fast and general way to output primitive data types would be > quite welcome. Naive question: Can't we just ask C to do it for us? (With a foreign function call.) Matthias. From tom.davie at gmail.com Wed Jun 17 11:15:51 2009 From: tom.davie at gmail.com (Thomas Davie) Date: Wed Jun 17 10:59:10 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> Message-ID: <8942CD18-8F65-411A-A0B1-C938DF219314@gmail.com> On 17 Jun 2009, at 13:32, Yitzchak Gale wrote: > Henk-Jan van Tuyl wrote: >> reverse >> maximum >> minimum > > Oh yes, please fix those also! import Prelude.Strict? Honestly, these functions are ones that I've *deffinately* used lazy versions of, in fact, in the cases of minimum/maximum I've even used ones that are super-lazy and parallel using unamb. It would be extremely odd to randomly decide "most people would want this to be strict" based on no knowledge of what they're actually doing. Instead, why don't we stand by the fact that haskell is a lazy language, and that the functions we get by default are lazy, and then write a strict prelude as I suggest above to complement the lazy version. Bob From dons at galois.com Wed Jun 17 11:20:01 2009 From: dons at galois.com (Don Stewart) Date: Wed Jun 17 11:05:07 2009 Subject: [Haskell-cafe] slow code In-Reply-To: References: <9621AF5D-5C87-43A6-B8A2-103109570416@aracnet.com> <00FDD473-F0DB-41F8-8410-C435CDF045C0@aracnet.com> <20090616155858.GE4695@whirlpool.galois.com> <83C5F868-8806-4AD4-B9B9-AB9B81C79BA5@aracnet.com> <87bpon8g33.fsf@malde.org> Message-ID: <20090617152001.GC10342@whirlpool.galois.com> matthias.goergens: > > Still, a fast and general way to output primitive data types would be > > quite welcome. Data.Binary is the way (though it doesn't yet use direct output for float and double bits) From briqueabraque at yahoo.com Wed Jun 17 11:23:34 2009 From: briqueabraque at yahoo.com (=?ISO-8859-1?Q?Maur=ED=ADcio?=) Date: Wed Jun 17 11:07:08 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: <1245178684.5131.8.camel@flippa-eee> References: <1244822326.28941.29.camel@flippa-eee> <1245178684.5131.8.camel@flippa-eee> Message-ID: >>> I'm hearing reports of people having difficulty obtaining accounts on >>> the Haskell wiki, (...) >> Maybe OpenID could help with spam problems without >> the need for manual intervention: > I doubt it - I know LiveJournal has a problem with spambots gaining free > accounts, and it provides OpenID. They may not be exploited for the > OpenID account yet, but I imagine they will be sooner rather than later > - OpenID is more useful to tie in people's existing identities. I would sugest that Haskell wiki only accepts OpenIDs, without providing then itself. So spammers would have to use domains, and I (naively?) believe those are costly to obtain and easy to block. Maur?cio From briqueabraque at yahoo.com Wed Jun 17 11:47:48 2009 From: briqueabraque at yahoo.com (=?ISO-8859-1?Q?Maur=ED=ADcio?=) Date: Wed Jun 17 11:31:18 2009 Subject: [Haskell-cafe] Re: ANNOUNCE: clock 0.1 released In-Reply-To: <1ff5dedc0906152014q13cd7071vf26d3bcba9ceb002@mail.gmail.com> References: <1ff5dedc0906152014q13cd7071vf26d3bcba9ceb002@mail.gmail.com> Message-ID: > clock (...) I like the way you use Unicode on operators. > It was implemented in response to a haskell-cafe discussion: > http://www.mail-archive.com/haskell-cafe@haskell.org/msg51244.html Since I started that, I have to say thanks! > Any suggestions for improvement, bug-fixes, joint-development offers are > most welcome *^o^*!! Joint-development? Here is a sugestion, although it's really not glamourous :) I'm working on this 'bindings-common' (and other 'bindings-*') packages. It already provides the foreign code you used for 'clock', so you could link to it and help me expand its coverage. But it's really not something one would like to do for fun, although I believe it's going to be usefull. Best, Maur?cio From dons at galois.com Wed Jun 17 11:47:41 2009 From: dons at galois.com (Don Stewart) Date: Wed Jun 17 11:32:47 2009 Subject: [Haskell-cafe] Android and Haskell In-Reply-To: <711894390906162343o1aec6aedq1780f5ca0c6f3d3b@mail.gmail.com> References: <5ae4f2ba0906162233g55806575h9dd83d0c8ee702f1@mail.gmail.com> <20090617163153.cd1afe7a.mle+hs@mega-nerd.com> <711894390906162343o1aec6aedq1780f5ca0c6f3d3b@mail.gmail.com> Message-ID: <20090617154741.GI10342@whirlpool.galois.com> toby.hutton: > On Wed, Jun 17, 2009 at 4:31 PM, Erik de Castro Lopo > wrote: > > > Well if the android phones have a JVM then something like OpenQuark > should do the trick. > > > The Android phones actually have a different VM which essentially takes > compiled/translated java bytecode. > > http://en.wikipedia.org/wiki/Dalvik_virtual_machine EDSL time! -- Don From stircrazynemo at hotmail.com Wed Jun 17 11:54:16 2009 From: stircrazynemo at hotmail.com (.shawn) Date: Wed Jun 17 11:37:33 2009 Subject: [Haskell-cafe] About the Monad Transformers Message-ID: On page 141 of "Yet another Haskell Tutorial" (9.7 Monad Transformers) mapTreeM action (Leaf a) = do lift (putStrLn ("Leaf" ++ show a)) b <- action a return (Leaf b) mapTreeM :: (MonadTrans t, Monad (t IO), Show a) => (a -> t IO a1) -> Tree a -> t IO (Tree a1) Why does the type signature of mapTreeM look like this? And what does it mean by "The lift tell us that we're going to be executing a command in an enclosed monad. In this case the enclosed monad is IO"? Why does the author put lift here? How does the lift work? I have no idea about the explanation in the book...is there anyone can give me some hints about this? Thank you in advance! _________________________________________________________________ Messenger10????????????? http://10.msn.com.cn -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090617/c53d3fe5/attachment.html From nrolle at web.de Wed Jun 17 12:18:01 2009 From: nrolle at web.de (Nico Rolle) Date: Wed Jun 17 12:01:17 2009 Subject: [Haskell-cafe] ghc does not link after compiling Message-ID: <45fccde20906170918k473ed76fi9e3a489dfdd0f344@mail.gmail.com> hi I wanted to compile my little test programm so it can take advantage of a multicore system. But when i call the compiler with ghc -O2 --make Benchmark.hs -threaded it just produces a acouple of .hi and .o files but no executable. But in the documantation was written that i just need to call ghc like that and it will produce my desired executable. My version of ghc is 6.10.3 regards From hjgtuyl at chello.nl Wed Jun 17 12:22:51 2009 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Wed Jun 17 12:05:55 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> Message-ID: On Wed, 17 Jun 2009 13:32:40 +0200, Yitzchak Gale wrote: > Henk-Jan van Tuyl wrote: >> reverse >> maximum >> minimum > > Oh yes, please fix those also! maximum' = foldl' max 0 [1 .. 999999] minimum' = foldl' min 0 [1 .. 999999] > >> scanl >> scanr >> scanr1 >> iterate >> take >> drop >> splitAt >> inits > > Hmm, I use those all the time with large lists. They are lazy as > expected, > and seem to work fine. Do you have examples of problems with them? A hugs (version: Sep 2006) session: Hugs> last $ scanl const 0 [0 .. 10 ^ 6] ERROR - C stack overflow Hugs> head $ scanr (+) 0 [1 .. 10 ^ 6] ERROR - C stack overflow Hugs> head $ scanr1 (+) [1 .. 10 ^ 6] ERROR - C stack overflow Hugs> iterate (+ 1) 0 !! (10 ^ 6) ERROR - C stack overflow Hugs> last $ take (10 ^ 6) [1 ..] 1000000 Hugs> head $ drop (10 ^ 6) [1 ..] 1000001 Hugs> head . snd $ splitAt (10 ^ 6) [1 ..] 1000001 Data.List> last $ last $ inits [1 .. 10 ^ 6] ERROR - C stack overflow A GHCi 6.10.1 session: Prelude> last $ scanl const 0 [0 .. 10 ^ 6] 0 Prelude> head $ scanr (+) 0 [1 .. 10 ^ 6] *** Exception: stack overflow Prelude> head $ scanr1 (+) [1 .. 10 ^ 6] *** Exception: stack overflow Prelude> iterate (+ 1) 0 !! (10 ^ 6) *** Exception: stack overflow Prelude> last $ take (10 ^ 6) [1 ..] 1000000 Prelude> head $ drop (10 ^ 6) [1 ..] 1000001 Prelude> head . snd $ splitAt (10 ^ 6) [1 ..] 1000001 Prelude> :m Data.List Prelude Data.List> last $ last $ inits [1 .. 10 ^ 6] ??? (not finished yet) take, drop and splitAt seem to work fine now, but when I did these tests the first time, GHCi generated a stack overflow exception (I think it was GHCi 6.8.3). > >> foldM >> filterM (Bulat) foldM' f a (x:xs) = do a' <- f a x a' `seq` foldM' f a' xs -- Met vriendelijke groet, Henk-Jan van Tuyl -- http://functor.bamikanarie.com http://Van.Tuyl.eu/ -- From deniz.a.m.dogan at gmail.com Wed Jun 17 12:22:59 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Wed Jun 17 12:06:15 2009 Subject: [Haskell-cafe] ghc does not link after compiling In-Reply-To: <45fccde20906170918k473ed76fi9e3a489dfdd0f344@mail.gmail.com> References: <45fccde20906170918k473ed76fi9e3a489dfdd0f344@mail.gmail.com> Message-ID: <7b501d5c0906170922w7edd3040oabe64dbc5154df4f@mail.gmail.com> 2009/6/17 Nico Rolle : > hi > > I wanted to compile my little test programm so it can take advantage > of a multicore system. > But when i call the compiler with > > ghc -O2 --make Benchmark.hs -threaded > > it just produces a acouple of .hi and .o files but no executable. > But in the documantation was written that i just need to call ghc like > that and it will produce my desired executable. > My version of ghc is 6.10.3 > regards > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > Is the module name "Main"? -- Deniz Dogan From daniel.is.fischer at web.de Wed Jun 17 12:34:50 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Jun 17 12:18:55 2009 Subject: [Haskell-cafe] ghc does not link after compiling In-Reply-To: <45fccde20906170918k473ed76fi9e3a489dfdd0f344@mail.gmail.com> References: <45fccde20906170918k473ed76fi9e3a489dfdd0f344@mail.gmail.com> Message-ID: <200906171834.50579.daniel.is.fischer@web.de> Am Mittwoch 17 Juni 2009 18:18:01 schrieb Nico Rolle: > hi > > I wanted to compile my little test programm so it can take advantage > of a multicore system. > But when i call the compiler with > > ghc -O2 --make Benchmark.hs -threaded If your module name is not Main, you need the -main-is flag: ghc -O2 -threaded -main-is Benchmark --make Benchmark or ghc -O2 -threaded -main-is Benchmark.main --make Benchmark > > it just produces a acouple of .hi and .o files but no executable. > But in the documantation was written that i just need to call ghc like > that and it will produce my desired executable. > My version of ghc is 6.10.3 > regards From nrolle at web.de Wed Jun 17 12:38:32 2009 From: nrolle at web.de (Nico Rolle) Date: Wed Jun 17 12:21:47 2009 Subject: [Haskell-cafe] ghc does not link after compiling In-Reply-To: <7b501d5c0906170922w7edd3040oabe64dbc5154df4f@mail.gmail.com> References: <45fccde20906170918k473ed76fi9e3a489dfdd0f344@mail.gmail.com> <7b501d5c0906170922w7edd3040oabe64dbc5154df4f@mail.gmail.com> Message-ID: <45fccde20906170938y3726b9bei67df9068689424cf@mail.gmail.com> oh sry now it works thank you 2009/6/17 Deniz Dogan : > 2009/6/17 Nico Rolle : >> hi >> >> I wanted to compile my little test programm so it can take advantage >> of a multicore system. >> But when i call the compiler with >> >> ghc -O2 --make Benchmark.hs -threaded >> >> it just produces a acouple of .hi and .o files but no executable. >> But in the documantation was written that i just need to call ghc like >> that and it will produce my desired executable. >> My version of ghc is 6.10.3 >> regards >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > Is the module name "Main"? > > -- > Deniz Dogan > From miguelimo38 at yandex.ru Wed Jun 17 12:54:58 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Wed Jun 17 12:38:15 2009 Subject: [Haskell-cafe] About the Monad Transformers In-Reply-To: References: Message-ID: <0460E609-700B-44EF-80D8-60D4813379EB@yandex.ru> On 17 Jun 2009, at 19:54, .shawn wrote: > Why does the type signature of mapTreeM look like this? Why not? I can't think of any other possibility. > And what does it mean by "The lift tell us that we're going to be > executing a command in an enclosed monad. In this case the enclosed > monad is IO"? Wild guess: I think they mean exactly what they said. Literally. > Why does the author put lift here? Because he wanted to work in a more general setting than just IO monad. He needed IO, of course, because of "putStrLn", but he wanted to give the user of this function an opportunity to do something besides just IO. > How does the lift work? "lift" is defined in the "MonadTrans" type class, so it works differently depending on what transformer you use. You can even define your own one and "lift" would work as you write it. The only thing we know for sure is that whichever transformer you use, "lift" would have the type "m x -> t m x", where "t" is a transformer in question. So, it would be OK to apply it to, say, something of type "IO a", and you'd have something of type "t IO a" as a result. From nccb2 at kent.ac.uk Wed Jun 17 13:09:19 2009 From: nccb2 at kent.ac.uk (Neil Brown) Date: Wed Jun 17 12:52:27 2009 Subject: [Haskell-cafe] About the Monad Transformers In-Reply-To: References: Message-ID: <4A39233F.4040305@kent.ac.uk> .shawn wrote: > On page 141 of "Yet another Haskell Tutorial" (9.7 Monad Transformers) > > mapTreeM action (Leaf a) = do > lift (putStrLn ("Leaf" ++ show a)) > b <- action a > return (Leaf b) > > mapTreeM :: (MonadTrans t, Monad (t IO), Show a) => (a -> t IO a1) -> > Tree a -> t IO (Tree a1) > > Why does the type signature of mapTreeM look like this? > And what does it mean by "The lift tell us that we're going to be > executing a command in an enclosed monad. In this case the enclosed > monad is IO"? Why does the author put lift here? How does the lift work? The idea of a monad transformer is to add a second monad (the transformer) onto a first (I find thatoften, as in this case, IO is involved). The type parameter t (standing for the monad transformer) takes two arguments: the first is the monad being added to (IO) and the second is the normal monadic return value. For example, with the StateT transformer using a state with type Int, the type signature becomes: mapTreeM :: (MonadTrans (StateT Int), Monad (StateT Int IO), Show a) => (a -> StateT Int IO a1) -> Tree a -> StateT Int IO (Tree a1) So it takes a function from a to a1 in our combined StateT Int IO monad, a Tree of a, and gives you back a Tree of a1 in the monad, by transforming each value in the tree monadically. When you write the do block, you are writing in the StateT Int IO monad (or whatever transformer you happen to be using). Thus, the compiler expects the statements of the do block to be of this type. putStrLn gives back something in the IO monad, and there is no support in the language/type-system for automatically turning an IO thing into a StateT Int IO thing. Hence where lift comes in. lift is used to make something of the inside monad (IO) become something of the transformed monad (StateT Int IO). The call of action does not need lift, because its result is already in the StateT Int IO monad. The times where lift becomes particularly important is when you end up with two state monads (or two writer monads, or whatever) in a stack. If you had the nasty construction StateT Int (StateT Int IO) as your monad, you'd need a lift to access the inner state, but you'd leave off the lift to access the outer state. Hope that helps, Neil. From loupgaroublond at gmail.com Wed Jun 17 13:32:36 2009 From: loupgaroublond at gmail.com (Yaakov Nemoy) Date: Wed Jun 17 13:15:50 2009 Subject: [Haskell-cafe] Start to Finish C2HS guide Message-ID: <7f692fec0906171032q769a0adbr7ffbd92f53dab555@mail.gmail.com> Hey List, I was experimenting a bit with binding RPM in Haskell and i figured i would document the process a bit. The link below sums up from start to finish in tutorial fashion how to write bindings. http://loupgaroublond.blogspot.com/2009/06/haskell-bindings-to-c-from-start-to.html Perhaps would it be possible to include some of this kind of information with C2HS documentation in the future? -Yaakov Nemoy From hjgtuyl at chello.nl Wed Jun 17 14:07:01 2009 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Wed Jun 17 13:50:01 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> Message-ID: On Wed, 17 Jun 2009 18:22:51 +0200, Henk-Jan van Tuyl wrote: > On Wed, 17 Jun 2009 13:32:40 +0200, Yitzchak Gale wrote: > >> Henk-Jan van Tuyl wrote: >>> reverse >>> maximum >>> minimum >> >> Oh yes, please fix those also! > > maximum' = foldl' max 0 [1 .. 999999] > minimum' = foldl' min 0 [1 .. 999999] > Of course I meant: maximum' xs = foldl1' max xs minimum' xs = foldl1' min xs -- Met vriendelijke groet, Henk-Jan van Tuyl -- http://functor.bamikanarie.com http://Van.Tuyl.eu/ -- From nrolle at web.de Wed Jun 17 14:25:08 2009 From: nrolle at web.de (Nico Rolle) Date: Wed Jun 17 14:08:23 2009 Subject: [Haskell-cafe] measuring time differences between functions Message-ID: <45fccde20906171125p60520738qd8b4637c578c7f3c@mail.gmail.com> Hi everyone. I made parallel versions of my functions projection selection and sort and i wanted to test the difference in runtime. But he only printed 0.00 twice. Maybe hes just too fast? Or is it because of lazy evaluation? or is there a better way to mesure performance in execution time? regards main = do xs <- readCSV "dataconvert/lineitem.tbl" '|' start <- getCurrentTime let pnp = projection [5] xs let snp = selection (\x -> (x!!0) > (Int 17000)) pnp let sortnp = sort [0] [ASC] snp end <- getCurrentTime putStrLn $ show (end `diffUTCTime` start) start2 <- getCurrentTime let pp = pProjection [5] xs let sp = pSelection (\x -> (x!!0) > (Int 17000)) pp let sortp = pSort [0] [ASC] sp end2 <- getCurrentTime putStrLn $ show (end2 `diffUTCTime` start2) return snp From joshhoyt at gmail.com Wed Jun 17 15:03:53 2009 From: joshhoyt at gmail.com (j3h) Date: Wed Jun 17 14:47:08 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: References: <1244822326.28941.29.camel@flippa-eee> <1245178684.5131.8.camel@flippa-eee> Message-ID: <34714aad0906171203p7b73180n1c10a837447dc0c2@mail.gmail.com> On Wed, Jun 17, 2009 at 8:23 AM, Maur??cio wrote: > I would sugest that Haskell wiki only accepts OpenIDs, without > providing then itself. So spammers would have to use domains, > and I (naively?) believe those are costly to obtain and easy > to block. It's easy for a spammer to obtain an OpenID without having to obtain a domain. Unfortunately, OpenID by itself is not a sufficient mechanism for preventing spam. Josh From daniel.is.fischer at web.de Wed Jun 17 15:07:36 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Jun 17 14:51:42 2009 Subject: [Haskell-cafe] measuring time differences between functions In-Reply-To: <45fccde20906171125p60520738qd8b4637c578c7f3c@mail.gmail.com> References: <45fccde20906171125p60520738qd8b4637c578c7f3c@mail.gmail.com> Message-ID: <200906172107.36829.daniel.is.fischer@web.de> Am Mittwoch 17 Juni 2009 20:25:08 schrieb Nico Rolle: > Hi everyone. > I made parallel versions of my functions projection selection and sort > and i wanted to test the difference in runtime. > But he only printed 0.00 twice. > Maybe hes just too fast? > Or is it because of lazy evaluation? > or is there a better way to mesure performance in execution time? > regards > > main = do > xs <- readCSV "dataconvert/lineitem.tbl" '|' > start <- getCurrentTime > let pnp = projection [5] xs > let snp = selection (\x -> (x!!0) > (Int 17000)) pnp > let sortnp = sort [0] [ASC] snp > end <- getCurrentTime > putStrLn $ show (end `diffUTCTime` start) > start2 <- getCurrentTime > let pp = pProjection [5] xs > let sp = pSelection (\x -> (x!!0) > (Int 17000)) pp > let sortp = pSort [0] [ASC] sp > end2 <- getCurrentTime > putStrLn $ show (end2 `diffUTCTime` start2) > return snp The let bindings do not cause any computation because of laziness, all they do is bind the names to a thunk that says how to calculate the value if it is needed. Regardless of how long the computation would take, binding the names to a thunk takes only a few nanoseconds. To measure the time needed for the computations, you must force them to be carried out between the two calls to getCurrentTime. Probably inserting print $ last snp before end <- getCurrentTime (and likewise for the second) would be enough (if the sorting doesn't require the values in snp to be fully evaluated, you would have to do more forcing). From daniel.is.fischer at web.de Wed Jun 17 15:16:37 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Jun 17 15:00:41 2009 Subject: [Haskell-cafe] measuring time differences between functions In-Reply-To: <45fccde20906171125p60520738qd8b4637c578c7f3c@mail.gmail.com> References: <45fccde20906171125p60520738qd8b4637c578c7f3c@mail.gmail.com> Message-ID: <200906172116.37544.daniel.is.fischer@web.de> Am Mittwoch 17 Juni 2009 20:25:08 schrieb Nico Rolle: > or is there a better way to mesure performance in execution time? I think System.CPUTime provides more reliable timings if the work takes long enough for the scheduler to kick in. And there are several benchmarking packages on Hackage, e.g. maybench, microbench, benchpress, StrictBench. From keithshep at gmail.com Wed Jun 17 15:50:45 2009 From: keithshep at gmail.com (Keith Sheppard) Date: Wed Jun 17 15:34:01 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <8942CD18-8F65-411A-A0B1-C938DF219314@gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> <8942CD18-8F65-411A-A0B1-C938DF219314@gmail.com> Message-ID: <92e42b740906171250w2dc15d44o36346117f55d8fd5@mail.gmail.com> Haskell's numeric literals are strict. You wouldn't want that to change right? It seems to me that having sum and product be strict is consistent with this. -Keith On Wed, Jun 17, 2009 at 11:15 AM, Thomas Davie wrote: > > On 17 Jun 2009, at 13:32, Yitzchak Gale wrote: > >> Henk-Jan van Tuyl wrote: >>> >>> reverse >>> maximum >>> minimum >> >> Oh yes, please fix those also! > > import Prelude.Strict? > > Honestly, these functions are ones that I've *deffinately* used lazy > versions of, in fact, in the cases of minimum/maximum I've even used ones > that are super-lazy and parallel using unamb. > > It would be extremely odd to randomly decide "most people would want this to > be strict" based on no knowledge of what they're actually doing. ?Instead, > why don't we stand by the fact that haskell is a lazy language, and that the > functions we get by default are lazy, and then write a strict prelude as I > suggest above to complement the lazy version. > > Bob > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- keithsheppard.name From ravi at bluespec.com Wed Jun 17 15:55:59 2009 From: ravi at bluespec.com (Ravi Nanavati) Date: Wed Jun 17 15:39:13 2009 Subject: [Haskell-cafe] Fwd: Boston Haskell June 23rd meeting: openings for Lightning Talks Message-ID: <7b977d860906171255v6120cb4aq3125f58cfe464d17@mail.gmail.com> ---------- Forwarded message ---------- From: Ravi Nanavati Date: Wed, Jun 17, 2009 at 3:55 PM Subject: June 23rd meeting: openings for Lightning Talks To: bostonhaskell@googlegroups.com Both speakers for the June 23rd meeting have let me know that they expect their presentations to be on the shorter side of the 30-45 minutes alloted, so that means we have some space in the schedule. We could just use that as additional free-form discussion and mingling time, but since I saw them be successful at ILC'2009 and at the Boston Lisp Meeting after that, I'd like to offer that space to anyone who wants to give a "Lightning Talk". I think we should use the same formula as the Lisp Meeting: strictly-timed 5-minute talks followed by 2-minutes for questions and answers from the audience. Lightning talks don't have to be Haskell-specific, as long as the topic is appropriate for the audience. If you're interested in giving a Lightning Talk at the June 23rd meeting, please contact me ( ravi@bluespec.com ) and let me know what you'd like to talk about. Thank you, ?- Ravi Nanavati From lennart at augustsson.net Wed Jun 17 16:05:13 2009 From: lennart at augustsson.net (Lennart Augustsson) Date: Wed Jun 17 15:48:29 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <92e42b740906171250w2dc15d44o36346117f55d8fd5@mail.gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090615151424.GG31863@whirlpool.galois.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> <8942CD18-8F65-411A-A0B1-C938DF219314@gmail.com> <92e42b740906171250w2dc15d44o36346117f55d8fd5@mail.gmail.com> Message-ID: What do you mean by "literals are strict"? Strictness is a semantic property of functions, and while literals can be overloaded to be functions I don't know what you mean. On Wed, Jun 17, 2009 at 9:50 PM, Keith Sheppard wrote: > Haskell's numeric literals are strict. You wouldn't want that to > change right? It seems to me that having sum and product be strict is > consistent with this. > > -Keith > > On Wed, Jun 17, 2009 at 11:15 AM, Thomas Davie wrote: >> >> On 17 Jun 2009, at 13:32, Yitzchak Gale wrote: >> >>> Henk-Jan van Tuyl wrote: >>>> >>>> reverse >>>> maximum >>>> minimum >>> >>> Oh yes, please fix those also! >> >> import Prelude.Strict? >> >> Honestly, these functions are ones that I've *deffinately* used lazy >> versions of, in fact, in the cases of minimum/maximum I've even used ones >> that are super-lazy and parallel using unamb. >> >> It would be extremely odd to randomly decide "most people would want this to >> be strict" based on no knowledge of what they're actually doing. ?Instead, >> why don't we stand by the fact that haskell is a lazy language, and that the >> functions we get by default are lazy, and then write a strict prelude as I >> suggest above to complement the lazy version. >> >> Bob >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > > > -- > keithsheppard.name > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From gue.schmidt at web.de Wed Jun 17 16:46:40 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Wed Jun 17 16:30:06 2009 Subject: [Haskell-cafe] Re: Which windowing toolkit to use? In-Reply-To: <1245232582.7315.1320797515@webmail.messagingengine.com> References: <1245232582.7315.1320797515@webmail.messagingengine.com> Message-ID: Hi Patai, there is one other alternative to gtk2hs and wxhaskell: .NET Forms It is accessable through Sigbjorn Finne's hs-dotnet package. I am right now *starting* to use it myself, so just consider it an option. Both of the others are quite usable, wxhaskell has very easy to use layouts and looks fine on windows (native look) but lacks any support for MVC, ie. a click on a list will only give you back which position was clicked and it's up to you what "object" that should map to. Gtk2hs also has layouts, IMO not as nice as wxhaskell, does not look as nice on XP, (no true native look and feel), but does have support for mvc. Both (gtk2hs and wxhaskell) have a "multithreading" problem, cause it's not possible to call gui code outside the main gui event loop, and believe me, the wish for that does occur, so it's kinda hard to code a gui that is not sluggish with long computations. With the threading part, .NET Forms can handle that much easier. G?nther Patai Gergely schrieb: > Hi all, > > I intend to start coding the UI of the heap profiling toolkit I'm > working on [1] soon. I'd be happy to get some advice on choosing the > right windowing toolkit for this task. The main requirements are: > > - portability and native look & feel if possible > - easy to distribute executables under Windows > - relatively slow code rot > - sane interface that doesn't need wild workarounds even if what I'm > doing is not trivial or elementary > - trouble-free source installation in case someone wants to contribute > > As I see, at the moment there's no serious alternative besides GTK and > wx, so my question is which do you think is better suited to this task? > I have absolutely no development experience with GTK, and while I used a > bit of wx in the past (in C++), I'm not really familiar with it either, > especially not the Haskell bindings. I noticed that installing the wx > binding with user rights doesn't seem to work directly from hackage > (doesn't pass --user to ghc-pkg?), but it looks like a problem that can > be solved with some hand editing. I'm a bit more afraid of setting up a > development environment under Windows; is there any major pain involved > with either of these libraries if I use MinGW? > > And how about their interface? Is there any significant difference? I'd > especially like to hear the opinion of someone who's reasonably familiar > with both. > > Thanks, > > Gergely > > [1] http://code.google.com/p/hp2any/ > From keithshep at gmail.com Wed Jun 17 17:05:50 2009 From: keithshep at gmail.com (Keith Sheppard) Date: Wed Jun 17 16:49:04 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <92e42b740906151749k70efce9fv1cde624e25c68268@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> <8942CD18-8F65-411A-A0B1-C938DF219314@gmail.com> <92e42b740906171250w2dc15d44o36346117f55d8fd5@mail.gmail.com> Message-ID: <92e42b740906171405n2207827amf94471ef413fe22d@mail.gmail.com> In lambda calculus numbers are just functions and you evaluate them just like any other function. Haskell could have chosen the same representation for numbers and all evaluation on numbers would be lazy (assuming normal order evaluation). I think that would have been the "Purist Lazy" way to go. That is not the way the creators of Haskell designed language though... am i missing something? On Wed, Jun 17, 2009 at 4:05 PM, Lennart Augustsson wrote: > What do you mean by "literals are strict"? ?Strictness is a semantic > property of functions, and while literals can be overloaded to be > functions I don't know what you mean. > > On Wed, Jun 17, 2009 at 9:50 PM, Keith Sheppard wrote: >> Haskell's numeric literals are strict. You wouldn't want that to >> change right? It seems to me that having sum and product be strict is >> consistent with this. >> >> -Keith >> >> On Wed, Jun 17, 2009 at 11:15 AM, Thomas Davie wrote: >>> >>> On 17 Jun 2009, at 13:32, Yitzchak Gale wrote: >>> >>>> Henk-Jan van Tuyl wrote: >>>>> >>>>> reverse >>>>> maximum >>>>> minimum >>>> >>>> Oh yes, please fix those also! >>> >>> import Prelude.Strict? >>> >>> Honestly, these functions are ones that I've *deffinately* used lazy >>> versions of, in fact, in the cases of minimum/maximum I've even used ones >>> that are super-lazy and parallel using unamb. >>> >>> It would be extremely odd to randomly decide "most people would want this to >>> be strict" based on no knowledge of what they're actually doing. ?Instead, >>> why don't we stand by the fact that haskell is a lazy language, and that the >>> functions we get by default are lazy, and then write a strict prelude as I >>> suggest above to complement the lazy version. >>> >>> Bob >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> Haskell-Cafe@haskell.org >>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>> >> >> >> >> -- >> keithsheppard.name >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > -- keithsheppard.name From magnus at therning.org Wed Jun 17 17:08:34 2009 From: magnus at therning.org (Magnus Therning) Date: Wed Jun 17 16:52:00 2009 Subject: [Haskell-cafe] Re: Which windowing toolkit to use? In-Reply-To: References: <1245232582.7315.1320797515@webmail.messagingengine.com> Message-ID: <4A395B52.2050305@therning.org> G??nther Schmidt wrote: > Hi Patai, > > there is one other alternative to gtk2hs and wxhaskell: .NET Forms > > It is accessable through Sigbjorn Finne's hs-dotnet package. Is that usable with mono? I certainly hope that something as useful as the heap profiling toolkit's GUI won't be a Windows-only thing. Is the plan to make the heap profiling ship with GHC? In that case it might be ill advised to add a dependency on dot-net/mono. Though it could be argued it's just as ill advised to add a dependency on GTK/WX. /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 197 bytes Desc: OpenPGP digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090617/61047517/signature.bin From bulat.ziganshin at gmail.com Wed Jun 17 17:11:28 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Wed Jun 17 16:54:50 2009 Subject: [Haskell-cafe] Re: Which windowing toolkit to use? In-Reply-To: References: <1245232582.7315.1320797515@webmail.messagingengine.com> Message-ID: <16310701678.20090618011128@gmail.com> Hello Gu?nther, Thursday, June 18, 2009, 12:46:40 AM, you wrote: > there is one other alternative to gtk2hs and wxhaskell: .NET Forms > It is accessable through Sigbjorn Finne's hs-dotnet package. > I am right now *starting* to use it myself, so just consider it an option. can you please provide code snippets? some starting basis will greatly help to grok this way of GUI -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From paul.chiusano at gmail.com Wed Jun 17 18:07:14 2009 From: paul.chiusano at gmail.com (Paul Chiusano) Date: Wed Jun 17 17:50:30 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? In-Reply-To: <57A134DD-CF18-4502-AC0D-C7B7265576AD@cs.uu.nl> References: <57A134DD-CF18-4502-AC0D-C7B7265576AD@cs.uu.nl> Message-ID: Stefan, Thank you for the detailed response! In trying to follow your email I got a bit confused by your notation - const :: a -> b -> a const x y = x could read a -> {S} -> b ->{L} a > Here, we have annotated the function-space constructor (->) with > information about whether the corresponding function is strict or lazy in > its argument. Indeed, const is lazy in its first argument and lazy in its > second. Did you mean to say that const is *strict *in its first param and lazy in its second (since const _|_ y = _|_)? Also, can you explain your notation, how does a -> {S} -> b ->{L} a indicate the strictness? Why not just {S} a -> {L} b -> a? Best, Paul On Wed, Jun 17, 2009 at 6:31 AM, Stefan Holdermans wrote: > Dear Paul, > > This thread as well as your blog post is very interesting. Hopefully I can > add something more or less valuable to it. > > On your blog, you mention that your scheme for run-time strictness analysis > doesn't work out because it'll have you force a function first before you > can find out about its strictness. I guess this can be easily overcome by > separating the function from the strictness information it carries. > > One way to do this, would be by storing strictness information in the type > of a function. Actually, this is exactly what type-based approaches to > strictness analyses do. So, for example, an extended type of the function > const, > > const :: a -> b -> a > const x y = x > > could read > > a -> {S} -> b ->{L} a > > Here, we have annotated the function-space constructor (->) with > information about whether the corresponding function is strict or lazy in > its argument. Indeed, const is lazy in its first argument and lazy in its > second. (Note that this is very simple take on storing strictness > information in types: there is plenty more to say about it, but I will > refrain from that.) > > An annotated type like the one above can be easily inferred by a strictness > analyser. But what exactly is type inference? Well, one way to look at it is > a means to reconstruct typing information that was left out from the > program. For example, if we infer the type a -> b -> a for the const > function in Haskell, we are effectively completing the definition of const > with explicit type information. This information can then be stored in the > program. Using Java-like syntax: > > const (x :: a) (y :: b) = x > > So, now const takes two extra arguments, both of which are types rather > than values. When, calling a polymorphic function, type inference then > computes the type arguments for a specific instantiation of the polymorphic > function: > > const 2 'x' > > becomes > > const 2 'x' > > While typing information can proof valuable to have around at compile type, > we don't actually want types to be passed around at run time. Luckily, in > Haskell no run-time decisions can be made based on these type arguments, so > all these extra abstractions and applications can be erased when generating > code for a program. > > Pretty much the same holds for the strictness annotations that are inferred > by a strictness analyser. Inferring strictness can be thought of as > decorating the program. For instance, for const we get something like: > > const (x :: a{S}) (y :: b{L}) = x > > where a {S} indicates strictness and {L} laziness. > > Viewing strictness annotations as types, a natural step is to allow > functions to be polymorphic in their strictness annotations as well. This is > especially useful for higher-order functions. The function apply, for > example, > > apply :: (a -> b) -> a -> b > apply f x = f x > > is supposed to work on both strict and lazy functions. Moreover, depending > on whether we pass it a strict or a lazy function as its first argument, it > becomes, respectively, strict or lazy in its second argument. This insight > can be captured quite nicely by means of a type that is polymorphic in its > strictness annotations: > > (a ->{i} b) ->{S} ->{i} b > > Here, i is a strictness variable that is to be instantiated with either S > or L. Decorating the definition of apply may now yield something like > > apply {i} (f :: (a ->{i} b){S}) (x :: a{i}) > > Of course, just as with ordinary types, strictness annotations don't have > to be passed around at run-time: they can be erased from the program and all > that are made based on strictness information can then be made at compile > time. > > But what if we don't erase these annotations? Then we can use strictness > information to participate in run-time decisions as well---just as you > proposed. Let's explore that idea. > > Performing strictness analysis on foldl, > > foldl :: (b -> a -> b) -> b -> [a] -> b > foldl f e [] = e > foldl f e (x : xs) = foldl f (f e x) xs > > we find the annotated type > > (b ->{i} ->{j} b) ->{L} b ->{i} [a] ->{S} -> b > > Indeed, whether foldl is strict in its second argument depends on wether > its first argument is strict in its own first argument. Let's decorate the > definition of foldl accordingly: > > foldl {i} {j} (f :: (b ->{i} ->{j} b){L}) (e :: b{i}) (l :: > [a]{S}) = > case l of > [] -> e > x : xs -> foldl {i} {j} f (f e x) xs > > Allright, that's messy, but bear with me. (At this point, we could erase > the type arguments and only keep the strictness arguments for we only want > the latter to play a role at run time, but let's keep them both, just to be > uniform.) > > Now, let's apply the foldl to (+), 0, and [1 .. 1000000] assuming that (+) > is strict in both its arguments and specialised to Int, > > (+) :: Int ->{S} Int ->{S} Int > > and let's pass in the arguments in three steps. First we pass in the type > arguments: > > foldl :: (Int ->{i} Int ->{j} Int) ->{L} Int ->{i} [Int] ->{S} > Int > > Then the strictness arguments: > > foldl :: (Int ->{S} ->Int ->{S} Int) ->{L} Int ->{S} > [Int] ->{S} Int > > Now we have obtained a specialised version of foldl that is lazy in its > first argument and strict in its second and third argument! When passing in > the remaining three arguments we can thus indeed evaluate the second > argument before we pass it to foldl: > > foldl (+) (0) [1 .. 1000000] > > Moreover, this can be done for each recursive call as well, effectively > having the computation require constant space. > > So, the on strictness information depending decision that is to made here, > is to apply functions strictly or lazily. Funnily, if we are willing to do > the static part of the strictness analysis by hand, we can already > experiment a bit with this scheme in Haskell. (I've attached the source > code.) > > First, let us abstract from function types annotated with S or L and > introduce a type class: > > infixl 9 # > > class Fun f where > lam :: (a -> b) -> f a b > (#) :: f a b -> (a -> b) > > That is, functions are constructed by means of the method lam and applied > (destructed) by means of (#). > > Haskell's built-in lazy function space (->) provides a natural > implementation of the class: > > instance Fun (->) where > lam = id > (#) = ($) > > In addition, we provide a strict function-space constructor (:->): > > newtype a :-> b = S {unS :: a -> b} > > instance Fun (:->) where > lam = S > (#) = \f x -> unS f $! x > > Now we can have a "hand-annotated" version of foldl: > > foldl :: (Fun i, Fun j) => i b (j a b) -> i b ([a] :-> b) > foldl = lam $ \f -> lam $ \e -> lam $ \l -> case l of > [] -> e > x : xs -> foldl # f # (f # e # x) # xs > > Note how the type arguments i and j play the roles of the strictness > annotations from the explanation above. Furthermore we have replaced > Haskell's lambda abstraction by means of abstraction through lam and > Haskell's function application by application through (#). Apart from that, > this is just your ordinary foldl. Well... :-) > > What's important to note is that the transformation from the "normal" > definition of foldl to this annotated beast could be performed at compile > time by a strictness analyser. > > Now, let's try it out. Say we have two versions of addition on integers: a > lazy one (lplus) and a strict one (splus). Note the types: > > lplus :: Int -> Int -> Int > lplus = (+) > > splus :: Int :-> Int :-> Int > splus = lam $ \m -> lam $ \n -> ((+) $! m) $! n > > There we go: > > *Main> foldl # lplus # 0 # [1 .. 1000000] > *** Exception: stack overflow > > *Main> foldl # splus # 0 # [1 .. 1000000] > 1784293664 > > Isn't that neat? > > Of course, whether this scheme would work out in practice depends on > whether the cost of lazy evaluation really outweighs the cost of passing > around strictness information. I'm not so sure, but I would be interested to > see the results of experiments with this idea. An important factor seems to > be how much strictness information that is passed around in a naive > implementation of this scheme can be eliminated by "normal" compiler > optimisations. > > Well, just my two cents. :-) > > Cheers, > > Stefan > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090617/9aa0efb3/attachment-0001.html From lennart at augustsson.net Wed Jun 17 18:32:55 2009 From: lennart at augustsson.net (Lennart Augustsson) Date: Wed Jun 17 18:16:10 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <92e42b740906171405n2207827amf94471ef413fe22d@mail.gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <20090616031849.GA5253@liouville.galois.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> <8942CD18-8F65-411A-A0B1-C938DF219314@gmail.com> <92e42b740906171250w2dc15d44o36346117f55d8fd5@mail.gmail.com> <92e42b740906171405n2207827amf94471ef413fe22d@mail.gmail.com> Message-ID: The creators of Haskell didn't pick any particular representation for numbers. (Well, literals are kind of Integers.) You can pick what types you make instances of Num. Some of them are lazy, some of them are strict. On Wed, Jun 17, 2009 at 11:05 PM, Keith Sheppard wrote: > In lambda calculus numbers are just functions and you evaluate them > just like any other function. Haskell could have chosen the same > representation for numbers and all evaluation on numbers would be lazy > (assuming normal order evaluation). I think that would have been the > "Purist Lazy" way to go. That is not the way the creators of Haskell > designed language though... am i missing something? > > On Wed, Jun 17, 2009 at 4:05 PM, Lennart > Augustsson wrote: >> What do you mean by "literals are strict"? ?Strictness is a semantic >> property of functions, and while literals can be overloaded to be >> functions I don't know what you mean. >> >> On Wed, Jun 17, 2009 at 9:50 PM, Keith Sheppard wrote: >>> Haskell's numeric literals are strict. You wouldn't want that to >>> change right? It seems to me that having sum and product be strict is >>> consistent with this. >>> >>> -Keith >>> >>> On Wed, Jun 17, 2009 at 11:15 AM, Thomas Davie wrote: >>>> >>>> On 17 Jun 2009, at 13:32, Yitzchak Gale wrote: >>>> >>>>> Henk-Jan van Tuyl wrote: >>>>>> >>>>>> reverse >>>>>> maximum >>>>>> minimum >>>>> >>>>> Oh yes, please fix those also! >>>> >>>> import Prelude.Strict? >>>> >>>> Honestly, these functions are ones that I've *deffinately* used lazy >>>> versions of, in fact, in the cases of minimum/maximum I've even used ones >>>> that are super-lazy and parallel using unamb. >>>> >>>> It would be extremely odd to randomly decide "most people would want this to >>>> be strict" based on no knowledge of what they're actually doing. ?Instead, >>>> why don't we stand by the fact that haskell is a lazy language, and that the >>>> functions we get by default are lazy, and then write a strict prelude as I >>>> suggest above to complement the lazy version. >>>> >>>> Bob >>>> _______________________________________________ >>>> Haskell-Cafe mailing list >>>> Haskell-Cafe@haskell.org >>>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>>> >>> >>> >>> >>> -- >>> keithsheppard.name >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> Haskell-Cafe@haskell.org >>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>> >> > > > > -- > keithsheppard.name > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From gue.schmidt at web.de Wed Jun 17 18:38:22 2009 From: gue.schmidt at web.de (Guenther Schmidt) Date: Wed Jun 17 18:21:40 2009 Subject: [Haskell-cafe] Re: Which windowing toolkit to use? In-Reply-To: <16310701678.20090618011128@gmail.com> References: <1245232582.7315.1320797515@webmail.messagingengine.com> <16310701678.20090618011128@gmail.com> Message-ID: <4A39705E.5030102@web.de> Hi Bulat, well, do a cabal install hs-dotnet. Then do a cabal unpack hs-dotnet and look into the examples directory, there are 2 for gui, Forms and FileSelect. If they don't work right away then follow the instructions for aquanting the .dll in the bin directory with the NET framework. The LINQ examples will only work if you have .NET 3.5 installed, the gui examples even with .NET 2.0. Good luck and come back for more if you like :) G?nther PS: The galois inc. guys are amazingly practical code contributors, the link to Sigbjorns website is on hackage, the hs-dotnet package. Bulat Ziganshin schrieb: > Hello Gu?nther, > > Thursday, June 18, 2009, 12:46:40 AM, you wrote: > > >> there is one other alternative to gtk2hs and wxhaskell: .NET Forms >> > > >> It is accessable through Sigbjorn Finne's hs-dotnet package. >> > > >> I am right now *starting* to use it myself, so just consider it an option. >> > > can you please provide code snippets? some starting basis will greatly > help to grok this way of GUI > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090617/403c8aab/attachment.html From niklas.broberg at gmail.com Wed Jun 17 18:42:35 2009 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Wed Jun 17 18:25:49 2009 Subject: [Haskell-cafe] Re: ANN: haskell-src-exts 1.0.0 rc1 (aka 0.5.2) In-Reply-To: References: Message-ID: Hi all, > This means I feel ready to take that scary leap that means to drop the > safe 0.x version numbering (experimental) and finally make the first > stable release, version 1.0.0. But before I take that leap I want the > library to be thoroughly tested, so I can with confidence say that it > truly *is* stable. Therefore, I hereby announce the release on hackage > of haskell-src-exts-0.5.2, which I consider (almost) a release > candidate for 1.0.0. I have just uploaded haskell-src-exts-0.5.4 to hackage, which is 1.0.0 rc2. Thanks a lot to those who tested the previous version, and please continue to test and report! Changes in 0.5.4: ================== Three fixed bugs: * BangPatterns are now parsed correctly in function bindings. * Single-item class contexts are now accepted with parenthesis around them (doh!). * The haddock documentation (paltry as it is) can now be built. Thanks a lot to Brian Lewis for the patch, which rearranges my commented guard clause. Haddock apparently didn't like the '{- | guard = ...' line... One new feature: * The parseFileX family of functions now all recognize and act on LANGUAGE pragmas (previously only parseFile did). There is now also an extra field in the ParseMode called 'ignoreLanguagePragmas', which defaults to False. Set it to True if you really want parseFile et al to disregard LANGUAGE pragmas. (Note that you can always use the simple 'parse' function that doesn't try to be clever at all.) Cheers, /Niklas From gue.schmidt at web.de Wed Jun 17 18:44:16 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Wed Jun 17 18:27:42 2009 Subject: [Haskell-cafe] Re: Which windowing toolkit to use? In-Reply-To: <4A395B52.2050305@therning.org> References: <1245232582.7315.1320797515@webmail.messagingengine.com> <4A395B52.2050305@therning.org> Message-ID: Magnus Therning schrieb: > G??nther Schmidt wrote: >> Hi Patai, >> >> there is one other alternative to gtk2hs and wxhaskell: .NET Forms >> >> It is accessable through Sigbjorn Finne's hs-dotnet package. > > Is that usable with mono? Sorry Magnus, dunno. The galois guys provide a lot of really really useful code, I surmise they use it themselves quit a lot, but, the instructions are a bit sparse and since they actually make a living writing haskell code they propably just don't have much time for that. > > I certainly hope that something as useful as the heap profiling > toolkit's GUI > won't be a Windows-only thing. > > Is the plan to make the heap profiling ship with GHC? > > In that case it might be ill advised to add a dependency on dot-net/mono. > Though it could be argued it's just as ill advised to add a dependency on > GTK/WX. > > /M > > > ------------------------------------------------------------------------ > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From ryani.spam at gmail.com Wed Jun 17 20:33:06 2009 From: ryani.spam at gmail.com (Ryan Ingram) Date: Wed Jun 17 20:16:19 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? In-Reply-To: References: <57A134DD-CF18-4502-AC0D-C7B7265576AD@cs.uu.nl> Message-ID: <2f9b2d30906171733n3ed24f0dw934f25fd463428f7@mail.gmail.com> Also, partial application + seq throws a wrench in things: seq (const undefined) () == () /= seq undefined () but seq (const undefined ()) () == undefined == seq undefined () So const is only strict in its first argument when fully applied; I think any strictness annotation would have to have information about *when* the strictness applies. That is, these two functions need to have different types: const1 = \x -> seq x (\y -> x) const2 = \x ->\y -> x The first is strict always whereas the second is only strict when fully applied. -- ryan On Wed, Jun 17, 2009 at 3:07 PM, Paul Chiusano wrote: > Stefan, > Thank you for the detailed response! In trying to follow your email I got a > bit confused by your notation - >> >> ?const :: a -> b -> a >> >> ?const x y = x >> >> could read >> >> ?a -> {S} -> b ->{L} a > > >> >> Here, we have annotated the function-space constructor (->) with >> information about whether the corresponding function is strict or lazy in >> its argument. Indeed, const is lazy in its first argument and lazy in its >> second. > > Did you mean to say that const is strict in its first param and lazy in its > second (since const _|_ y = _|_)? Also, can you explain your notation, how > does a -> {S} -> b ->{L} a indicate the strictness? Why not just {S} a -> > {L} b -> a? > Best, > Paul > > On Wed, Jun 17, 2009 at 6:31 AM, Stefan Holdermans wrote: >> >> Dear Paul, >> >> This thread as well as your blog post is very interesting. Hopefully I can >> add something more or less valuable to it. >> >> On your blog, you mention that your scheme for run-time strictness >> analysis doesn't work out because it'll have you force a function first >> before you can find out about its strictness. I guess this can be easily >> overcome by separating the function from the strictness information it >> carries. >> >> One way to do this, would be by storing strictness information in the type >> of a function. Actually, this is exactly what type-based approaches to >> strictness analyses do. So, for example, an extended type of the function >> const, >> >> ?const :: a -> b -> a >> ?const x y = x >> >> could read >> >> ?a -> {S} -> b ->{L} a >> >> Here, we have annotated the function-space constructor (->) with >> information about whether the corresponding function is strict or lazy in >> its argument. Indeed, const is lazy in its first argument and lazy in its >> second. (Note that this is very simple take on storing strictness >> information in types: there is plenty more to say about it, but I will >> refrain from that.) >> >> An annotated type like the one above can be easily inferred by a >> strictness analyser. But what exactly is type inference? Well, one way to >> look at it is a means to reconstruct typing information that was left out >> from the program. For example, if we infer the type a -> b -> a for the >> const function in Haskell, we are effectively completing the definition of >> const with explicit type information. This information can then be stored in >> the program. Using Java-like syntax: >> >> ?const (x :: a) (y :: b) = x >> >> So, now const takes two extra arguments, both of which are types rather >> than values. When, calling a polymorphic function, type inference then >> computes the type arguments for a specific instantiation of the polymorphic >> function: >> >> ?const 2 'x' >> >> becomes >> >> ?const 2 'x' >> >> While typing information can proof valuable to have around at compile >> type, we don't actually want types to be passed around at run time. Luckily, >> in Haskell no run-time decisions can be made based on these type arguments, >> so all these extra abstractions and applications can be erased when >> generating code for a program. >> >> Pretty much the same holds for the strictness annotations that are >> inferred by a strictness analyser. Inferring strictness can be thought of as >> decorating the program. For instance, for const we get something like: >> >> ?const (x :: a{S}) (y :: b{L}) = x >> >> where a {S} indicates strictness and {L} laziness. >> >> Viewing strictness annotations as types, a natural step is to allow >> functions to be polymorphic in their strictness annotations as well. This is >> especially useful for higher-order functions. The function apply, for >> example, >> >> ?apply :: (a -> b) -> a -> b >> ?apply f x = f x >> >> is supposed to work on both strict and lazy functions. ?Moreover, >> depending on whether we pass it a strict or a lazy function as its first >> argument, it becomes, respectively, strict or lazy in its second argument. >> This insight can be captured quite nicely by means of a type that is >> polymorphic in its strictness annotations: >> >> ?(a ->{i} b) ->{S} ->{i} b >> >> Here, i is a strictness variable that is to be instantiated with either S >> or L. Decorating the definition of apply may now yield something like >> >> ?apply {i} (f :: (a ->{i} b){S}) (x :: a{i}) >> >> Of course, just as with ordinary types, strictness annotations don't have >> to be passed around at run-time: they can be erased from the program and all >> that are made based on strictness information can then be made at compile >> time. >> >> But what if we don't erase these annotations? Then we can use strictness >> information to participate in run-time decisions as well---just as you >> proposed. Let's explore that idea. >> >> Performing strictness analysis on foldl, >> >> ?foldl :: (b -> a -> b) -> b -> [a] -> b >> ?foldl f e [] ? ? ? = e >> ?foldl f e (x : xs) = foldl f (f e x) xs >> >> we find the annotated type >> >> ?(b ->{i} ->{j} b) ->{L} b ->{i} [a] ->{S} -> b >> >> Indeed, whether foldl is strict in its second argument depends on wether >> its first argument is strict in its own first argument. Let's decorate the >> definition of foldl accordingly: >> >> ?foldl {i} {j} (f :: (b ->{i} ->{j} b){L}) (e :: b{i}) (l :: >> [a]{S}) = >> ? ?case l of >> ? ? ?[] ? ? -> e >> ? ? ?x : xs -> foldl {i} {j} f (f e x) xs >> >> Allright, that's messy, but bear with me. (At this point, we could erase >> the type arguments and only keep the strictness arguments for we only want >> the latter to play a role at run time, but let's keep them both, just to be >> uniform.) >> >> Now, let's apply the foldl to (+), 0, and [1 .. 1000000] assuming that (+) >> is strict in both its arguments and specialised to Int, >> >> ?(+) :: Int ->{S} Int ->{S} Int >> >> and let's pass in the arguments in three steps. First we pass in the type >> arguments: >> >> ?foldl :: (Int ->{i} Int ->{j} Int) ->{L} Int ->{i} [Int] >> ->{S} Int >> >> Then the strictness arguments: >> >> ?foldl :: (Int ->{S} ->Int ->{S} Int) ->{L} Int ->{S} >> [Int] ->{S} Int >> >> Now we have obtained a specialised version of foldl that is lazy in its >> first argument and strict in its second and third argument! When passing in >> the remaining three arguments we can thus indeed evaluate the second >> argument before we pass it to foldl: >> >> ?foldl (+) (0) [1 .. 1000000] >> >> Moreover, this can be done for each recursive call as well, effectively >> having the computation require constant space. >> >> So, the on strictness information depending decision that is to made here, >> is to apply functions strictly or lazily. Funnily, if we are willing to do >> the static part of the strictness analysis by hand, we can already >> experiment a bit with this scheme in Haskell. (I've attached the source >> code.) >> >> First, let us abstract from function types annotated with S or L and >> introduce a type class: >> >> ?infixl 9 # >> >> ?class Fun f where >> ? ?lam :: (a -> b) -> f a b >> ? ?(#) :: f a b -> (a -> b) >> >> That is, functions are constructed by means of the method lam and applied >> (destructed) by means of (#). >> >> Haskell's built-in lazy function space (->) provides a natural >> implementation of the class: >> >> ?instance Fun (->) where >> ? ?lam = id >> ? ?(#) = ($) >> >> In addition, we provide a strict function-space constructor (:->): >> >> ?newtype a :-> b = S {unS :: a -> b} >> >> ?instance Fun (:->) where >> ? ?lam = S >> ? ?(#) = \f x -> unS f $! x >> >> Now we can have a "hand-annotated" version of foldl: >> >> ?foldl :: (Fun i, Fun j) => i b (j a b) -> i b ([a] :-> b) >> ?foldl = lam $ \f -> lam $ \e -> lam $ \l -> case l of >> ? ? ? ? ? ?[] ? ? -> e >> ? ? ? ? ? ?x : xs -> foldl # f # (f # e # x) # xs >> >> Note how the type arguments i and j play the roles of the strictness >> annotations from the explanation above. Furthermore we have replaced >> Haskell's lambda abstraction by means of abstraction through lam and >> Haskell's function application by application through (#). Apart from that, >> this is just your ordinary foldl. Well... :-) >> >> What's important to note is that the transformation from the "normal" >> definition of foldl to this annotated beast could be performed at compile >> time by a strictness analyser. >> >> Now, let's try it out. Say we have two versions of addition on integers: a >> lazy one (lplus) and a strict one (splus). Note the types: >> >> ?lplus :: Int -> Int -> Int >> ?lplus = (+) >> >> ?splus :: Int :-> Int :-> Int >> ?splus = lam $ \m -> lam $ \n -> ((+) $! m) $! n >> >> There we go: >> >> ?*Main> foldl # lplus # 0 # [1 .. 1000000] >> ?*** Exception: stack overflow >> >> ?*Main> foldl # splus # 0 # [1 .. 1000000] >> ?1784293664 >> >> Isn't that neat? >> >> Of course, whether this scheme would work out in practice depends on >> whether the cost of lazy evaluation really outweighs the cost of passing >> around strictness information. I'm not so sure, but I would be interested to >> see the results of experiments with this idea. An important factor seems to >> be how much strictness information that is passed around in a naive >> implementation of this scheme can be eliminated by "normal" compiler >> optimisations. >> >> Well, just my two cents. :-) >> >> Cheers, >> >> ?Stefan >> >> >> >> > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > From ryant5000 at gmail.com Wed Jun 17 20:38:54 2009 From: ryant5000 at gmail.com (Ryan Trinkle) Date: Wed Jun 17 20:29:54 2009 Subject: [Haskell-cafe] Creating a new Haskell mailing list Message-ID: <442d2c4c0906171738r21b8ac36u1efb8803202185ed@mail.gmail.com> Hi all, I'm interested in starting a mailing list on haskell.org. Who should I talk to about such things? Thanks, Ryan -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090617/9b1d3cda/attachment.html From conal at conal.net Wed Jun 17 20:57:08 2009 From: conal at conal.net (Conal Elliott) Date: Wed Jun 17 20:40:41 2009 Subject: [Haskell-cafe] Haskell-based iPhone development Message-ID: If you are working with Haskell and making iPhone apps, or if you intend to soon, please say so at http://haskell.org/haskellwiki/IPhone. By helping each other out, I hope we can work more productively and have more fun in the process. At this point, I'd like to find out what you'd like to share, what help you'd like from others, and generally what kind of apps you want to make. We'll see what evolves from there. - Conal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090617/cc9430ef/attachment.html From jstrait at moonloop.net Wed Jun 17 21:08:29 2009 From: jstrait at moonloop.net (Jon Strait) Date: Wed Jun 17 20:58:11 2009 Subject: [Haskell-cafe] Confusion on the third monad law when using lambda abstractions Message-ID: <4A39938D.7020400@moonloop.net> Hi everyone, I use and love Haskell, but I just have this nagging concern, that maybe someone can help me reason about. If I'm missing something completely obvious here and making the wrong assumptions, please be gentle. :) I'm reading the third (bind associativity) law for monads in this form: m >>= (\x -> k x >>= h) = (m >>= k) >>= h Now considering the definition of liftM2: liftM2 f m1 m2 = m1 >>= (\x1 -> m2 >>= (\x2 -> return (f x1 x2))) Isn't this liftM2 definition in the same form as the LHS of the third law equation, with (\x2 -> return (f x1 x2)) being the h function? Comparing this definition with the third law equation, the equation doesn't work because on the RHS equivalent; the x1 argument would be lost. So, why wasn't I finding a mention of a qualification that states that the third law only applies as long as the function in the h position doesn't reference arguments bound from previous 'binds'? It took going all the way back to Philip Wadler's 1992 paper, 'Monads for functional programming' to find reassurance: "The scope of variable x includes h on the left but excludes h on the right, so this law is valid only when x does not appear free in h." I'm also thinking of the Maybe monad, where Nothing >>= \x -> Just (x + 1) >>= \y -> return (y + 2) evaluates to Nothing after the first monadic bind and doesn't evaluate the rest of the expression. However, Nothing >>= Just . (+ 1) >>= return . (+ 2) should evaluate through the first and second monadic bind, evaluating to Nothing each time, of course. For the Maybe monad, both expressions give the same result, but if there were another monad defined like, data MadMaybe a = Nothing | Perhaps | Just a instance Monad MadMaybe where (Just x) >>= k = k x Nothing >>= _ = Perhaps Perhaps >>= _ = Nothing - then the two previous expressions run in the MadMaybe monad would evaluate to different values. Since the first of the previous expressions evaluates like the LHS of the third law equation above and the second expression evaluates like the RHS, the expressions should be equivalent, but they are not. Does this put into question the third monad law's relevance to Haskell monads, or is it that MadMaybe shouldn't be made a monad because it violates the third law? Thanks for any insight. Jon From dpiponi at gmail.com Wed Jun 17 21:24:52 2009 From: dpiponi at gmail.com (Dan Piponi) Date: Wed Jun 17 21:08:05 2009 Subject: [Haskell-cafe] Confusion on the third monad law when using lambda abstractions In-Reply-To: <4A39938D.7020400@moonloop.net> References: <4A39938D.7020400@moonloop.net> Message-ID: <625b74080906171824w63397546ldb3dfa9b0dd85c8a@mail.gmail.com> On Wed, Jun 17, 2009 at 6:08 PM, Jon Strait wrote: > ...but if there > were another monad defined like, > > data MadMaybe a = Nothing | Perhaps | Just a MadMaybe violates the second law. It's quite unlike a monad. -- Dan From gale at sefer.org Wed Jun 17 21:47:14 2009 From: gale at sefer.org (Yitzchak Gale) Date: Wed Jun 17 21:30:48 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A38FB19.5080704@gmail.com> References: <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <2608b8a80906170521k70ec3269k992b0db1fca4e5ec@mail.gmail.com> <4A38E5BF.8080005@gmail.com> <2608b8a80906170703h2985bd0ai5622fc1ddda6adf@mail.gmail.com> <4A38FB19.5080704@gmail.com> Message-ID: <2608b8a80906171847s59f1782fkbe45a6eaa3b24c8f@mail.gmail.com> I wrote: >> OK, would you like me to reflect this discussion in tickets? >> Let's see, so far we have #3300, I don't see anything else. >> >> Do you want two tickets, one each for WIndows/Unix? Or >> four, separating the FilePath and getArgs issues? Simon Marlow wrote: > One for each issue is usually better, so four. OK, they are: #3300, #3307, #3308, #3309. Regards, Yitz From jake.mcarthur at gmail.com Wed Jun 17 22:26:14 2009 From: jake.mcarthur at gmail.com (Jake McArthur) Date: Wed Jun 17 22:09:29 2009 Subject: [Haskell-cafe] Confusion on the third monad law when using lambda abstractions In-Reply-To: <4A39938D.7020400@moonloop.net> References: <4A39938D.7020400@moonloop.net> Message-ID: <4A39A5C6.2060102@gmail.com> Jon Strait wrote: > I'm reading the third (bind associativity) law for monads in this form: > > m >>= (\x -> k x >>= h) = (m >>= k) >>= h Arguably, that law would be better stated as: (h <=< k) <=< m = h <=< (k <=< m) This wouldn't be so unintuitive. - Jake From dave at zednenem.com Wed Jun 17 23:11:30 2009 From: dave at zednenem.com (David Menendez) Date: Wed Jun 17 23:12:30 2009 Subject: [Haskell-cafe] Confusion on the third monad law when using lambda abstractions In-Reply-To: <4A39938D.7020400@moonloop.net> References: <4A39938D.7020400@moonloop.net> Message-ID: <49a77b7a0906172011w106ceb5bxb6ea6cb751884800@mail.gmail.com> On Wed, Jun 17, 2009 at 9:08 PM, Jon Strait wrote: > I use and love Haskell, but I just have this nagging concern, that maybe > someone can help me reason about. ?If I'm missing something completely > obvious here and making the wrong assumptions, please be gentle. ?:) > > I'm reading the third (bind associativity) law for monads in this form: > > m >>= (\x -> k x >>= h) ?= ?(m >>= k) >>= h > > Now considering the definition of liftM2: > > liftM2 f m1 m2 = m1 >>= (\x1 -> m2 >>= (\x2 -> return (f x1 x2))) > > Isn't this liftM2 ?definition in the same form as the LHS of the third law > equation, with (\x2 -> return (f x1 x2)) being the h function? The usual convention here is that m, k, and h are variables bound outside the scope of the law. In other words, the law only applies to expressions which can be rewritten to have the form let m = ... k = ... h = ... in m >>= (\x -> k x >>= h) In the case of liftM2, you'd have to rewrite it as, liftM2 f m1 m2 = m >>= \x -> k x >>= h where m = m1 k = \x -> m2 >>= \y -> return (x,y) h = \(x,y) -> return (f x y) which is awkward, but works perfectly fine with the third law. -- Dave Menendez From vigalchin at gmail.com Thu Jun 18 00:53:28 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Thu Jun 18 00:36:41 2009 Subject: [Haskell-cafe] Haskell on Android Message-ID: <5ae4f2ba0906172153ue7b7695k3f4c87bb758b126b@mail.gmail.com> Hello, Let me change the subject ... I think everybody understood my "thrust" but let me make more provocative. Don, please let me expose my ignorance for the greater good and time my personal scorn ;^) ... "EDSL" time => Embedded Domain-Specific Language?? If so, can you please be more specific! I don't mind to be a grunt for Haskell. Kind regards, Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090618/f37d1dd8/attachment.html From dagit at codersbase.com Thu Jun 18 01:26:23 2009 From: dagit at codersbase.com (Jason Dagit) Date: Thu Jun 18 01:09:37 2009 Subject: [Haskell-cafe] Haskell on Android In-Reply-To: <5ae4f2ba0906172153ue7b7695k3f4c87bb758b126b@mail.gmail.com> References: <5ae4f2ba0906172153ue7b7695k3f4c87bb758b126b@mail.gmail.com> Message-ID: On Wed, Jun 17, 2009 at 9:53 PM, Vasili I. Galchin wrote: > Hello, > > Let me change the subject ... I think everybody understood my "thrust" > but let me make more provocative. Don, please let me expose my ignorance for > the greater good and time my personal scorn ;^) ... "EDSL" time => Embedded > Domain-Specific Language?? If so, can you please be more specific! I don't > mind to be a grunt for Haskell. Yes, EDSL is Embedded Domain-Specific Language. Although, I'm not sure I understand what you are asking. I looked at the wiki page which Conal created and he does mention using an EDSL in Haskell to generate code. Perhaps this is what you want to know more about? There is a paper linked from the wiki page that should help a lot with answering questions you have about the technique. For a simple example of how it can work, I wrote a program called Autoproc that 'compiles' the haskell EDSL into a procmail recipe. You can find the source code here: darcs get http://projects.codersbase.com/repos/autoproc/ It's really not much code so it should be easy to wrap your mind around it. I call the above code simple, but it works quite well and illustrates that a little bit of Haskell can go a long ways :) How it works is that the expressions you code up in Haskell build up values which correspond to the abstract syntax, or your intermediate representation. You can then transform that representation and do whatever a compiler or translator would normally do and the target format is some other language or machine code. This technique allows you to reuse the facilites of the host language, such as strong static typing and laziness, the parser, standard libs and so on. It's a great way to prototype a language and work out the kinks before you invest in making a stand alone implementation. And all that aside, it's just plain fun. I hope that helps, Jason -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090618/006697c2/attachment.html From dagit at codersbase.com Thu Jun 18 01:34:51 2009 From: dagit at codersbase.com (Jason Dagit) Date: Thu Jun 18 01:18:06 2009 Subject: [Haskell-cafe] Haskell on Android In-Reply-To: References: <5ae4f2ba0906172153ue7b7695k3f4c87bb758b126b@mail.gmail.com> Message-ID: Oh, and here is the wiki page I mentioned: http://haskell.org/haskellwiki/IPhone On Wed, Jun 17, 2009 at 10:26 PM, Jason Dagit wrote: > > > On Wed, Jun 17, 2009 at 9:53 PM, Vasili I. Galchin wrote: > >> Hello, >> >> Let me change the subject ... I think everybody understood my >> "thrust" but let me make more provocative. Don, please let me expose my >> ignorance for the greater good and time my personal scorn ;^) ... "EDSL" >> time => Embedded Domain-Specific Language?? If so, can you please be more >> specific! I don't mind to be a grunt for Haskell. > > > Yes, EDSL is Embedded Domain-Specific Language. Although, I'm not sure I > understand what you are asking. I looked at the wiki page which Conal > created and he does mention using an EDSL in Haskell to generate code. > Perhaps this is what you want to know more about? > > There is a paper linked from the wiki page that should help a lot with > answering questions you have about the technique. For a simple example of > how it can work, I wrote a program called Autoproc that 'compiles' the > haskell EDSL into a procmail recipe. You can find the source code here: > darcs get http://projects.codersbase.com/repos/autoproc/ > > It's really not much code so it should be easy to wrap your mind around > it. I call the above code simple, but it works quite well and illustrates > that a little bit of Haskell can go a long ways :) > > How it works is that the expressions you code up in Haskell build up values > which correspond to the abstract syntax, or your intermediate > representation. You can then transform that representation and do whatever > a compiler or translator would normally do and the target format is some > other language or machine code. > > This technique allows you to reuse the facilites of the host language, such > as strong static typing and laziness, the parser, standard libs and so on. > It's a great way to prototype a language and work out the kinks before you > invest in making a stand alone implementation. And all that aside, it's > just plain fun. > > I hope that helps, > Jason > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090618/ebad5a2a/attachment.html From stefan at cs.uu.nl Thu Jun 18 00:31:49 2009 From: stefan at cs.uu.nl (Stefan Holdermans) Date: Thu Jun 18 01:22:25 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? In-Reply-To: <2f9b2d30906171733n3ed24f0dw934f25fd463428f7@mail.gmail.com> References: <57A134DD-CF18-4502-AC0D-C7B7265576AD@cs.uu.nl> <2f9b2d30906171733n3ed24f0dw934f25fd463428f7@mail.gmail.com> Message-ID: <5D93BA1E-4D26-4D60-9A57-F035C7F6A01D@cs.uu.nl> Ryan, > Also, partial application + seq throws a wrench in things: [...] You're absolutely right. I did not take into account the effects of seq in my previous post. However, this is exactly the subject of a paper I presented at TFP, two weeks ago. A revised version of the paper will be available soon; slided can already be picked up from http://people.cs.uu.nl/stefan/pubs/holdermans09spreading.html . Cheers, Stefan From stefan at cs.uu.nl Thu Jun 18 00:19:31 2009 From: stefan at cs.uu.nl (Stefan Holdermans) Date: Thu Jun 18 01:22:33 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? In-Reply-To: References: <57A134DD-CF18-4502-AC0D-C7B7265576AD@cs.uu.nl> Message-ID: <706E19D9-D2C2-4CE3-95DC-AE5C0688A22E@cs.uu.nl> Paul, > In trying to follow your email I got a bit confused by your notation - > > const :: a -> b -> a const x y = x could read a -> {S} -> b - > >{L} a > > Here, we have annotated the function-space constructor (->) with > information about whether the corresponding function is strict or > lazy in its argument. Indeed, const is lazy in its first argument > and lazy in its second. > > Did you mean to say that const is strict in its first param and lazy > in its second (since const _|_ y = _|_)? Also, can you explain your > notation, how does a -> {S} -> b ->{L} a indicate the strictness? > Why not just {S} a -> {L} b -> a? I'm sorry for the confusion. Indeed, const, as the type was intended to reflect, const is strict in its first argument and lazy in its second. I prefer to put the annotation on the function arrow as strictness is a property of functions, but if you want to have these annotations prefixing the argument types, then I guess that's fine as well; in the end, it really doesn't matter, does it? Cheers, Stefan From jason.dusek at gmail.com Thu Jun 18 01:53:14 2009 From: jason.dusek at gmail.com (Jason Dusek) Date: Thu Jun 18 01:36:26 2009 Subject: [Haskell-cafe] (fwd) Haskell logo fail In-Reply-To: References: Message-ID: <42784f260906172253p2f14d71auf936b7a6db8bdb3d@mail.gmail.com> Why don't we have a picture of a cool dinosaur instead? -- Jason Dusek From vigalchin at gmail.com Thu Jun 18 02:20:33 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Thu Jun 18 02:03:46 2009 Subject: [Haskell-cafe] Haskell on Android In-Reply-To: References: <5ae4f2ba0906172153ue7b7695k3f4c87bb758b126b@mail.gmail.com> Message-ID: <5ae4f2ba0906172320r50eacf46ma4e78704f3e2c1b3@mail.gmail.com> On Thu, Jun 18, 2009 at 12:26 AM, Jason Dagit wrote: > > > On Wed, Jun 17, 2009 at 9:53 PM, Vasili I. Galchin wrote: > >> Hello, >> >> Let me change the subject ... I think everybody understood my >> "thrust" but let me make more provocative. Don, please let me expose my >> ignorance for the greater good and time my personal scorn ;^) ... "EDSL" >> time => Embedded Domain-Specific Language?? If so, can you please be more >> specific! I don't mind to be a grunt for Haskell. > > > Yes, EDSL is Embedded Domain-Specific Language. Although, I'm not sure I > understand what you are asking. I looked at the wiki page which Conal > created and he does mention using an EDSL in Haskell to generate code. > Perhaps this is what you want to know more about? > > There is a paper linked from the wiki page that should help a lot with > answering questions you have about the technique. For a simple example of > how it can work, I wrote a program called Autoproc that 'compiles' the > haskell EDSL into a procmail recipe. You can find the source code here: > darcs get http://projects.codersbase.com/repos/autoproc/ > ^^^ cool .. thx. > > > It's really not much code so it should be easy to wrap your mind around > it. I call the above code simple, but it works quite well and illustrates > that a little bit of Haskell can go a long ways :) > ;^) > > > How it works is that the expressions you code up in Haskell build up values > which correspond to the abstract syntax, or your intermediate > representation. You can then transform that representation and do whatever > a compiler or translator would normally do and the target format is some > other language or machine code. > . let me read carefully .. thx. > > > This technique allows you to reuse the facilites of the host language, such > as strong static typing and laziness, the parser, standard libs and so on. > It's a great way to prototype a language and work out the kinks before you > invest in making a stand alone implementation. And all that aside, it's > just plain fun. > again ;^) Vasili > > > I hope that helps, > Jason > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090618/a61ad0ef/attachment.html From johan.tibell at gmail.com Thu Jun 18 02:24:50 2009 From: johan.tibell at gmail.com (Johan Tibell) Date: Thu Jun 18 02:08:23 2009 Subject: [Haskell-cafe] ANNOUNCE: hyena Message-ID: <90889fe70906172324i63e49ac6n123c87ef306b0e07@mail.gmail.com> I am pleased to announce the first release of hyena, a library for building web servers, based on the work on iteratee style I/O by Oleg Kiselyov. The library allows you to create web servers that consume their input incrementally, without resorting to lazy I/O. This should lead to more predictable resource usage. This is an early alpha release so expect the API to change in the future. In particular, I'm working on converting the current definition of iteratees/enumerators used to the one in the iteratee package [1]. I decided to release this version, based on a simple left fold, due to requests by several people who already started using hyena. Get it: cabal install hyena And on Hackage: http://hackage.haskell.org//package/hyena 1. http://hackage.haskell.org/package/iteratee -- Johan -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090618/342d3595/attachment.html From jon.fairbairn at cl.cam.ac.uk Thu Jun 18 03:08:31 2009 From: jon.fairbairn at cl.cam.ac.uk (Jon Fairbairn) Date: Thu Jun 18 02:53:15 2009 Subject: [Haskell-cafe] Re: (fwd) Haskell logo fail References: <42784f260906172253p2f14d71auf936b7a6db8bdb3d@mail.gmail.com> Message-ID: Jason Dusek writes: > Why don't we have a picture of a cool dinosaur instead? Something cool because the last heat of life went out of it 65 million years ago? -- J?n Fairbairn Jon.Fairbairn@cl.cam.ac.uk From noteed at gmail.com Thu Jun 18 03:17:07 2009 From: noteed at gmail.com (minh thu) Date: Thu Jun 18 03:00:40 2009 Subject: [Haskell-cafe] Re: (fwd) Haskell logo fail In-Reply-To: References: <42784f260906172253p2f14d71auf936b7a6db8bdb3d@mail.gmail.com> Message-ID: <40a414c20906180017k250eeda9r9e479b7be7512a98@mail.gmail.com> 2009/6/18 Jon Fairbairn : > Jason Dusek writes: > >> Why don't we have a picture of a cool dinosaur instead? > > Something cool because the last heat of life went out of it > 65 million years ago? "made with secret dinosaur technology" Thu From sjoerd at w3future.com Thu Jun 18 03:57:02 2009 From: sjoerd at w3future.com (Sjoerd Visscher) Date: Thu Jun 18 03:40:25 2009 Subject: [Haskell-cafe] ANNOUNCE fmlist In-Reply-To: References: Message-ID: <471C27BA-2DA7-4449-9AF8-4353AA9A4FED@w3future.com> I am pleased to announce the first release of Data.FMList, lists represented by their foldMap function: > newtype FMList a = FM { unFM :: forall b . Monoid b => (a -> b) -> b } It has O(1) cons, snoc and append, just like difference lists. Fusion is more or less built-in, for f.e. fmap and (>>=), but I'm not sure if this gives any advantages over what a compiler like GHC can do for regular lists. My interest in this was purely the coding exercise, and I think there are some nice lines of code in there, for example: > reverse l = FM $ \f -> getDual $ unFM l (Dual . f) If you like folds or monoids, you certainly should take a look. One fun example: > -- A right-infinite list > c = 1 `cons` c > -- A left-infinite list > d = d `snoc` 2 > -- A middle-infinite list ?? > e = c `append` d *Main> head e 1 *Main> last e 2 Install it with cabal install fmlist Or go to http://hackage.haskell.org/package/fmlist-0.1 I owe a big thanks to Oleg Kiselyov, who wrote some of the more complicated folds in http://okmij.org/ftp/Haskell/zip-folds.lhs I don't think I could have come up with the zipWith code. This is my first package on Hackage, so any comments are welcome! greetings, Sjoerd Visscher PS. What happened to the traverse encoded containers (see below)? It turns out that it is a bit too generic, and functions like filter were impossible to implement. FMLists still have a Traversable instance, but only because the tree structure is (almost) undetectable, so they can simply be rebuilt using cons and empty. On Jun 15, 2009, at 1:29 AM, Sjoerd Visscher wrote: > Hi, > > While playing with Church Encodings of data structures, I realized > there are generalisations in the same way Data.Foldable and > Data.Traversable are generalisations of lists. > > The normal Church Encoding of lists is like this: > > > newtype List a = L { unL :: forall b. (a -> b -> b) -> b -> b } > > It represents a list by a right fold: > > > foldr f z l = unL l f z > > List can be constructed with cons and nil: > > > nil = L $ \f -> id > > cons a l = L $ \f -> f a . unL l f > > Oleg has written about this: http://okmij.org/ftp/Haskell/zip- > folds.lhs > > Now function of type (b -> b) are endomorphisms which have a > Data.Monoid instance, so the type can be generalized: > > > newtype FM a = FM { unFM :: forall b. Monoid b => (a -> b) -> b } > > fmnil = FM $ \f -> mempty > > fmcons a l = FM $ \f -> f a `mappend` unFM l f > > Now lists are represented by (almost) their foldMap function: > > > instance Foldable FM where > > foldMap = flip unFM > > But notice that there is now nothing list specific in the FM type, > nothing prevents us to add other constructor functions. > > > fmsnoc l a = FM $ \f -> unFM l f `mappend` f a > > fmlist = fmcons 2 $ fmcons 3 $ fmnil `fmsnoc` 4 `fmsnoc` 5 > > *Main> getProduct $ foldMap Product fmlist > 120 > > Now that we have a container type represented by foldMap, there's > nothing stopping us to do a container type represented by traverse > from Data.Traversable: > > {-# LANGUAGE RankNTypes #-} > > import Data.Monoid > import Data.Foldable > import Data.Traversable > import Control.Monad > import Control.Applicative > > newtype Container a = C { travC :: forall f b . Applicative f => (a - > > f b) -> f (Container b) } > > czero :: Container a > cpure :: a -> Container a > ccons :: a -> Container a -> Container a > csnoc :: Container a -> a -> Container a > cpair :: Container a -> Container a -> Container a > cnode :: Container a -> a -> Container a -> Container a > ctree :: a -> Container (Container a) -> Container a > cflat :: Container (Container a) -> Container a > > czero = C $ \f -> pure czero > cpure x = C $ \f -> cpure <$> f x > ccons x l = C $ \f -> ccons <$> f x <*> travC l f > csnoc l x = C $ \f -> csnoc <$> travC l f <*> f x > cpair l r = C $ \f -> cpair <$> travC l f <*> travC r f > cnode l x r = C $ \f -> cnode <$> travC l f <*> f x <*> travC r f > ctree x l = C $ \f -> ctree <$> f x <*> travC l (traverse f) > cflat l = C $ \f -> cflat <$> travC l (traverse f) > > instance Functor Container where > fmap g c = C $ \f -> travC c (f . g) > instance Foldable Container where > foldMap = foldMapDefault > instance Traversable Container where > traverse = flip travC > instance Monad Container where > return = cpure > m >>= f = cflat $ fmap f m > instance Monoid (Container a) where > mempty = czero > mappend = cpair > > Note that there are all kinds of "constructors", and they can all be > combined. Writing their definitions is similar to how you would > write Traversable instances. > > So I'm not sure what we have here, as I just ran into it, I wasn't > looking for a solution to a problem. It is also all quite abstract, > and I'm not sure I understand what is going on everywhere. Is this > useful? Has this been done before? Are there better implementations > of foldMap and (>>=) for Container? > > Finally, a little example. A Show instance (for debugging purposes) > which shows the nesting structure. > > newtype ShowContainer a = ShowContainer { doShowContainer :: String } > instance Functor ShowContainer where > fmap _ (ShowContainer x) = ShowContainer $ "(" ++ x ++ ")" > instance Applicative ShowContainer where > pure _ = ShowContainer "()" > ShowContainer l <*> ShowContainer r = ShowContainer $ init l ++ "," > ++ r ++ ")" > instance Show a => Show (Container a) where > show = doShowContainer . traverse (ShowContainer . show) > > greetings, > -- > Sjoerd Visscher > sjoerd@w3future.com > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe -- Sjoerd Visscher sjoerd@w3future.com From bulat.ziganshin at gmail.com Thu Jun 18 04:13:09 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Thu Jun 18 04:05:30 2009 Subject: [Haskell-cafe] Re: (fwd) Haskell logo fail In-Reply-To: <40a414c20906180017k250eeda9r9e479b7be7512a98@mail.gmail.com> References: <42784f260906172253p2f14d71auf936b7a6db8bdb3d@mail.gmail.com> <40a414c20906180017k250eeda9r9e479b7be7512a98@mail.gmail.com> Message-ID: <326536765.20090618121309@gmail.com> Hello minh, Thursday, June 18, 2009, 11:17:07 AM, you wrote: >>> Why don't we have a picture of a cool dinosaur instead? >> >> Something cool because the last heat of life went out of it >> 65 million years ago? > "made with secret dinosaur technology" "made with dinosaur technology" :))) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From ashley at semantic.org Thu Jun 18 04:26:21 2009 From: ashley at semantic.org (Ashley Yakeley) Date: Thu Jun 18 04:09:37 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: <4A3864B3.5020000@semantic.org> References: <1244822326.28941.29.camel@flippa-eee> <4A35B78C.3040809@semantic.org> <1245086323.3817.2.camel@glastonbury> <1245089315.5131.5.camel@flippa-eee> <4A369677.2010500@therning.org> <4A36A31A.10504@semantic.org> <4A3827CC.50806@semantic.org> <4A3864B3.5020000@semantic.org> Message-ID: <4A39FA2D.4040604@semantic.org> I wrote: > Rules for usernames are the same as rules for particle titles, erm, article titles From marlowsd at gmail.com Thu Jun 18 05:22:30 2009 From: marlowsd at gmail.com (Simon Marlow) Date: Thu Jun 18 05:05:45 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <1829193364.20090617001945@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <1829193364.20090617001945@gmail.com> Message-ID: <4A3A0756.3080707@gmail.com> On 16/06/2009 21:19, Bulat Ziganshin wrote: > Hello Simon, > > Tuesday, June 16, 2009, 5:02:43 PM, you wrote: > >> I don't know how getArgs fits in here - should we be decoding argv using >> the ACP? > > myGetArgs = do > alloca $ \p_argc -> do > p_argv_w<- commandLineToArgvW getCommandLineW p_argc > argc<- peek p_argc > argv_w<- peekArray (i argc) p_argv_w > mapM peekTString argv_w>>= return.tail > > foreign import stdcall unsafe "windows.h GetCommandLineW" > getCommandLineW :: LPTSTR > > foreign import stdcall unsafe "windows.h CommandLineToArgvW" > commandLineToArgvW :: LPCWSTR -> Ptr CInt -> IO (Ptr LPWSTR) Presumably we'd also have to remove the +RTS ... -RTS in Haskell if we did this, correct? Cheers, Simon From sebf at informatik.uni-kiel.de Thu Jun 18 05:28:02 2009 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Thu Jun 18 05:11:21 2009 Subject: [Haskell-cafe] ANNOUNCE fmlist In-Reply-To: <471C27BA-2DA7-4449-9AF8-4353AA9A4FED@w3future.com> References: <471C27BA-2DA7-4449-9AF8-4353AA9A4FED@w3future.com> Message-ID: On Jun 18, 2009, at 9:57 AM, Sjoerd Visscher wrote: > I am pleased to announce the first release of Data.FMList, lists > represented by their foldMap function: [...] > http://hackage.haskell.org/package/fmlist-0.1 cool! Just for fun: a derivation translating between different formulations of monadic bind. m >>= g = flatten (fmap g m) = FM $ \f -> unFM (fmap g m) (foldMap f) = FM $ \f -> unFM (FM $ \f' -> unFM m (f' . g)) (foldMap f) = FM $ \f -> (\f' -> unFM m (f' . g)) (foldMap f) = FM $ \f -> unFM m (folfMap f . g) -- your definition = FM $ \f -> unFM m (flip unFM f . g) = FM $ \f -> unFM m (\x -> flip unFM f (g x)) = FM $ \f -> unFM m (\x -> unFM (g x) f) -- like continuation monad Cheers, Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 163 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090618/24a592d5/PGP.bin From bulat.ziganshin at gmail.com Thu Jun 18 05:33:12 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Thu Jun 18 05:16:33 2009 Subject: [Haskell-cafe] Re[2]: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <4A3A0756.3080707@gmail.com> References: <6d74b0d20906132156gafef444q33afb1fee082e135@mail.gmail.com> <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <1829193364.20090617001945@gmail.com> <4A3A0756.3080707@gmail.com> Message-ID: <1845122838.20090618133312@gmail.com> Hello Simon, Thursday, June 18, 2009, 1:22:30 PM, you wrote: >> myGetArgs = do > Presumably we'd also have to remove the +RTS ... -RTS in Haskell if we > did this, correct? yes, it's long-standing in my own to-do list :) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From jochem at functor.nl Thu Jun 18 05:35:15 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Thu Jun 18 05:18:30 2009 Subject: [Haskell-cafe] ANNOUNCE: hyena In-Reply-To: <90889fe70906172324i63e49ac6n123c87ef306b0e07@mail.gmail.com> References: <90889fe70906172324i63e49ac6n123c87ef306b0e07@mail.gmail.com> Message-ID: <4A3A0A53.6090105@functor.nl> Johan Tibell wrote: > I am pleased to announce the first release of hyena, a library for building > web servers, based on the work on iteratee style I/O by Oleg Kiselyov. > > The library allows you to create web servers that consume their input > incrementally, without resorting to lazy I/O. This should lead to more > predictable resource usage. > > This is an early alpha release so expect the API to change in the future. In > particular, I'm working on converting the current definition of > iteratees/enumerators used to the one in the iteratee package [1]. I decided > to release this version, based on a simple left fold, due to requests by > several people who already started using hyena. > > Get it: > > cabal install hyena > > And on Hackage: > > http://hackage.haskell.org//package/hyena > > 1. http://hackage.haskell.org/package/iteratee Cool! I will certainly look into it. Cheers, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From str at holumbus.org Thu Jun 18 06:35:39 2009 From: str at holumbus.org (Sebastian Reese) Date: Thu Jun 18 06:18:53 2009 Subject: [Haskell-cafe] Profiling/cost centre question Message-ID: <20090618123539.13017nby3kkflncr@stud.fh-wedel.de> Hi there, I mailed to this list in May (http://www.haskell.org/pipermail/haskell-cafe/2009-May/062126.html) with no answer at all. So I wrote a smaller program to demonstrate my problem/question. Maybe now someone can help me now. I wrote a small program that does nothing but listening on a TCP port. After connection is done it simply terminates. #> cat Test.hs module Main where import Network main :: IO () main = (do servSock <- {-# SCC "cc1" #-}listenOn . PortNumber $ 10000 (handle, host, port) <- {-# SCC "cc2" #-}accept servSock return () )`catch` (putStrLn . show) #> I compile, run (connection from elsewhere, so program terminates) and watch the .prof output #> ghc --make -threaded -O2 -prof -caf-all -auto-all Test.hs Linking Test ... #> ./Test +RTS -p #> cat Test.prof Thu Jun 18 12:24 2009 Time and Allocation Profiling Report (Final) Test +RTS -p -RTS total time = 0.32 secs (16 ticks @ 20 ms) total alloc = 32,384 bytes (excludes profiling overheads) COST CENTRE MODULE %time %alloc MAIN MAIN 100.0 7.8 CAF GHC.Conc 0.0 4.0 CAF GHC.Handle 0.0 26.8 cc1 Main 0.0 3.8 cc2 Main 0.0 55.8 ... snip ... #> My actual question is, where does the 100% individual time from MAIN come from, how can I debug that in other programs and where does this MAIN cost centre come from? thanks for your help Sebastian ---------------------------------------------------------------- This message was sent using IMP, the Internet Messaging Program. From hthiel.char at zonnet.nl Thu Jun 18 07:23:03 2009 From: hthiel.char at zonnet.nl (Hans van Thiel) Date: Thu Jun 18 07:03:35 2009 Subject: [Haskell-cafe] Confusion on the third monad law when using lambda abstractions In-Reply-To: <4A39A5C6.2060102@gmail.com> References: <4A39938D.7020400@moonloop.net> <4A39A5C6.2060102@gmail.com> Message-ID: <1245324183.4762.6.camel@dhcppc0> On Wed, 2009-06-17 at 21:26 -0500, Jake McArthur wrote: > Jon Strait wrote: > > I'm reading the third (bind associativity) law for monads in this form: > > > > m >>= (\x -> k x >>= h) = (m >>= k) >>= h > > Arguably, that law would be better stated as: > > (h <=< k) <=< m = h <=< (k <=< m) > > This wouldn't be so unintuitive. Hi, The only place I've ever seen Kleisli composition, or its flip, used is in demonstrating the monad laws. Yet it is so elegant and, even having its own name, it must have some practical use. Do you, or anybody else, have some pointers? Best Regards, Hans van Thiel > > - Jake > From keithshep at gmail.com Thu Jun 18 07:29:58 2009 From: keithshep at gmail.com (Keith Sheppard) Date: Thu Jun 18 07:13:11 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> <8942CD18-8F65-411A-A0B1-C938DF219314@gmail.com> <92e42b740906171250w2dc15d44o36346117f55d8fd5@mail.gmail.com> <92e42b740906171405n2207827amf94471ef413fe22d@mail.gmail.com> Message-ID: <92e42b740906180429u4209ff12y70a79af9d3801998@mail.gmail.com> OK, I think I went off on a tangent that isn't very useful anyway thanks -Keith On Wed, Jun 17, 2009 at 6:32 PM, Lennart Augustsson wrote: > The creators of Haskell didn't pick any particular representation for numbers. > (Well, literals are kind of In..tegers.) ?You can pick what types you > make instances of Num. > Some of them are lazy, some of them are strict. > > On Wed, Jun 17, 2009 at 11:05 PM, Keith Sheppard wrote: >> In lambda calculus numbers are just functions and you evaluate them >> just like any other function. Haskell could have chosen the same >> representation for numbers and all evaluation on numbers would be lazy >> (assuming normal order evaluation). I think that would have been the >> "Purist Lazy" way to go. That is not the way the creators of Haskell >> designed language though... am i missing something? >> >> On Wed, Jun 17, 2009 at 4:05 PM, Lennart >> Augustsson wrote: >>> What do you mean by "literals are strict"? ?Strictness is a semantic >>> property of functions, and while literals can be overloaded to be >>> functions I don't know what you mean. >>> >>> On Wed, Jun 17, 2009 at 9:50 PM, Keith Sheppard wrote: >>>> Haskell's numeric literals are strict. You wouldn't want that to >>>> change right? It seems to me that having sum and product be strict is >>>> consistent with this. >>>> >>>> -Keith >>>> >>>> On Wed, Jun 17, 2009 at 11:15 AM, Thomas Davie wrote: >>>>> >>>>> On 17 Jun 2009, at 13:32, Yitzchak Gale wrote: >>>>> >>>>>> Henk-Jan van Tuyl wrote: >>>>>>> >>>>>>> reverse >>>>>>> maximum >>>>>>> minimum >>>>>> >>>>>> Oh yes, please fix those also! >>>>> >>>>> import Prelude.Strict? >>>>> >>>>> Honestly, these functions are ones that I've *deffinately* used lazy >>>>> versions of, in fact, in the cases of minimum/maximum I've even used ones >>>>> that are super-lazy and parallel using unamb. >>>>> >>>>> It would be extremely odd to randomly decide "most people would want this to >>>>> be strict" based on no knowledge of what they're actually doing. ?Instead, >>>>> why don't we stand by the fact that haskell is a lazy language, and that the >>>>> functions we get by default are lazy, and then write a strict prelude as I >>>>> suggest above to complement the lazy version. >>>>> >>>>> Bob >>>>> _______________________________________________ >>>>> Haskell-Cafe mailing list >>>>> Haskell-Cafe@haskell.org >>>>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>>>> >>>> >>>> >>>> >>>> -- >>>> keithsheppard.name >>>> _______________________________________________ >>>> Haskell-Cafe mailing list >>>> Haskell-Cafe@haskell.org >>>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>>> >>> >> >> >> >> -- >> keithsheppard.name >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > -- keithsheppard.name From stefan at cs.uu.nl Thu Jun 18 07:35:10 2009 From: stefan at cs.uu.nl (Stefan Holdermans) Date: Thu Jun 18 07:18:23 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? In-Reply-To: <706E19D9-D2C2-4CE3-95DC-AE5C0688A22E@cs.uu.nl> References: <57A134DD-CF18-4502-AC0D-C7B7265576AD@cs.uu.nl> <706E19D9-D2C2-4CE3-95DC-AE5C0688A22E@cs.uu.nl> Message-ID: Paul, >> Did you mean to say that const is strict in its first param and >> lazy in its second (since const _|_ y = _|_)? Also, can you explain >> your notation, how does a -> {S} -> b ->{L} a indicate the >> strictness? Why not just {S} a -> {L} b -> a? > > I'm sorry for the confusion. Indeed, const, as the type was intended > to reflect, const is strict in its first argument and lazy in its > second. Ah, sorry. Now I see where I really confused you. Someone pointed out that I erroneously inserted an extra -> in the type. The type should read a ->{S} b ->{L} a HTH, Stefan From tom.davie at gmail.com Thu Jun 18 07:53:25 2009 From: tom.davie at gmail.com (Thomas Davie) Date: Thu Jun 18 07:36:43 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: <92e42b740906180429u4209ff12y70a79af9d3801998@mail.gmail.com> References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> <8942CD18-8F65-411A-A0B1-C938DF219314@gmail.com> <92e42b740906171250w2dc15d44o36346117f55d8fd5@mail.gmail.com> <92e42b740906171405n2207827amf94471ef413fe22d@mail.gmail.com> <92e42b740906180429u4209ff12y70a79af9d3801998@mail.gmail.com> Message-ID: No, I think it's extremely useful. It highlights that numbers can both be lazy and strict, and that the so called "useless" lazy sum, is in fact, useful. Bob On 18 Jun 2009, at 13:29, Keith Sheppard wrote: > OK, I think I went off on a tangent that isn't very useful anyway > > thanks > -Keith > > On Wed, Jun 17, 2009 at 6:32 PM, Lennart > Augustsson wrote: >> The creators of Haskell didn't pick any particular representation >> for numbers. >> (Well, literals are kind of In..tegers.) You can pick what types you >> make instances of Num. >> Some of them are lazy, some of them are strict. >> >> On Wed, Jun 17, 2009 at 11:05 PM, Keith >> Sheppard wrote: >>> In lambda calculus numbers are just functions and you evaluate them >>> just like any other function. Haskell could have chosen the same >>> representation for numbers and all evaluation on numbers would be >>> lazy >>> (assuming normal order evaluation). I think that would have been the >>> "Purist Lazy" way to go. That is not the way the creators of Haskell >>> designed language though... am i missing something? >>> >>> On Wed, Jun 17, 2009 at 4:05 PM, Lennart >>> Augustsson wrote: >>>> What do you mean by "literals are strict"? Strictness is a >>>> semantic >>>> property of functions, and while literals can be overloaded to be >>>> functions I don't know what you mean. >>>> >>>> On Wed, Jun 17, 2009 at 9:50 PM, Keith >>>> Sheppard wrote: >>>>> Haskell's numeric literals are strict. You wouldn't want that to >>>>> change right? It seems to me that having sum and product be >>>>> strict is >>>>> consistent with this. >>>>> >>>>> -Keith >>>>> >>>>> On Wed, Jun 17, 2009 at 11:15 AM, Thomas >>>>> Davie wrote: >>>>>> >>>>>> On 17 Jun 2009, at 13:32, Yitzchak Gale wrote: >>>>>> >>>>>>> Henk-Jan van Tuyl wrote: >>>>>>>> >>>>>>>> reverse >>>>>>>> maximum >>>>>>>> minimum >>>>>>> >>>>>>> Oh yes, please fix those also! >>>>>> >>>>>> import Prelude.Strict? >>>>>> >>>>>> Honestly, these functions are ones that I've *deffinately* used >>>>>> lazy >>>>>> versions of, in fact, in the cases of minimum/maximum I've even >>>>>> used ones >>>>>> that are super-lazy and parallel using unamb. >>>>>> >>>>>> It would be extremely odd to randomly decide "most people would >>>>>> want this to >>>>>> be strict" based on no knowledge of what they're actually >>>>>> doing. Instead, >>>>>> why don't we stand by the fact that haskell is a lazy language, >>>>>> and that the >>>>>> functions we get by default are lazy, and then write a strict >>>>>> prelude as I >>>>>> suggest above to complement the lazy version. >>>>>> >>>>>> Bob >>>>>> _______________________________________________ >>>>>> Haskell-Cafe mailing list >>>>>> Haskell-Cafe@haskell.org >>>>>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>>>>> >>>>> >>>>> >>>>> >>>>> -- >>>>> keithsheppard.name >>>>> _______________________________________________ >>>>> Haskell-Cafe mailing list >>>>> Haskell-Cafe@haskell.org >>>>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>>>> >>>> >>> >>> >>> >>> -- >>> keithsheppard.name >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> Haskell-Cafe@haskell.org >>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>> >> > > > > -- > keithsheppard.name > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From l-siebeneicher at versanet.de Thu Jun 18 07:58:53 2009 From: l-siebeneicher at versanet.de (Leonard Siebeneicher) Date: Thu Jun 18 07:42:12 2009 Subject: [Haskell-cafe] how to #include files within parsec ... without unsafePerformIO? Message-ID: <1245326333.12872.2.camel@TALWACHT> Dear reader, I wonder whether there is a 'general' working solution to include files within a parsec parser. Without the need of unsafePerformIO. Appending an example program, using unsafePerformIO. Thanx for reading. Greetings, Leonard Siebeneicher --- Begin: experiment.hs --- import Text.ParserCombinators.Parsec import System.IO.Unsafe my_str :: Parser String my_str = many1 anyToken wrap_input :: Parser String -> Parser String wrap_input p = do i <- getInput setInput readI a <- my_str setInput i b <- my_str return $ a ++ " //\n\n " ++ b where {- Aaaah ... any solution without unsafePerformIO? -} readI = unsafePerformIO (readFile "experiment.hs") main = case parse (wrap_input my_str) "" "eintest" of Left err -> putStrLn "Error raised" Right ostr -> putStrLn ostr --- End: experiment.hs --- ___ Thinking about a special type like data MyInclude = PlainText String | IncludeFile String the parser could generate [MyInclude] data, but it does not work generally. From nccb2 at kent.ac.uk Thu Jun 18 08:06:52 2009 From: nccb2 at kent.ac.uk (Neil Brown) Date: Thu Jun 18 07:49:56 2009 Subject: [Haskell-cafe] how to #include files within parsec ... without unsafePerformIO? In-Reply-To: <1245326333.12872.2.camel@TALWACHT> References: <1245326333.12872.2.camel@TALWACHT> Message-ID: <4A3A2DDC.6030708@kent.ac.uk> Leonard Siebeneicher wrote: > Dear reader, > > I wonder whether there is a 'general' working solution to include files > within a parsec parser. Without the need of unsafePerformIO. > At least in parsec 2, I don't think so. Our solution was to read in the main file, tokenise it (using Alex), preprocess it (using some regex-like pattern matching on the token stream) in the IO monad and include the new files then (also tokenising and preprocessing them). Then after preprocessing we feed the entire resulting token stream to Parsec. Whether a two-phase approach (preprocess then parse) works depends on whether your include syntax is simple enough that you can spot the includes without parsing. Thanks, Neil. From gleb.alexeev at gmail.com Thu Jun 18 09:14:42 2009 From: gleb.alexeev at gmail.com (Gleb Alexeyev) Date: Thu Jun 18 08:57:18 2009 Subject: [Haskell-cafe] Re: curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <145D69DE-F783-41A3-AC65-2402FFF4DFF0@gmail.com> <2608b8a80906170138l43c1b244mb36f4735ac574466@mail.gmail.com> <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> <8942CD18-8F65-411A-A0B1-C938DF219314@gmail.com> <92e42b740906171250w2dc15d44o36346117f55d8fd5@mail.gmail.com> <92e42b740906171405n2207827amf94471ef413fe22d@mail.gmail.com> <92e42b740906180429u4209ff12y70a79af9d3801998@mail.gmail.com> Message-ID: Thomas Davie wrote: > No, I think it's extremely useful. It highlights that numbers can both > be lazy and strict, and that the so called "useless" lazy sum, is in > fact, useful. > But lazy sum should have beed defined in terms of foldr, not foldl. And foldl is not strict enough for strict sum. Therefore the current choice in the worst of both worlds. From keithshep at gmail.com Thu Jun 18 09:31:58 2009 From: keithshep at gmail.com (Keith Sheppard) Date: Thu Jun 18 09:15:12 2009 Subject: [Haskell-cafe] curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> <8942CD18-8F65-411A-A0B1-C938DF219314@gmail.com> <92e42b740906171250w2dc15d44o36346117f55d8fd5@mail.gmail.com> <92e42b740906171405n2207827amf94471ef413fe22d@mail.gmail.com> <92e42b740906180429u4209ff12y70a79af9d3801998@mail.gmail.com> Message-ID: <92e42b740906180631k73a61fco8336008ad48b1a9f@mail.gmail.com> I don't think anyone is calling it useless at this point. I could not see a use for it initially and it was quickly pointed out that there are in fact some infrequent use cases where a lazy sum is the best option. I think this is more a discussion about "principle of least surprise" or which use case is most frequent. I am pretty new to haskell so I may just be missing something basic (I welcome an explaination for why I am looking at this the wrong way), but if your argument is on consistency then doesn't it follow that number litterals should be defined using a church encoding or some equivalent? -Keith On Thu, Jun 18, 2009 at 7:53 AM, Thomas Davie wrote: > No, I think it's extremely useful. ?It highlights that numbers can both be > lazy and strict, and that the so called "useless" lazy sum, is in fact, > useful. > > Bob > > On 18 Jun 2009, at 13:29, Keith Sheppard wrote: > >> OK, I think I went off on a tangent that isn't very useful anyway >> >> thanks >> -Keith >> >> On Wed, Jun 17, 2009 at 6:32 PM, Lennart >> Augustsson wrote: >>> >>> The creators of Haskell didn't pick any particular representation for >>> numbers. >>> (Well, literals are kind of In..tegers.) ?You can pick what types you >>> make instances of Num. >>> Some of them are lazy, some of them are strict. >>> >>> On Wed, Jun 17, 2009 at 11:05 PM, Keith Sheppard >>> wrote: >>>> >>>> In lambda calculus numbers are just functions and you evaluate them >>>> just like any other function. Haskell could have chosen the same >>>> representation for numbers and all evaluation on numbers would be lazy >>>> (assuming normal order evaluation). I think that would have been the >>>> "Purist Lazy" way to go. That is not the way the creators of Haskell >>>> designed language though... am i missing something? >>>> >>>> On Wed, Jun 17, 2009 at 4:05 PM, Lennart >>>> Augustsson wrote: >>>>> >>>>> What do you mean by "literals are strict"? ?Strictness is a semantic >>>>> property of functions, and while literals can be overloaded to be >>>>> functions I don't know what you mean. >>>>> >>>>> On Wed, Jun 17, 2009 at 9:50 PM, Keith Sheppard >>>>> wrote: >>>>>> >>>>>> Haskell's numeric literals are strict. You wouldn't want that to >>>>>> change right? It seems to me that having sum and product be strict is >>>>>> consistent with this. >>>>>> >>>>>> -Keith >>>>>> >>>>>> On Wed, Jun 17, 2009 at 11:15 AM, Thomas Davie >>>>>> wrote: >>>>>>> >>>>>>> On 17 Jun 2009, at 13:32, Yitzchak Gale wrote: >>>>>>> >>>>>>>> Henk-Jan van Tuyl wrote: >>>>>>>>> >>>>>>>>> reverse >>>>>>>>> maximum >>>>>>>>> minimum >>>>>>>> >>>>>>>> Oh yes, please fix those also! >>>>>>> >>>>>>> import Prelude.Strict? >>>>>>> >>>>>>> Honestly, these functions are ones that I've *deffinately* used lazy >>>>>>> versions of, in fact, in the cases of minimum/maximum I've even used >>>>>>> ones >>>>>>> that are super-lazy and parallel using unamb. >>>>>>> >>>>>>> It would be extremely odd to randomly decide "most people would want >>>>>>> this to >>>>>>> be strict" based on no knowledge of what they're actually doing. >>>>>>> ?Instead, >>>>>>> why don't we stand by the fact that haskell is a lazy language, and >>>>>>> that the >>>>>>> functions we get by default are lazy, and then write a strict prelude >>>>>>> as I >>>>>>> suggest above to complement the lazy version. >>>>>>> >>>>>>> Bob >>>>>>> _______________________________________________ >>>>>>> Haskell-Cafe mailing list >>>>>>> Haskell-Cafe@haskell.org >>>>>>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>>>>>> >>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> keithsheppard.name >>>>>> _______________________________________________ >>>>>> Haskell-Cafe mailing list >>>>>> Haskell-Cafe@haskell.org >>>>>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>>>>> >>>>> >>>> >>>> >>>> >>>> -- >>>> keithsheppard.name >>>> _______________________________________________ >>>> Haskell-Cafe mailing list >>>> Haskell-Cafe@haskell.org >>>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>>> >>> >> >> >> >> -- >> keithsheppard.name >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe > > -- keithsheppard.name From jake.mcarthur at gmail.com Thu Jun 18 09:34:45 2009 From: jake.mcarthur at gmail.com (Jake McArthur) Date: Thu Jun 18 09:17:59 2009 Subject: [Haskell-cafe] Confusion on the third monad law when using lambda abstractions In-Reply-To: <1245324183.4762.6.camel@dhcppc0> References: <4A39938D.7020400@moonloop.net> <4A39A5C6.2060102@gmail.com> <1245324183.4762.6.camel@dhcppc0> Message-ID: <4A3A4275.8060301@gmail.com> Hans van Thiel wrote: > The only place I've ever seen Kleisli composition, or its flip, used is > in demonstrating the monad laws. Yet it is so elegant and, even having > its own name, it must have some practical use. Do you, or anybody else, > have some pointers? I only just started finding places to use it myself, admittedly, but I now think it has common use and it fairly easy to spot. I'll take it slow, if not for you, as you seem to have a grasp on what these operators are already, then for other readers. Consider a function of this form: foo x = a $ b $ c $ d $ e $ f x The obvious thing to do here is to simply drop the `x` from both sides by using `(.)` instead of `($)`: ==> foo x = a . b . c . d . e . f $ x ==> foo = a . b . c . d . e . f Now, consider this: bar x = a =<< b =<< c =<< d =<< e =<< f x If you compare that to the original version of `foo` above, you see that it is similar. In fact, looking at the types for `($)` and `(=<<)`: ($) :: (a -> b) -> ( a -> b) (=<<) :: Monad m => (a -> m b) -> (m a -> m b) So, `(=<<)` is just like `($)` except for the information carried along by the monad. Anyway, the "obvious" thing to do is to drop the `x` from both sides of the definition for `bar`. To do that with `foo` earlier, we had to substitute `($)` with `(.)`. What we are looking for is an equivalent operator for monads: (.) :: (b c) -> (a -> b) -> (a -> c) (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c) So we now can do this: ==> bar x = a <=< b <=< c <=< d <=< e <=< f $ x ==> bar = a <=< b <=< c <=< d <=< e <=< f And we're done. Generally, you can transform anything of the form: baz x1 = a =<< b =<< ... =<< z x1 into: baz = a <=< b <=< ... <=< z If you aren't already using `(=<<)` much more than `(>>=)` or do-notation then you will have a harder time finding opportunities to use `(<=<)` because only `(=<<)` has the same flow as function application, which allows your mind to play the appropriate association games. I suppose you could also replace `(>>=)` with `(>>>)`, but this would likely require more mental adjustment than replacing `(=<<)` with `(<=<)`. - Jake From sjoerd at w3future.com Thu Jun 18 08:49:55 2009 From: sjoerd at w3future.com (Sjoerd Visscher) Date: Thu Jun 18 09:22:49 2009 Subject: [Haskell-cafe] Confusion on the third monad law when using lambda abstractions In-Reply-To: <1245324183.4762.6.camel@dhcppc0> References: <4A39938D.7020400@moonloop.net> <4A39A5C6.2060102@gmail.com> <1245324183.4762.6.camel@dhcppc0> Message-ID: <5A44C5A8-06DB-4A8B-BBF4-AC91D986FF19@w3future.com> I had seen it before, and a bit of Googling turned up this: The monad laws can be written as return >=> g == g g >=> return == g (g >=> h) >=> k == g>=> (h >=> k) So, functions of type a -> m b are the arrows of a category with (>=>) as composition, and return as identity. http://sites.google.com/site/haskell/category-theory/thekleislicategory Although I think I saw them somewhere else. Sjoerd On Jun 18, 2009, at 1:23 PM, Hans van Thiel wrote: > > On Wed, 2009-06-17 at 21:26 -0500, Jake McArthur wrote: >> Jon Strait wrote: >>> I'm reading the third (bind associativity) law for monads in this >>> form: >>> >>> m >>= (\x -> k x >>= h) = (m >>= k) >>= h >> >> Arguably, that law would be better stated as: >> >> (h <=< k) <=< m = h <=< (k <=< m) >> >> This wouldn't be so unintuitive. > Hi, > The only place I've ever seen Kleisli composition, or its flip, used > is > in demonstrating the monad laws. Yet it is so elegant and, even having > its own name, it must have some practical use. Do you, or anybody > else, > have some pointers? > > Best Regards, > > Hans van Thiel >> >> - Jake >> > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe -- Sjoerd Visscher sjoerd@w3future.com From jake.mcarthur at gmail.com Thu Jun 18 09:54:31 2009 From: jake.mcarthur at gmail.com (Jake McArthur) Date: Thu Jun 18 09:37:44 2009 Subject: [Haskell-cafe] Confusion on the third monad law when using lambda abstractions In-Reply-To: <4A3A4275.8060301@gmail.com> References: <4A39938D.7020400@moonloop.net> <4A39A5C6.2060102@gmail.com> <1245324183.4762.6.camel@dhcppc0> <4A3A4275.8060301@gmail.com> Message-ID: <4A3A4717.9020309@gmail.com> Jake McArthur wrote: > Generally, you can transform anything of the form: > > baz x1 = a =<< b =<< ... =<< z x1 > > into: > > baz = a <=< b <=< ... <=< z I was just looking through the source for the recently announced Hyena library and decided to give a more concrete example from a real-world project. Consider this function from the project's Data.Enumerator module[1]: compose enum1 enum2 f initSeed = enum1 f1 (Right initSeed) >>= k where f1 (Right seed) bs = ... k (Right seed) = ... First, I would flip the `(>>=)` into a `(=<<)` (and I will ignore the `where` portion of the function from now on): compose enum1 enum2 f initSeed = k =<< enum1 f1 (Right initSeed) Next, transform the `(=<<)` into a `(<=<)`: compose enum1 enum2 f initSeed = k <=< enum1 f1 $ Right initSeed We can "move" the `($)` to the right by using `(.)`: compose enum1 enum2 f initSeed = k <=< enum1 f1 . Right $ initSeed Finally, we can drop the `initSeed` from both sides: compose enum1 enum2 f = k <=< enum1 f1 . Right I didn't test that my transformation preserved the semantics of the function or even that the type is still the same, but even if it's wrong it should give you the idea. - Jake [1] http://github.com/tibbe/hyena/blob/9655e9e6473af1e069d22d3ee75537ad3b88a732/Data/Enumerator.hs#L117 From colinpauladams at googlemail.com Thu Jun 18 10:02:55 2009 From: colinpauladams at googlemail.com (Colin Adams) Date: Thu Jun 18 09:46:08 2009 Subject: [Haskell-cafe] Confusion on the third monad law when using lambda abstractions In-Reply-To: <4A3A4717.9020309@gmail.com> References: <4A39938D.7020400@moonloop.net> <4A39A5C6.2060102@gmail.com> <1245324183.4762.6.camel@dhcppc0> <4A3A4275.8060301@gmail.com> <4A3A4717.9020309@gmail.com> Message-ID: <1afdeaec0906180702k2e6d0926r148c9b2d45f78813@mail.gmail.com> What is enum2 doing in all of this - it appears to be ignored. 2009/6/18 Jake McArthur : > Jake McArthur wrote: >> >> Generally, you can transform anything of the form: >> >> ? ?baz x1 = a =<< b =<< ... =<< z x1 >> >> into: >> >> ? ?baz = a <=< b <=< ... <=< z > > I was just looking through the source for the recently announced Hyena > library and decided to give a more concrete example from a real-world > project. Consider this function from the project's Data.Enumerator > module[1]: > > ? ?compose enum1 enum2 f initSeed = enum1 f1 (Right initSeed) >>= k > ? ? ? ?where > ? ? ? ? ?f1 (Right seed) bs = ... > ? ? ? ? ?k (Right seed) = ... > > First, I would flip the `(>>=)` into a `(=<<)` (and I will ignore the > `where` portion of the function from now on): > > ? ?compose enum1 enum2 f initSeed = k =<< enum1 f1 (Right initSeed) > > Next, transform the `(=<<)` into a `(<=<)`: > > ? ?compose enum1 enum2 f initSeed = k <=< enum1 f1 $ Right initSeed > > We can "move" the `($)` to the right by using `(.)`: > > ? ?compose enum1 enum2 f initSeed = k <=< enum1 f1 . Right $ initSeed > > Finally, we can drop the `initSeed` from both sides: > > ? ?compose enum1 enum2 f = k <=< enum1 f1 . Right > > I didn't test that my transformation preserved the semantics of the function > or even that the type is still the same, but even if it's wrong it should > give you the idea. > > - Jake > > [1] > http://github.com/tibbe/hyena/blob/9655e9e6473af1e069d22d3ee75537ad3b88a732/Data/Enumerator.hs#L117 > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From nccb2 at kent.ac.uk Thu Jun 18 10:09:22 2009 From: nccb2 at kent.ac.uk (Neil Brown) Date: Thu Jun 18 09:52:26 2009 Subject: [Haskell-cafe] Confusion on the third monad law when using lambda abstractions In-Reply-To: <1afdeaec0906180702k2e6d0926r148c9b2d45f78813@mail.gmail.com> References: <4A39938D.7020400@moonloop.net> <4A39A5C6.2060102@gmail.com> <1245324183.4762.6.camel@dhcppc0> <4A3A4275.8060301@gmail.com> <4A3A4717.9020309@gmail.com> <1afdeaec0906180702k2e6d0926r148c9b2d45f78813@mail.gmail.com> Message-ID: <4A3A4A92.8050808@kent.ac.uk> Clicking on the source code link reveals that enum2 is used in the where clause. It's not important to the transformation that Jake was performing. In essence, <=< is the monadic version of . (function composition) and as explained, it can be used to do some pointfree-like programming in the presence of monads. It's also handy in the arguments to things like mapM. E.g. f = mapM (\x -> foo x >>= bar) becomes: f = mapM (bar <=< foo) Neil. Colin Adams wrote: > What is enum2 doing in all of this - it appears to be ignored. > > 2009/6/18 Jake McArthur : > >> Jake McArthur wrote: >> >>> Generally, you can transform anything of the form: >>> >>> baz x1 = a =<< b =<< ... =<< z x1 >>> >>> into: >>> >>> baz = a <=< b <=< ... <=< z >>> >> I was just looking through the source for the recently announced Hyena >> library and decided to give a more concrete example from a real-world >> project. Consider this function from the project's Data.Enumerator >> module[1]: >> >> compose enum1 enum2 f initSeed = enum1 f1 (Right initSeed) >>= k >> where >> f1 (Right seed) bs = ... >> k (Right seed) = ... >> >> First, I would flip the `(>>=)` into a `(=<<)` (and I will ignore the >> `where` portion of the function from now on): >> >> compose enum1 enum2 f initSeed = k =<< enum1 f1 (Right initSeed) >> >> Next, transform the `(=<<)` into a `(<=<)`: >> >> compose enum1 enum2 f initSeed = k <=< enum1 f1 $ Right initSeed >> >> We can "move" the `($)` to the right by using `(.)`: >> >> compose enum1 enum2 f initSeed = k <=< enum1 f1 . Right $ initSeed >> >> Finally, we can drop the `initSeed` from both sides: >> >> compose enum1 enum2 f = k <=< enum1 f1 . Right >> >> I didn't test that my transformation preserved the semantics of the function >> or even that the type is still the same, but even if it's wrong it should >> give you the idea. >> >> - Jake >> >> [1] >> http://github.com/tibbe/hyena/blob/9655e9e6473af1e069d22d3ee75537ad3b88a732/Data/Enumerator.hs#L117 >> _______________________________________________ >> 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 duncan.coutts at worc.ox.ac.uk Thu Jun 18 10:18:39 2009 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Thu Jun 18 10:01:51 2009 Subject: [Haskell-cafe] Re: Unicode workaround for getDirectoryContents under Windows? In-Reply-To: <2608b8a80906171847s59f1782fkbe45a6eaa3b24c8f@mail.gmail.com> References: <4A378257.9090405@gmail.com> <645958025.20090616154231@gmail.com> <4A379155.8030500@gmail.com> <2608b8a80906160546r54011223xec706d8cd592097d@mail.gmail.com> <4A3797F3.2040707@gmail.com> <2608b8a80906170521k70ec3269k992b0db1fca4e5ec@mail.gmail.com> <4A38E5BF.8080005@gmail.com> <2608b8a80906170703h2985bd0ai5622fc1ddda6adf@mail.gmail.com> <4A38FB19.5080704@gmail.com> <2608b8a80906171847s59f1782fkbe45a6eaa3b24c8f@mail.gmail.com> Message-ID: <1245334719.28197.8.camel@localhost> On Thu, 2009-06-18 at 04:47 +0300, Yitzchak Gale wrote: > I wrote: > >> OK, would you like me to reflect this discussion in tickets? > >> Let's see, so far we have #3300, I don't see anything else. > >> > >> Do you want two tickets, one each for WIndows/Unix? Or > >> four, separating the FilePath and getArgs issues? > > Simon Marlow wrote: > > One for each issue is usually better, so four. > > OK, they are: #3300, #3307, #3308, #3309. Could we please make clear in those tickets that they only affect Windows. I do hope we are only proposing that FilePath be interpreted as Unicode on Window and OSX. It would break things to decode to Unicode on Unix systems. On Unix filepaths really are strings of bytes, not an encoding of Unicode code points. It's true that this is not reflected accurately in the type FilePath = String. The FilePath should be an opaque type that allows decoding into a human readable Unicode String. I wonder how much code would actually break if FilePath became an opaque type, eg if we make it an instance of IsString. It only need change in System.IO and System.FilePath, not in the old H98 modules. Duncan From ekmett at gmail.com Thu Jun 18 10:21:19 2009 From: ekmett at gmail.com (Edward Kmett) Date: Thu Jun 18 10:04:30 2009 Subject: [Haskell-cafe] Re: curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <2608b8a80906170432y2f7e523ah99deeaa0d7d03455@mail.gmail.com> <8942CD18-8F65-411A-A0B1-C938DF219314@gmail.com> <92e42b740906171250w2dc15d44o36346117f55d8fd5@mail.gmail.com> <92e42b740906171405n2207827amf94471ef413fe22d@mail.gmail.com> <92e42b740906180429u4209ff12y70a79af9d3801998@mail.gmail.com> Message-ID: <7fb8f82f0906180721o7b245cbfx9bd0622a14767856@mail.gmail.com> On Thu, Jun 18, 2009 at 9:14 AM, Gleb Alexeyev wrote: > Thomas Davie wrote: > >> No, I think it's extremely useful. It highlights that numbers can both be >> lazy and strict, and that the so called "useless" lazy sum, is in fact, >> useful. >> >> But lazy sum should have beed defined in terms of foldr, not foldl. And > foldl is not strict enough for strict sum. Therefore the current choice in > the worst of both worlds. > I definitely agree with that sentiment. -Edward Kmett -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090618/04c701fb/attachment.html From schlepptop at henning-thielemann.de Thu Jun 18 10:21:23 2009 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Thu Jun 18 10:05:25 2009 Subject: [Haskell-cafe] Creating a new Haskell mailing list In-Reply-To: <442d2c4c0906171738r21b8ac36u1efb8803202185ed@mail.gmail.com> References: <442d2c4c0906171738r21b8ac36u1efb8803202185ed@mail.gmail.com> Message-ID: <4A3A4D63.9070807@henning-thielemann.de> Ryan Trinkle schrieb: > Hi all, > > I'm interested in starting a mailing list on haskell.org > . Who should I talk to about such things? Is it a mailing list related to a project? Then you may request a project on community.haskell.org, then you can start a mailing list at yourproject@project.haskell.org From ekmett at gmail.com Thu Jun 18 10:30:45 2009 From: ekmett at gmail.com (Edward Kmett) Date: Thu Jun 18 10:14:00 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? In-Reply-To: References: Message-ID: <7fb8f82f0906180730x6b6d22e2na8959b240d4aef15@mail.gmail.com> I have been exploring a weak form of runtime strictness analysis in a tracing JIT project of my own in the spirit of TraceMonkey. Basically a tracing JIT doesn't compile blocks of code but instead once a tracing point has been passed often enough, it starts a trace from that point logging the series of instructions executed to a bounded log. If you make it back to the starting point before the log fills up then you've identified a superblock with a bunch of side exits for handling when your assumptions are violated. What is interesting is in a lazy setting, if you are tracing a bytecode representation that knows about allocation and thunks, you can do some additional optimizations in here. If on every path to a side exit or the end of the loop you find that the thunk is evaluated you can evaluate it strictly and move its execution earlier in the trace. This gives you a weak form of runtime strictness analysis. If the pointer to that thunk never escapes, then you can unbox the contents of the thunk and operate on its members in registers. Add constant folding, polyinline caching to improve branch prediction for spineless tagless g-machine thunk evaluation, and code migration to the side exits and it becomes an interesting runtime system. But the key concern for the sake of the current discussion is that it models strictness analysis and unboxing quite naturally as an artifact of the jitting process. So that said, a form of conservative strictness analysis at runtime is possible. -Edward Kmett On Sun, Jun 14, 2009 at 7:42 PM, Paul Chiusano wrote: > Hello, > I was recently trying to figure out if there was a way, at runtime, to do > better strictness analysis for polymorphic HOFs, for which the strictness of > some arguments might depend on the strictness of the strictness of function > types that are passed as arguments [1]. As an example, consider foldl. The > 'seed' parameter of foldl can be made strict as long as the binary function > used for the fold is strict in its arguments. Unfortunately, because > strictness analysis is done statically, Haskell can't assume anything about > the strictness of the binary function - assuming we only compile one > instance of foldl, it must be the most conservative version possible, and > that means making the seed parameter lazy. :-( > > I started thinking about ways you could to a check at runtime for this sort > of thing, something to the effect of asking foldl, before heap-allocating a > thunk for the seed parameter, whether that parameter could be made strict. > foldl could then inspect other arguments that have been supplied, and based > on these arguments, evaluate or go ahead with creating a thunk the seed > parameter. It's a runtime cost, sure, but would it be more than the cost of > having to do an additional heap allocation? In any case a small runtime cost > might be worth it if the analysis becomes more uniform. > > So, my question is: does doing this sort of runtime analysis seem like a > horrible idea? Is it even possible? Has anyone tried this in the past? (So > far I haven't found anything, but would love references if people have > them.) > > Note that I'm not suggesting Haskell should do anything like this. I'm > playing around with the ideas because I'm interesting in creating a lazy > language and I was hoping to have strictness analysis be very predictable > and uniform, something the programmer can count on and use to simply reason > about space usage ... which might be hopelessly unrealistic goal! I guess > the more general question is - is "perfect" strictness analysis (however > that is defined) possible, if we're willing to incur some runtime cost? What > would that look like? > > Best, > Paul > > [1]: > More background on my thinking here - a bit half-baked, so bear with me! > > http://pchiusano.blogspot.com/2009/06/perfect-strictness-analysis-part-1.html > > http://pchiusano.blogspot.com/2009/06/perfect-strictness-analysis-part-2.html > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090618/6960682a/attachment-0001.html From anotheraddress at gmx.de Thu Jun 18 11:22:23 2009 From: anotheraddress at gmx.de (Daniel =?iso-8859-15?q?Sch=FCssler?=) Date: Thu Jun 18 11:05:37 2009 Subject: [Haskell-cafe] how to #include files within parsec ... without unsafePerformIO? In-Reply-To: <1245326333.12872.2.camel@TALWACHT> References: <1245326333.12872.2.camel@TALWACHT> Message-ID: <200906181722.24287.anotheraddress@gmx.de> Hi, ParsecT with m=IO? Your 'do' block would become: do i <- getInput included <- liftIO readI -- import Control.Monad.Trans for liftIO setInput included a <- my_str setInput i b <- my_str return $ a ++ " //\n\n " ++ b where readI = readFile "experiment.hs" Maybe I'm misunderstanding the problem. Greetings, Daniel On Thursday 18 June 2009 13:58:53 Leonard Siebeneicher wrote: > Dear reader, > > I wonder whether there is a 'general' working solution to include files > within a parsec parser. Without the need of unsafePerformIO. > > Appending an example program, using unsafePerformIO. > > Thanx for reading. > > Greetings, > Leonard Siebeneicher > > > --- Begin: experiment.hs --- > import Text.ParserCombinators.Parsec > import System.IO.Unsafe > > my_str :: Parser String > my_str = many1 anyToken > > wrap_input :: Parser String -> Parser String > wrap_input p = > do > i <- getInput > setInput readI > a <- my_str > setInput i > b <- my_str > return $ a ++ " //\n\n " ++ b > where > {- Aaaah ... any solution without unsafePerformIO? -} > readI = unsafePerformIO (readFile "experiment.hs") > > > main = > case parse (wrap_input my_str) "" "eintest" of > Left err -> putStrLn "Error raised" > Right ostr -> putStrLn ostr > --- End: experiment.hs --- > > > ___ > Thinking about a special type like > > data MyInclude = PlainText String > > | IncludeFile String > > the parser could generate [MyInclude] data, but it does not work > generally. > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From hthiel.char at zonnet.nl Thu Jun 18 11:32:08 2009 From: hthiel.char at zonnet.nl (Hans van Thiel) Date: Thu Jun 18 11:12:40 2009 Subject: [Haskell-cafe] Confusion on the third monad law when using lambda abstractions In-Reply-To: <4A3A4275.8060301@gmail.com> References: <4A39938D.7020400@moonloop.net> <4A39A5C6.2060102@gmail.com> <1245324183.4762.6.camel@dhcppc0> <4A3A4275.8060301@gmail.com> Message-ID: <1245339129.3038.15.camel@dhcppc0> On Thu, 2009-06-18 at 08:34 -0500, Jake McArthur wrote: [snip] > So, `(=<<)` is just like `($)` except for the information carried along > by the monad. > > Anyway, the "obvious" thing to do is to drop the `x` from both sides of > the definition for `bar`. To do that with `foo` earlier, we had to > substitute `($)` with `(.)`. What we are looking for is an equivalent > operator for monads: > > (.) :: (b c) -> (a -> b) -> (a -> c) Just to show I'm paying attention, there's an arrow missing, right? (.) :: (b -> c) -> (a -> b) -> (a -> c) Many thanks, also to the others who've replied. I've wondered about (=<<) usage for a long time too, and this is all very illuminating. I'll work this through and put it in my monad tutorial, if I may (without implicating you guys in any way, of course, unless you insist...) Regards, Hans van Thiel [snip] From lee.duhem at gmail.com Thu Jun 18 11:57:30 2009 From: lee.duhem at gmail.com (Lee Duhem) Date: Thu Jun 18 11:40:42 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list - Ouch In-Reply-To: References: Message-ID: On Wed, Jun 17, 2009 at 7:30 PM, G??nther Schmidt wrote: > Hi all, > > you have come up with so many solutions it's embarrassing to admit that I > didn't come up with even one. I have the similarly difficulties, but I found to understand some of these answers, equational reasoning is a very useful tool, I have prepared a blog post for how I worked out some of these answers, here is the draft of it, I hope it can help you too. Oh, if it doesn't help you at all, please let know why :-) lee ==== Understanding Functions Which Use 'instance Monad []' by Equational Reasoning G??nther Schmidt asked in Haskell-Cafe how to get a stream like this: ["a", ... , "z", "aa", ... , "az", "ba", ... , "bz", ... ] and people in Haskell-Cafe offer some interesting answer for this question. On the one hand, these answers show the power of Haskell and GHC base libraries, but on the other hand, understanding them is a challenge for Haskell newbie like me. But I found to understand these answers, equational reasoning is very helpful, here is why I think so. Answer 1 (by Matthew Brecknell): concat $ tail $ iterate (map (:) ['a' .. 'z'] <*>) [[]] Well, how does this expression do what we want? concat, tail, iterate, map, are easy, looks like the magic is in (<*>). What's this operator mean? (<*>) comes from class Applicative of Control.Applicative, class Functor f => Applicative f where -- | Lift a value. pure :: a -> f a -- | Sequential application. (<*>) :: f (a -> b) -> f a -> f b and 'instance Applicative []' is instance Applicative [] where pure = return (<*>) = ap ap comes from Control.Monad ap :: (Monad m) => m (a -> b) -> m a -> m b ap = liftM2 id liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) } so the key to understand (<*>) is understanding the meaning of liftM2. liftM2 uses, hum, do-notation, so by Haskell 98 report, this can be translated to liftM2 f m1 m2 (1.0) = m1 >>= \x1 -> m2 >>= \x2 -> return (f x1 x2) When it is applied to list (you can convince yourself of this by type inference), wee need 'instance Monad []' instance Monad [] where m >>= k = foldr ((++) . k) [] m m >> k = foldr ((++) . (\ _ -> k)) [] m return x = [x] fail _ = [] so liftM2 f m1 m2 = m1 >>= \x1 -> m2 >>= \x2 -> return (f x1 x2) let f1 = \x1 -> m2 >>= \x2 -> return (f x1 x2) f2 = \x2 -> return (f x1 x2) we can write m1 >>= f1 = foldr ((++) . f1) [] m1 m2 >>= f2 = foldr ((++) . f2) [] m2 Now we can see for list m1, m2, how does 'liftM2 f m1 m2' work z1 = [] foreach x1 in (reverse m1); do -- foldr ((++) . f1) [] m1 z2 = [] foreach x2 in (reverse m2); do -- foldr ((++) . f2) [] m2 z2 = [f x1 x2] ++ z2 done z1 = z2 ++ z1 done Now we are ready to see how to apply (<*>): map (:) ['a' .. 'z'] <*> [[]] = (map (:) ['a' .. 'z']) <*> [[]] = [('a':), ..., ('z':)] <*> [[]] -- misuse of [...] notation = ap [('a':), ..., ('z':)] [[]] = liftM2 id [('a':), ..., ('z':)] [[]] = [('a':), ..., ('z':)] >>= \x1 -> [[]] >>= \x2 -> return (id x1 x2) Here x1 bind to ('z':), ..., ('a':) in turn, x2 always bind to [], and noticed that return (id ('z':) []) -- f = id; x1 = ('a':); x2 = [] = return (('z':) []) = return ((:) 'z' []) = return "z" = ["z"] we have map (:) ['a', .., 'z'] <*> [[]] = liftM2 id [('a':), ..., ('z':)] [[]] = ["a", ..., "z"] (If you can't follow the this, work through the definition of foldr step by step will be very helpful.) map (:) ['a', .., 'z'] <*> (map (:) ['a', .., 'z'] <*> [[]]) = map (:) ['a', .., 'z'] <*> ["a", .., "z"] = liftM2 id [('a':), ..., ('z':)] ["a", ..., "z"] = ["aa", ..., "az", "ba", ..., "bz", ..., "za", ..., "zz"] Now it's easy to know what we get from iterate (map (:) ['a' .. 'z'] <*>) [[]] = [[], f [[]], f (f [[]]), ...] -- f = map (:) ['a' .. 'z'] <*> so concat $ tail $ iterate (map (:) ['a' .. 'z'] <*>) [[]] is exactly what we want. Understanding Haskell codes by equational reasoning could be a very tedious process, but it's also a very helpful and instructive process for the beginners, because it make you think slowly, check the computation process step by step, just like the compiler does. And in my opinion, this is exactly what a debugger does. Answer 2 (by Reid Barton): concatMap (\n -> replicateM n ['a'..'z']) [1..] In this solution, the hardest part is replicatM, which come from Control.Monad replicateM :: (Monad m) => Int -> m a -> m [a] replicateM n x = sequence (replicate n x) sequence :: Monad m => [m a] -> m [a] sequence ms = foldr k (return []) ms where k m m' = do { x <- m; xs <- m'; return (x:xs) } recall the defintion of liftM2: liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) } so k in definition of sequence is an application of liftM2, and sequence itself is a normal foldr. Exercise 1: Prove that for n >= 1 replicateM n ['a' .. 'z'] = (iterate (map (:) ['a' .. 'z'] <*>) [[]]) !! n or more generally replicateM = \n xs -> (iterate (map (:) xs <*>) [[]]) !! n Answer: replicateM 1 ['a' .. 'z'] = sequence [ ['a' .. 'z'] ] = foldr k (return []) [['a' .. 'z']] = k ['a' .. 'z'] [[]] -- return [] = [[]] = liftM2 (:) ['a' .. 'z'] [[]] = map (:) ['a' .. 'z'] <*> [[]] = ["a", ..., "z"] replicateM 2 ['a' .. 'z'] = sequence [['a' .. 'z'], ['a' .. 'z']] = foldr k [[]] [['a' .. 'z'], ['a' .. 'z']] = k ['a' .. 'z'] (k ['a' .. 'z'] [[]]) = k ['a' .. 'z'] (f [[]]) -- f = map (:) ['a' .. 'z'] <*> = f (f [[]]) From batterseapower at hotmail.com Thu Jun 18 12:30:53 2009 From: batterseapower at hotmail.com (Max Bolingbroke) Date: Thu Jun 18 12:14:06 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? In-Reply-To: <7fb8f82f0906180730x6b6d22e2na8959b240d4aef15@mail.gmail.com> References: <7fb8f82f0906180730x6b6d22e2na8959b240d4aef15@mail.gmail.com> Message-ID: <9d4d38820906180930g2e49aca4ne8569d5b0c117787@mail.gmail.com> 2009/6/18 Edward Kmett : > What is interesting is in a lazy setting, if you are tracing a bytecode > representation that knows about allocation and thunks, you can do some > additional optimizations in here. If on every path to a side exit or the end > of the loop you find that the thunk is evaluated you can evaluate it > strictly and move its execution earlier in the trace. This gives you a weak > form of runtime strictness analysis. If the pointer to that thunk never > escapes, then you can unbox the contents of the thunk and operate on its > members in registers. Add constant folding, polyinline caching?to improve > branch prediction for spineless tagless g-machine thunk evaluation, and code > migration to the side exits?and it becomes an interesting runtime system. This sounds absolutely awesome! Is the source code for your prototype publicly available anywhere? I'd love to take a look at the basic structure of something like this - trace JITing is something I keep meaning to look at in more depth. Cheers, Max From agocorona at gmail.com Thu Jun 18 12:38:57 2009 From: agocorona at gmail.com (Alberto G. Corona ) Date: Thu Jun 18 12:22:10 2009 Subject: Fwd: [Haskell-cafe] Re: curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <92e42b740906171250w2dc15d44o36346117f55d8fd5@mail.gmail.com> <92e42b740906171405n2207827amf94471ef413fe22d@mail.gmail.com> <92e42b740906180429u4209ff12y70a79af9d3801998@mail.gmail.com> <7fb8f82f0906180721o7b245cbfx9bd0622a14767856@mail.gmail.com> Message-ID: However it does not work as I expected. I ?m interested in memory management. I though that ghci> let l= [1..1000000] ghci> foldl' (+) 0 l would produce a stack overflow, since the list can not be freed, because l points to the beginning of the list however it succeed My conclussion is that, in the case of sum, with the lazy evaluation, isn?t the list what is the cause of the stack overflow, but the lazy structure 0 + 1 +2 + 3 +4.... created by foldl before the final evaluation I tried to test how I can force a stack overflow, in the strict case. Since foldl' is strict, the only way is to create a long long initial list. ghci> let l= [1..100000000] -- 100 times larger, two 0's added ghci> foldl' (+) 0 l as in the previous case, l will not garbage collect, and foldl' must build the real list [1,2,3,4..] . at the end perhaps a stack overflow willl be produced This is not the case in my windows system.ghc 6.10.1. instead of that, ghci grow to gigabyte size and more. I stopped the process or my machine would be irresponsive. My question is: Why the process does not grow also in the lazy case and instead produces a stack overflow inmediately? Yes I know that all of this is bizantine since strictness analysis would solve this when compiled, but I think that there are somethig that i don?t understand. It?s a bug perhaps??? 2009/6/18 Edward Kmett > On Thu, Jun 18, 2009 at 9:14 AM, Gleb Alexeyev wrote: > >> Thomas Davie wrote: >> >>> No, I think it's extremely useful. It highlights that numbers can both >>> be lazy and strict, and that the so called "useless" lazy sum, is in fact, >>> useful. >>> >>> But lazy sum should have beed defined in terms of foldr, not foldl. And >> foldl is not strict enough for strict sum. Therefore the current choice in >> the worst of both worlds. >> > > > I definitely agree with that sentiment. > > -Edward Kmett > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090618/201a03f2/attachment.html From chaddai.fouche at gmail.com Thu Jun 18 12:58:08 2009 From: chaddai.fouche at gmail.com (=?UTF-8?B?Q2hhZGRhw68gRm91Y2jDqQ==?=) Date: Thu Jun 18 12:41:20 2009 Subject: [Haskell-cafe] Re: curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <92e42b740906171405n2207827amf94471ef413fe22d@mail.gmail.com> <92e42b740906180429u4209ff12y70a79af9d3801998@mail.gmail.com> <7fb8f82f0906180721o7b245cbfx9bd0622a14767856@mail.gmail.com> Message-ID: On Thu, Jun 18, 2009 at 6:38 PM, Alberto G. Corona wrote: > My question is: Why the process does not grow also in the lazy case and > instead produces a stack overflow inmediately? This question is answered in detail on the Wiki http://www.haskell.org/haskellwiki/Foldr_Foldl_Foldl%27 As you thought, it is not the evaluation of foldl that overflow the stack, since foldl is terminally recursive it won't ever overflow the stack. On the other hand when the thunk created by foldl is finally evaluated, if the argument function is strict in its first argument it will overflow the stack if the list was too long. It is important to note that the size of the list itself or even the thunk doesn't guarantee a stack overflow : both of those structure are in the heap and if the argument function can produce output before evaluating its first argument, there will be no stack overflow, whatever the size of the thunk. As evidenced by this expression : ghci> take 10 . foldl (flip (:)) [] $ [1..1000000] [1000000,999999,999998,999997,999996,999995,999994,999993,999992,999991] -- Jeda? From agocorona at gmail.com Thu Jun 18 13:32:00 2009 From: agocorona at gmail.com (Alberto G. Corona ) Date: Thu Jun 18 13:15:12 2009 Subject: [Haskell-cafe] Re: curious about sum In-Reply-To: References: <92e42b740906130703o39954c2dv4fc694c88ce770de@mail.gmail.com> <92e42b740906171405n2207827amf94471ef413fe22d@mail.gmail.com> <92e42b740906180429u4209ff12y70a79af9d3801998@mail.gmail.com> <7fb8f82f0906180721o7b245cbfx9bd0622a14767856@mail.gmail.com> Message-ID: Very informative. The list is in the heap but the lazy sum of foldl is in the stack. ok.I suppose that all tail recursive functions are detected by the strictness analysis. 2009/6/18 Chadda? Fouch? > On Thu, Jun 18, 2009 at 6:38 PM, Alberto G. Corona > wrote: > > My question is: Why the process does not grow aleso in the lazy case and > > instead produces a stack overflow inmediately? > > This question is answered in detail on the Wiki > http://www.haskell.org/haskellwiki/Foldr_Foldl_Foldl%27 > As you thought, it is not the evaluation of foldl that overflow the > stack, since foldl is terminally recursive it won't ever overflow the > stack. On the other hand when the thunk created by foldl is finally > evaluated, if the argument function is strict in its first argument it > will overflow the stack if the list was too long. > > It is important to note that the size of the list itself or even the > thunk doesn't guarantee a stack overflow : both of those structure are > in the heap and if the argument function can produce output before > evaluating its first argument, there will be no stack overflow, > whatever the size of the thunk. > > As evidenced by this expression : > ghci> take 10 . foldl (flip (:)) [] $ [1..1000000] > [1000000,999999,999998,999997,999996,999995,999994,999993,999992,999991] > > -- > Jeda? > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090618/ae8db058/attachment.html From jake.mcarthur at gmail.com Thu Jun 18 14:35:20 2009 From: jake.mcarthur at gmail.com (Jake McArthur) Date: Thu Jun 18 14:18:12 2009 Subject: [Haskell-cafe] Confusion on the third monad law when using lambda abstractions In-Reply-To: <1245339129.3038.15.camel@dhcppc0> References: <4A39938D.7020400@moonloop.net> <4A39A5C6.2060102@gmail.com> <1245324183.4762.6.camel@dhcppc0> <4A3A4275.8060301@gmail.com> <1245339129.3038.15.camel@dhcppc0> Message-ID: <4A3A88E8.8080409@gmail.com> Hans van Thiel wrote: > Just to show I'm paying attention, there's an arrow missing, right? > (.) :: (b -> c) -> (a -> b) -> (a -> c) Correct. I noticed that after I sent it but I figured that it would be noticed. I also used (>>>) where I meant (>=>) at the bottom. They are semantically the same, of course, but (>>>) requires the Kleisli newtype. :( > Many thanks, also to the others who've replied. I've wondered about > (=<<) usage for a long time too, and this is all very illuminating. I'll > work this through and put it in my monad tutorial, if I may (without > implicating you guys in any way, of course, unless you insist...) You're welcome. I do not insist on anything either way. ;) - Jake From deniz.a.m.dogan at gmail.com Thu Jun 18 15:56:50 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Thu Jun 18 15:40:01 2009 Subject: [Haskell-cafe] Running a "sub-process" which dies with the main program Message-ID: <7b501d5c0906181256k58c5702ap9e1f80f890e56e79@mail.gmail.com> Hi I couldn't come up with a better subject than this one, so anyways... I have a small program which spawns a subprocess. However, when I hit C-c, the subprocess won't die, instead it will just keep running until it's done or until I kill it. I've looked around in System.Process for something suitable for my needs, but I can't seem to find it. Any ideas? -- Deniz Dogan From maciej.podgurski at googlemail.com Thu Jun 18 17:26:02 2009 From: maciej.podgurski at googlemail.com (Maciej Podgurski) Date: Thu Jun 18 17:09:21 2009 Subject: [Haskell-cafe] Use MySQL from Haskell Message-ID: <4A3AB0EA.4090304@googlemail.com> Hello, I'm trying to use MySQL from Haskell but it seems impossible for me to install one of the MySQL packages on my Windows XP machine. First I tired to install hsql-mysql-1.7.1 on GHC 6.10.3 but installing haskelldb-hsql failed with a hidden package error. So I added the old-time package to the cabal file but there still was a compile error (something due to the change from Exception to Exception e => e). So I switched to GHC 6.8.3 and tried it again. Now it says: Configuring hsql-mysql-1.7.1... Warning: 'extra-lib-dirs: /usr/lib/mysql' directory does not exist. Warning: 'include-dirs: /usr/include/mysql' directory does not exist. Warning: This package indirectly depends on multiple versions of the same package. This is highly likely to cause a compile failure. package process-1.0.0.1 requires filepath-1.1.0.0 package directory-1.0.0.1 requires filepath-1.1.0.0 package Cabal-1.6.0.3 requires filepath-1.1.0.2 Setup: Missing dependency on a foreign library: * Missing C library: mysqlclient This problem can usually be solved by installing the system package that provides this library (you may need the "-dev" version). If the library is already installed but in a non-standard location then you can use the flags --extra-include-dirs= and --extra-lib-dirs= to specify where it is. There's no Haskell package mysqlclient and I don't know how to install a C library in Haskell. So I switched to HDBC-2.1.1 and got the next compile error: Building convertible-1.0.5... Data/Convertible/Instances/Num.hs:671:0: warning: no newline at end of file [...] [5 of 8] Compiling Data.Convertible.Instances.C ( Data/Convertible/Instances/C.hs, dist\build/Data/C onvertible/Instances/C.o ) [6 of 8] Compiling Data.Convertible.Instances.Time ( Data/Convertible/Instances/Time.hs, dist\build/ Data/Convertible/Instances/Time.o ) Data/Convertible/Instances/Time.hs:64:0: Duplicate instance declarations: instance Typeable NominalDiffTime -- Defined at Data/Convertible/Instances/Time.hs:(64,0)-(65,42) instance Typeable NominalDiffTime -- Defined in time-1.1.3:Data.Time.Clock.UTC Data/Convertible/Instances/Time.hs:67:0: Duplicate instance declarations: instance Typeable UTCTime -- Defined at Data/Convertible/Instances/Time.hs:(67,0)-(68,34) instance Typeable UTCTime -- Defined in time-1.1.3:Data.Time.Clock.UTC So please help me, what GHC/package configuration will I need to use MySQL from my Haskell programs on Windows? I really like Haskell but all those "broken" packages are really discouraging. :( Best wishes, Maciej From donn at avvanta.com Thu Jun 18 17:47:25 2009 From: donn at avvanta.com (Donn Cave) Date: Thu Jun 18 17:30:37 2009 Subject: [Haskell-cafe] Running a "sub-process" which dies with the main program References: <7b501d5c0906181256k58c5702ap9e1f80f890e56e79@mail.gmail.com> Message-ID: <20090618214725.196DF93C47@mail.avvanta.com> Quoth Deniz Dogan , > I have a small program which spawns a subprocess. However, when I hit > C-c, the subprocess won't die, instead it will just keep running until > it's done or until I kill it. I've looked around in System.Process for > something suitable for my needs, but I can't seem to find it. Any > ideas? What you want, is the normal behavior for Berkeley/UNIX/POSIX ttys: signals generated by the (pseudo)tty handler from control characters are delivered to all processes in the foreground process group, which is a hereditary distinction where you have to actively opt out. Berkeley job control shells (bash, ksh et al.) reset process group on commands issuing from the terminal, so the foreground process group is whatever you invoked, and any subprocesses thereof (barring further process group resets), and that's what will abort if you press ctrl-C. If it isn't working that way, possibilities might include: - not a POSIX operating system - subprocess set its process group and is no longer in the terminal foreground process group. - a signal handler caught/ignored ctrl-C. Along with process group stuff in System.Process, if both processes are Haskell you might look at System.Posix.Terminal getTerminalProcessGroupID, as a way to directly check the second item above (and I suppose indirectly the first.) Unfortunately, none of these explanations come with any suggested remedy - they're just three ways to say "platform [OS or Haskell implementation] doesn't support POSIX ttys". Donn From tom at pledger.gen.nz Thu Jun 18 17:58:14 2009 From: tom at pledger.gen.nz (Tom Pledger) Date: Thu Jun 18 17:41:44 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list References: <230AED6D-F69E-4B8E-BCED-BED620722B07@cs.otago.ac.nz> Message-ID: Daniel Peebles gmail.com> writes: > My solution attempted to exploit this using Numeric.showIntAtBase but > failed because of the lack of 0 prefixes in the numbers. If you can > find a simple way to fix it without duplicating the showIntAtBase > code, I'd be interested! Another advantage of the integer & base method is that it doesn't require a fast-growing amount of memory to keep track of everything between two points in the list. e.g. Hugs> let mywords = "":[w++[ch] | w <- mywords, ch <- ['a'..'z']] in mywords!!1000000 " ERROR - Garbage collection fails to reclaim sufficient space or Hugs> let sss = [""] : [ [ c:s | c <- ['a'..'z'], s <- ss ] | ss <- sss ] in concat (tail sss) !! 1000000 " ERROR - Garbage collection fails to reclaim sufficient space I'm not sure offhand why Reid Barton's replicateM solution doesn't have the same problem. Is it a benefit of the lack of sharing Matthew Brecknell mentioned? Control.Monad> concatMap (\n -> replicateM n ['a'..'z']) [1..] !! 5000000 "jxlks" Regards, Tom From michael at snoyman.com Thu Jun 18 18:12:25 2009 From: michael at snoyman.com (Michael Snoyman) Date: Thu Jun 18 17:55:37 2009 Subject: [Haskell-cafe] Use MySQL from Haskell In-Reply-To: <4A3AB0EA.4090304@googlemail.com> References: <4A3AB0EA.4090304@googlemail.com> Message-ID: <29bf512f0906181512i50dec0d9ge04be77ab4e3f668@mail.gmail.com> Marciej, I went the HDBC route and got the same problem. Although it does not seem to be officially blessed, try installing the time-1.1.3 package. It's working for me at least, which I know is a dubious recommendation. Also, I am currently using the hdbc-odbc package for accessing MySQL. I couldn't get hdbc-mysql to work properly. I hope that once I get this project working right, I'll have a chance to dig into the hdbc-mysql issue itself. Good luck! Michael On Fri, Jun 19, 2009 at 12:26 AM, Maciej Podgurski < maciej.podgurski@googlemail.com> wrote: > Hello, > > I'm trying to use MySQL from Haskell but it seems impossible for me to > install one of the MySQL packages on my Windows XP machine. > > First I tired to install hsql-mysql-1.7.1 on GHC 6.10.3 but installing > haskelldb-hsql failed with a hidden package error. So I added the old-time > package to the cabal file but there still was a compile error (something due > to the change from Exception to Exception e => e). > > So I switched to GHC 6.8.3 and tried it again. Now it says: > > Configuring hsql-mysql-1.7.1... > Warning: 'extra-lib-dirs: /usr/lib/mysql' directory does not exist. > Warning: 'include-dirs: /usr/include/mysql' directory does not exist. > Warning: This package indirectly depends on multiple versions of the same > package. This is highly likely to cause a compile failure. > package process-1.0.0.1 requires filepath-1.1.0.0 > package directory-1.0.0.1 requires filepath-1.1.0.0 > package Cabal-1.6.0.3 requires filepath-1.1.0.2 > Setup: Missing dependency on a foreign library: > * Missing C library: mysqlclient > This problem can usually be solved by installing the system package that > provides this library (you may need the "-dev" version). If the library is > already installed but in a non-standard location then you can use the flags > --extra-include-dirs= and --extra-lib-dirs= to specify where it is. > > There's no Haskell package mysqlclient and I don't know how to install a C > library in Haskell. So I switched to HDBC-2.1.1 and got the next compile > error: > > Building convertible-1.0.5... > > Data/Convertible/Instances/Num.hs:671:0: > warning: no newline at end of file > [...] > [5 of 8] Compiling Data.Convertible.Instances.C ( > Data/Convertible/Instances/C.hs, dist\build/Data/C > onvertible/Instances/C.o ) > [6 of 8] Compiling Data.Convertible.Instances.Time ( > Data/Convertible/Instances/Time.hs, dist\build/ > Data/Convertible/Instances/Time.o ) > > Data/Convertible/Instances/Time.hs:64:0: > Duplicate instance declarations: > instance Typeable NominalDiffTime > -- Defined at Data/Convertible/Instances/Time.hs:(64,0)-(65,42) > instance Typeable NominalDiffTime > -- Defined in time-1.1.3:Data.Time.Clock.UTC > > Data/Convertible/Instances/Time.hs:67:0: > Duplicate instance declarations: > instance Typeable UTCTime > -- Defined at Data/Convertible/Instances/Time.hs:(67,0)-(68,34) > instance Typeable UTCTime > -- Defined in time-1.1.3:Data.Time.Clock.UTC > > So please help me, what GHC/package configuration will I need to use MySQL > from my Haskell programs on Windows? I really like Haskell but all those > "broken" packages are really discouraging. :( > > > Best wishes, > Maciej > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090618/32418e3a/attachment.html From haskell at brecknell.org Thu Jun 18 18:17:07 2009 From: haskell at brecknell.org (Matthew Brecknell) Date: Thu Jun 18 18:00:24 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list In-Reply-To: References: Message-ID: <1245363427.8395.21.camel@localhost> On Thu, 2009-06-18 at 23:57 +0800, Lee Duhem wrote: > [...] I have prepared a blog post for how > I worked out some of these answers, here is the draft of it, I hope it > can help you too. Nice post! Certainly, pen-and-paper reasoning like this is a very good way to develop deeper intuitions. > Answer 1 (by Matthew Brecknell): > > concat $ tail $ iterate (map (:) ['a' .. 'z'] <*>) [[]] I actually said "tail $ concat $ iterate ...", because I think the initial empty string is logically part of the sequence. Tacking "tail" on the front then produces the subsequence requested by the OP. I should have given more credit to Reid for this solution. I'm always delighted to see people using monadic combinators (like replicateM) in the list monad, because I so rarely think to use them this way. Sadly, my understanding of these combinators is still somewhat stuck in IO, where I first learned them. I never would have thought to use <*> this way if I had not seen Reid's solution first. Also, for many applications, a non-sharing version like Reid's is really what you want. Sharing versions have to keep references to old strings around to reuse later, and so are really only appropriate for applications which would keep them in memory anyway. Regards, Matthew From niklas.broberg at gmail.com Thu Jun 18 19:52:30 2009 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Thu Jun 18 19:35:41 2009 Subject: [Haskell-cafe] Re: ANN: haskell-src-exts 1.0.0 rc1 (aka 0.5.2) In-Reply-To: References: Message-ID: > I have just uploaded haskell-src-exts-0.5.4 to hackage, which is 1.0.0 > rc2. Thanks a lot to those who tested the previous version, and please > continue to test and report! Another day, another release candidate. Please see haskell-src-exts-0.5.5, 1.0.0 rc3. Thanks a lot to all reports, and please keep up the good work! Changes in 0.5.5: ================ * BangPatterns are now correctly handled everywhere (I think - tricksy little imps they are). I would like to put out a special call for tests of files that use bang patterns, in particular if they appear in "strange" locations inside patterns. * TypeFamilies now implies KindSignatures, as in GHC. * Chained contexts, e.g. foo :: Eq a => Show a => a, are now handled correctly. * . is no longer considered a reserved operator but a special operator when explicit forall is enabled, which means Prelude.. now parses correctly. * Parenthesised patterns inside list patterns no longer require RegularPatterns enabled. * List expressions are no longer translated to tuple expressions by the fixity mangler (yes, it did that)... Cheers, /Niklas From lee.duhem at gmail.com Thu Jun 18 20:07:29 2009 From: lee.duhem at gmail.com (Lee Duhem) Date: Thu Jun 18 20:23:57 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list In-Reply-To: <1245363427.8395.21.camel@localhost> References: <1245363427.8395.21.camel@localhost> Message-ID: On Fri, Jun 19, 2009 at 6:17 AM, Matthew Brecknell wrote: > On Thu, 2009-06-18 at 23:57 +0800, Lee Duhem wrote: >> [...] I have prepared a blog post for how >> I worked out some of these answers, here is the draft of it, I hope it >> can help you too. > > Nice post! Certainly, pen-and-paper reasoning like this is a very good > way to develop deeper intuitions. > >> ? ? ? Answer 1 (by Matthew Brecknell): >> >> ? ? ? concat $ tail $ iterate (map (:) ['a' .. 'z'] <*>) [[]] > > I actually said "tail $ concat $ iterate ...", because I think the > initial empty string is logically part of the sequence. Tacking "tail" > on the front then produces the subsequence requested by the OP. Yes, I changed your solution from "tail $ concat $ iterate ..." to "concat $ tail $ iterate ...", because I think cut useless part out early is good idea, forgot to mention that, sorry. > > I should have given more credit to Reid for this solution. I'm always > delighted to see people using monadic combinators (like replicateM) in > the list monad, because I so rarely think to use them this way. Sadly, > my understanding of these combinators is still somewhat stuck in IO, > where I first learned them. I never would have thought to use <*> this > way if I had not seen Reid's solution first. Actually, I first figure out how Reid's solution works, then figure out yours. After that, I found, for me, your solution's logic is easier to understand, so I take it as my first example. As I said at the end, or as I'll said at the end, Reid' solution and yours are the same (except effective) lee From thecodewitch at gmail.com Thu Jun 18 21:51:55 2009 From: thecodewitch at gmail.com (Greg Santucci) Date: Thu Jun 18 21:35:05 2009 Subject: [Haskell-cafe] Compiling to C Message-ID: <66c9435a0906181851o69312599w228f78cdc22afe7f@mail.gmail.com> Hi all, I'd like to call Haskell functions from C and receive its output as a string. Is compiling a Haskell program to C using ghc -C HaskellSource.hs the preferred method of doing this? Regards, Greg -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090618/7fd10bf5/attachment.html From allbery at ece.cmu.edu Thu Jun 18 21:59:56 2009 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Thu Jun 18 21:43:25 2009 Subject: [Haskell-cafe] About the Monad Transformers In-Reply-To: References: Message-ID: <7DCD06BE-2B9A-4CFF-803C-BB23F8A710B5@ece.cmu.edu> Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090618/51eaef1c/PGP.bin From thecodewitch at gmail.com Thu Jun 18 22:04:07 2009 From: thecodewitch at gmail.com (Greg Santucci) Date: Thu Jun 18 21:47:18 2009 Subject: [Haskell-cafe] Re: Compiling to C In-Reply-To: <66c9435a0906181851o69312599w228f78cdc22afe7f@mail.gmail.com> References: <66c9435a0906181851o69312599w228f78cdc22afe7f@mail.gmail.com> Message-ID: <66c9435a0906181904r25fda183y2eb8b9f6f768cc85@mail.gmail.com> Never mind, I Found The Manual. (FTFM) http://www.haskell.org/ghc/docs/latest/html/users_guide/win32-dlls.html On Fri, Jun 19, 2009 at 12:51 PM, Greg Santucci wrote: > Hi all, > > I'd like to call Haskell functions from C and receive its output as a > string. Is compiling a Haskell program to C using ghc -C HaskellSource.hs > the preferred method of doing this? > > Regards, > Greg > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090618/e4a99777/attachment.html From jsnow at cs.pdx.edu Thu Jun 18 22:46:17 2009 From: jsnow at cs.pdx.edu (Jim Snow) Date: Thu Jun 18 23:20:51 2009 Subject: [Haskell-cafe] IORef memory leak Message-ID: <4A3AFBF9.5050907@cs.pdx.edu> I'm having some trouble with excessive memory use in a program that uses a lot of IORefs. I was able to write a much simpler program which exhibits the same sort of behavior. It appears that "modifyIORef" and "writeIORef" leak memory; perhaps they keep a reference to the old value. I tried both ghc-6.8.3 and ghc-6.10.1. Is this a known limitation, or is this a ghc bug, or am I using IORefs in the wrong way? -jim module Main where import Data.IORef import Control.Monad -- Leaks memory leakcheck1 ior = do go 1000000000 where go 0 = return () go n = do modifyIORef ior (+1) go (n-1) -- Leaks memory leakcheck2 ior = do go 1000000000 where go 0 = return () go n = do x <- readIORef ior writeIORef ior (x+1) go (n-1) -- Runs in constant memory leakcheck3 ior = do go 1000000000 where go 0 = return () go n = do x <- readIORef ior go (n-1) main :: IO () main = do ior <- newIORef 0 leakcheck2 ior compiled with: ghc -O2 --make Leak.hs -o Leak From rmm-haskell at z.odi.ac Thu Jun 18 23:55:41 2009 From: rmm-haskell at z.odi.ac (Ross Mellgren) Date: Thu Jun 18 23:38:55 2009 Subject: [Haskell-cafe] IORef memory leak In-Reply-To: <4A3AFBF9.5050907@cs.pdx.edu> References: <4A3AFBF9.5050907@cs.pdx.edu> Message-ID: <54D372AF-5F48-40CE-8F3D-2CF988266BD6@z.odi.ac> It looks offhand like you're not being strict enough when you put things back in the IORef, and so it's building up thunks of (+1)... With two slight mods: go 0 = return () go n = do modifyIORef ior (+1) go (n-1) --> go 0 = return () go n = do modifyIORef ior (\ x -> let x' = x+1 in x `seq` x') go (n-1) and go n = do x <- readIORef ior writeIORef ior (x+1) go (n-1) --> go n = do x <- readIORef ior writeIORef ior $! x+1 go (n-1) It runs much better (with loop count = 10,000,000) -- leak1 is the code you posted, leak2 is with these changes: rmm@Hugo:~$ ./leak1 +RTS -s ./leak1 +RTS -s 200,296,364 bytes allocated in the heap 365,950,896 bytes copied during GC 66,276,472 bytes maximum residency (7 sample(s)) 1,906,448 bytes maximum slop 131 MB total memory in use (1 MB lost due to fragmentation) %GC time 75.9% (79.2% elapsed) Alloc rate 977,656,335 bytes per MUT second Productivity 24.0% of total user, 20.5% of total elapsed rmm@Hugo:~$ ./leak2 +RTS -s ./leak2 +RTS -s 160,006,032 bytes allocated in the heap 11,720 bytes copied during GC 1,452 bytes maximum residency (1 sample(s)) 9,480 bytes maximum slop 1 MB total memory in use (0 MB lost due to fragmentation) %GC time 0.5% (0.8% elapsed) Alloc rate 626,590,037 bytes per MUT second Productivity 99.2% of total user, 97.8% of total elapsed -Ross On Jun 18, 2009, at 10:46 PM, Jim Snow wrote: > > I'm having some trouble with excessive memory use in a program that > uses a lot of IORefs. I was able to write a much simpler program > which exhibits the same sort of behavior. It appears that > "modifyIORef" and "writeIORef" leak memory; perhaps they keep a > reference to the old value. I tried both ghc-6.8.3 and ghc-6.10.1. > > Is this a known limitation, or is this a ghc bug, or am I using > IORefs in the wrong way? > > -jim > > > module Main where > > import Data.IORef > import Control.Monad > > -- Leaks memory > leakcheck1 ior = > do go 1000000000 > where > go 0 = return () > go n = do modifyIORef ior (+1) > go (n-1) > > -- Leaks memory > leakcheck2 ior = > do go 1000000000 > where > go 0 = return () > go n = do x <- readIORef ior > writeIORef ior (x+1) > go (n-1) > > -- Runs in constant memory > leakcheck3 ior = > do go 1000000000 > where > go 0 = return () > go n = do x <- readIORef ior > go (n-1) > > main :: IO () > main = > do ior <- newIORef 0 > leakcheck2 ior > > > compiled with: ghc -O2 --make Leak.hs -o Leak > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From twd2 at dockerz.net Fri Jun 19 00:04:46 2009 From: twd2 at dockerz.net (Tim Docker) Date: Thu Jun 18 23:47:59 2009 Subject: [Haskell-cafe] IORef memory leak In-Reply-To: <4A3AFBF9.5050907@cs.pdx.edu> References: <4A3AFBF9.5050907@cs.pdx.edu> Message-ID: <93fbda5b1eb9a326d23aea594af513e6.squirrel@dockerz.net> > I'm having some trouble with excessive memory use in a program that uses > a lot of IORefs. I was able to write a much simpler program which > exhibits the same sort of behavior. It appears that "modifyIORef" and > "writeIORef" leak memory; perhaps they keep a reference to the old > value. I tried both ghc-6.8.3 and ghc-6.10.1. modifyIORef and writeIORef are not sufficiently strict for your needs. See this recent thread: http://www.nabble.com/Stack-overflow-td23746120.html Tim From vigalchin at gmail.com Fri Jun 19 00:26:24 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Fri Jun 19 00:09:34 2009 Subject: [Haskell-cafe] packages on Hackage? Message-ID: <5ae4f2ba0906182126w6a094213o4594f7f3b16c505e@mail.gmail.com> Hello, Haskell packages on Hackage can be hosted anywhere, yes? If a Haskell package is hosted on Hackage, how often is it backed up? Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090619/95cc9a46/attachment.html From lrpalmer at gmail.com Fri Jun 19 00:45:52 2009 From: lrpalmer at gmail.com (Luke Palmer) Date: Fri Jun 19 00:29:02 2009 Subject: [Haskell-cafe] IORef memory leak In-Reply-To: <54D372AF-5F48-40CE-8F3D-2CF988266BD6@z.odi.ac> References: <4A3AFBF9.5050907@cs.pdx.edu> <54D372AF-5F48-40CE-8F3D-2CF988266BD6@z.odi.ac> Message-ID: <7ca3f0160906182145p863301fm1e0fe9de19a61467@mail.gmail.com> On Thu, Jun 18, 2009 at 9:55 PM, Ross Mellgren wrote: > It looks offhand like you're not being strict enough when you put things > back in the IORef, and so it's building up thunks of (+1)... > > With two slight mods: > > go 0 = return () > go n = do modifyIORef ior (+1) > go (n-1) > > --> > > go 0 = return () > go n = do modifyIORef ior (\ x -> let x' = x+1 in x `seq` x') > go (n-1) Just a slight prettification of that line: modifyIORef ior ((1+) $!) Or applied prefix if you prefer. Prefix ($!) has the nice interpretation as the HOF that makes its argument into a strict function. Luke -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090619/b6f81f85/attachment.html From rmm-haskell at z.odi.ac Fri Jun 19 01:00:56 2009 From: rmm-haskell at z.odi.ac (Ross Mellgren) Date: Fri Jun 19 00:44:10 2009 Subject: [Haskell-cafe] IORef memory leak In-Reply-To: <7ca3f0160906182145p863301fm1e0fe9de19a61467@mail.gmail.com> References: <4A3AFBF9.5050907@cs.pdx.edu> <54D372AF-5F48-40CE-8F3D-2CF988266BD6@z.odi.ac> <7ca3f0160906182145p863301fm1e0fe9de19a61467@mail.gmail.com> Message-ID: D'oh, yeah that is better. You know, I actually had that and had expanded it because I was going to seq both the input and the result of the (+1), but punted on it and didn't switch back to the more compact format. -Ross On Jun 19, 2009, at 12:45 AM, Luke Palmer wrote: > On Thu, Jun 18, 2009 at 9:55 PM, Ross Mellgren haskell@z.odi.ac> wrote: > It looks offhand like you're not being strict enough when you put > things back in the IORef, and so it's building up thunks of (+1)... > > With two slight mods: > > > go 0 = return () > go n = do modifyIORef ior (+1) > go (n-1) > > --> > > go 0 = return () > go n = do modifyIORef ior (\ x -> let x' = x+1 in x `seq` x') > go (n-1) > > Just a slight prettification of that line: > > modifyIORef ior ((1+) $!) > > Or applied prefix if you prefer. Prefix ($!) has the nice > interpretation as the HOF that makes its argument into a strict > function. > > Luke > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090619/0f9ff4a3/attachment.html From jsnow at cs.pdx.edu Fri Jun 19 00:09:46 2009 From: jsnow at cs.pdx.edu (Jim Snow) Date: Fri Jun 19 00:44:32 2009 Subject: [Haskell-cafe] IORef memory leak In-Reply-To: <7ca3f0160906182145p863301fm1e0fe9de19a61467@mail.gmail.com> References: <4A3AFBF9.5050907@cs.pdx.edu> <54D372AF-5F48-40CE-8F3D-2CF988266BD6@z.odi.ac> <7ca3f0160906182145p863301fm1e0fe9de19a61467@mail.gmail.com> Message-ID: <4A3B0F8A.4000508@cs.pdx.edu> Luke Palmer wrote: > On Thu, Jun 18, 2009 at 9:55 PM, Ross Mellgren > wrote: > > It looks offhand like you're not being strict enough when you put > things back in the IORef, and so it's building up thunks of (+1)... > > With two slight mods: > > > go 0 = return () > go n = do modifyIORef ior (+1) > go (n-1) > > --> > > go 0 = return () > go n = do modifyIORef ior (\ x -> let x' = x+1 in x `seq` x') > go (n-1) > > > Just a slight prettification of that line: > > modifyIORef ior ((1+) $!) > > Or applied prefix if you prefer. Prefix ($!) has the nice > interpretation as the HOF that makes its argument into a strict function. > > Luke > do modifyIORef ior (\ x -> let x' = x+1 in x `seq` x') and do modifyIORef ior ((1+) $!) both still leak memory for me. However, do x <- readIORef ior writeIORef ior $! x+1 runs in constant space. I was able to fix my original program, and now it uses a predictable amount of memory. Thanks! -jim From magicloud.magiclouds at gmail.com Fri Jun 19 01:24:13 2009 From: magicloud.magiclouds at gmail.com (Magicloud Magiclouds) Date: Fri Jun 19 01:07:24 2009 Subject: [Haskell-cafe] Could someone give me a sample about haskelldb? Message-ID: <3bd412d40906182224m416f56c4mec1435503eb43548@mail.gmail.com> Hi, I am learning it following the very few documents on its site. Well, I failed, with the import modules, I still cannot compile it. The error is on "T.*". 6 import Database.HaskellDB.HDBC.SQLite3 7 import Database.HaskellDB 8 import Database.HaskellDB.DBSpec 9 import Database.HaskellDB.DBSpec.PPHelpers 10 import Database.HaskellDB.Query 48 q = do 49 t <- table $ Table "notes" [] 50 restrict ( t!T.done .<>. False ) 51 r <- project ( T.subject << t!T.subject ) 52 order [ desc r T.priority 53 , desc r T.dt ] 54 return r -- ??????? ??????? From l-siebeneicher at versanet.de Fri Jun 19 02:49:54 2009 From: l-siebeneicher at versanet.de (Leonard Siebeneicher) Date: Fri Jun 19 02:33:09 2009 Subject: [Haskell-cafe] how to #include files within parsec ... without unsafePerformIO? Message-ID: <1245394194.7770.20.camel@TALWACHT> Hi Neil, Hi Daniel. Thank you for your help, using parsec 3.0.0 and liftIO was the solution. After installing new parsec I have had to use import Text.Parsec ... instead of ... import Text.ParserCombinators.Parsec ... to get it work. It seems Text.ParserCombinators.Parsec refers to old Parsec 2 Have a nice week--end, Leonard From g9ks157k at acme.softbase.org Fri Jun 19 03:06:39 2009 From: g9ks157k at acme.softbase.org (Wolfgang Jeltsch) Date: Fri Jun 19 02:49:50 2009 Subject: [Haskell-cafe] Creating a new Haskell mailing list In-Reply-To: <4A3A4D63.9070807@henning-thielemann.de> References: <442d2c4c0906171738r21b8ac36u1efb8803202185ed@mail.gmail.com> <4A3A4D63.9070807@henning-thielemann.de> Message-ID: <200906190906.40075.g9ks157k@acme.softbase.org> Am Donnerstag, 18. Juni 2009 16:21 schrieb Henning Thielemann: > Ryan Trinkle schrieb: > > Hi all, > > > > I'm interested in starting a mailing list on haskell.org > > . Who should I talk to about such things? > > Is it a mailing list related to a project? Then you may request a > project on community.haskell.org, then you can start a mailing list at > yourproject@project.haskell.org See . Best wishes, Wolfgang From dav.vire+haskell at gmail.com Fri Jun 19 03:29:40 2009 From: dav.vire+haskell at gmail.com (david48) Date: Fri Jun 19 03:12:52 2009 Subject: [Haskell-cafe] Use MySQL from Haskell In-Reply-To: <29bf512f0906181512i50dec0d9ge04be77ab4e3f668@mail.gmail.com> References: <4A3AB0EA.4090304@googlemail.com> <29bf512f0906181512i50dec0d9ge04be77ab4e3f668@mail.gmail.com> Message-ID: <4c88418c0906190029w21907d82u837a8a6188486904@mail.gmail.com> > Marciej, > > I went the HDBC route and got the same problem. Although it does not seem to > be officially blessed, try installing the time-1.1.3 package. It's working > for me at least, which I know is a dubious recommendation.What worked for me : 1) Install GHC 6.10.3 from the binary tarball 2) Intall the haskell platform. ( not without problems, sadly ) 3) cabal install HDBC-mysql voil?. That worked both on Kubuntu 9.04 and on Centos 5.3 On kubuntu it was a pain in the .... to figure out which files were needed for opengl. I had to make a symlink by hand. ( opengl was built by the haskell platform ) On centos 5.3 ... libedit was the problem, but once the haskell platform is installed, cabal install hdbc-mysql works like a charm. David. From fh-wedel at gmx.de Fri Jun 19 03:31:22 2009 From: fh-wedel at gmx.de (=?ISO-8859-15?Q?Bj=F6rn_Peem=F6ller?=) Date: Fri Jun 19 03:14:34 2009 Subject: [Haskell-cafe] Use MySQL from Haskell In-Reply-To: <4A3AB0EA.4090304@googlemail.com> References: <4A3AB0EA.4090304@googlemail.com> Message-ID: <4A3B3ECA.2010607@gmx.de> Maciej Podgurski schrieb: > So I switched to HDBC-2.1.1 and got the next compile error: > > Building convertible-1.0.5... > > Data/Convertible/Instances/Num.hs:671:0: > warning: no newline at end of file > [...] > [5 of 8] Compiling Data.Convertible.Instances.C ( > Data/Convertible/Instances/C.hs, dist\build/Data/C > onvertible/Instances/C.o ) > [6 of 8] Compiling Data.Convertible.Instances.Time ( > Data/Convertible/Instances/Time.hs, dist\build/ > Data/Convertible/Instances/Time.o ) > > Data/Convertible/Instances/Time.hs:64:0: > Duplicate instance declarations: > instance Typeable NominalDiffTime > -- Defined at Data/Convertible/Instances/Time.hs:(64,0)-(65,42) > instance Typeable NominalDiffTime > -- Defined in time-1.1.3:Data.Time.Clock.UTC > > Data/Convertible/Instances/Time.hs:67:0: > Duplicate instance declarations: > instance Typeable UTCTime > -- Defined at Data/Convertible/Instances/Time.hs:(67,0)-(68,34) > instance Typeable UTCTime > -- Defined in time-1.1.3:Data.Time.Clock.UTC Hi Maciej, this is quite easy to fix (although a little bit dirty). The problem is that time-1.1.3 now defines some Typeable instances which time-1.1.2.4 did not and which are therefore defined in convertible, too. I don't know a general fix to the problem, but you can either - download the convertible package and comment out the two instance declarations as shown in the error message and then cabal install it - install from Hackage with additional constraint: cabal install convertible --constraint=time<1.1.3 I hope this will help you get HDBC running. Cheers, Bj?rn From ekmett at gmail.com Fri Jun 19 03:46:18 2009 From: ekmett at gmail.com (Edward Kmett) Date: Fri Jun 19 03:29:28 2009 Subject: [Haskell-cafe] Runtime strictness analysis for polymorphic HOFs? In-Reply-To: <9d4d38820906180930g2e49aca4ne8569d5b0c117787@mail.gmail.com> References: <7fb8f82f0906180730x6b6d22e2na8959b240d4aef15@mail.gmail.com> <9d4d38820906180930g2e49aca4ne8569d5b0c117787@mail.gmail.com> Message-ID: <7fb8f82f0906190046m17c8c445x7f89550a2901dbc4@mail.gmail.com> Hi Max, I don't have anything in a public repository at this time. I have been exploring a series of designs in this space trying to see if any could be applied to a system like GHC's bytecode interpreter, but up to now I've been working mostly with cooperatively jitting x86-64 assembly to x86-64 assembly for a possibly commercial project. I have only recently started trying to adapt my research to a more functional setting. If you hop on #haskell some time, I'd be happy to talk further. -Edward Kmett On Thu, Jun 18, 2009 at 12:30 PM, Max Bolingbroke < batterseapower@hotmail.com> wrote: > 2009/6/18 Edward Kmett : > > What is interesting is in a lazy setting, if you are tracing a bytecode > > representation that knows about allocation and thunks, you can do some > > additional optimizations in here. If on every path to a side exit or the > end > > of the loop you find that the thunk is evaluated you can evaluate it > > strictly and move its execution earlier in the trace. This gives you a > weak > > form of runtime strictness analysis. If the pointer to that thunk never > > escapes, then you can unbox the contents of the thunk and operate on its > > members in registers. Add constant folding, polyinline caching to improve > > branch prediction for spineless tagless g-machine thunk evaluation, and > code > > migration to the side exits and it becomes an interesting runtime system. > > This sounds absolutely awesome! Is the source code for your prototype > publicly available anywhere? I'd love to take a look at the basic > structure of something like this - trace JITing is something I keep > meaning to look at in more depth. > > Cheers, > Max > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090619/0db0ef62/attachment.html From vigalchin at gmail.com Fri Jun 19 04:05:10 2009 From: vigalchin at gmail.com (Vasili I. Galchin) Date: Fri Jun 19 03:48:20 2009 Subject: [Haskell-cafe] FFI question Message-ID: <5ae4f2ba0906190105n25473f5bkcf5e368ed35e7677@mail.gmail.com> Hello, I would like to write bindings from Haskell to Java. Is this possible? If so, where are examples? Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090619/048c657e/attachment.html From magicloud.magiclouds at gmail.com Fri Jun 19 04:32:20 2009 From: magicloud.magiclouds at gmail.com (Magicloud Magiclouds) Date: Fri Jun 19 04:21:28 2009 Subject: [Haskell-cafe] Re: Could someone give me a sample about haskelldb? In-Reply-To: <3bd412d40906182224m416f56c4mec1435503eb43548@mail.gmail.com> References: <3bd412d40906182224m416f56c4mec1435503eb43548@mail.gmail.com> Message-ID: <3bd412d40906190132o569ab851ha139b7e7ab26b8fb@mail.gmail.com> I changed it, some other problem occured. 1. How to compare a BoolT column to a True? "t!c .<>. True" could not work. 2. What shoud I use after "!"? Like table!col, recordset!col, what is col? Thanks. On Fri, Jun 19, 2009 at 1:24 PM, Magicloud Magiclouds wrote: > Hi, > ?I am learning it following the very few documents on its site. Well, > I failed, with the import modules, I still cannot compile it. The > error is on "T.*". > > ?6 import Database.HaskellDB.HDBC.SQLite3 > ?7 import Database.HaskellDB > ?8 import Database.HaskellDB.DBSpec > ?9 import Database.HaskellDB.DBSpec.PPHelpers > 10 import Database.HaskellDB.Query > > 48 ? ? q = do > 49 ? ? ? t <- table $ Table "notes" [] > 50 ? ? ? restrict ( t!T.done .<>. False ) > 51 ? ? ? r <- project ( T.subject << t!T.subject ) > 52 ? ? ? order [ desc r T.priority > 53 ? ? ? ? ? ? , desc r T.dt ] > 54 ? ? ? return r > -- > ??????? > ??????? > -- ??????? ??????? From benjovi at gmx.net Fri Jun 19 05:16:34 2009 From: benjovi at gmx.net (Benedikt Huber) Date: Fri Jun 19 05:03:04 2009 Subject: [Haskell-cafe] Re: ANN: haskell-src-exts 1.0.0 rc1 (aka 0.5.2) In-Reply-To: References: Message-ID: <4A3B5772.8050704@gmx.net> Niklas Broberg schrieb: > Another day, another release candidate. Please see > haskell-src-exts-0.5.5, 1.0.0 rc3. Thanks a lot to all reports, and > please keep up the good work! > Hi Niklas, I'm not quite sure what language features are not supported yet (besides CPP), so I simply report the failures for the language.c darcs repo. The third failure might be due the missing lanugage flags, I'm not sure. ---- 1 ---- ./dist/build/Language/C/Parser/Lexer.hs: Parse error at line 4, col 1 Stripped down example: > {-# OPTIONS #-} > {-# LINE 49 "src/Language/C/Parser/Lexer.x" #-} > module Fail where ---- 2 ---- ./dist/build/Language/C/Parser/Parser.hs: Parse error in expression: at line 865, col 1 ---- 3 ---- ./examples/sourceview/GenericTree.hs: Parse error at line 22, col 32 Stripped down example: > {-# LANGUAGE Rank2Types, ScopedTypeVariables, FlexibleInstances, ImpredicativeTypes #-} > module GenericTree where > import Data.Typeable > dynRep :: (Typeable a) => a -> (TypeRep, forall b. (Typeable b) => b -> (Maybe b)) > dynRep a = (typeOf a, \_ -> cast a) keep up the good work ! cheers, benedikt -------------- next part -------------- {-# OPTIONS -fglasgow-exts -cpp #-} module Language.C.Parser.Parser ( -- * Parse a C translation unit parseC, -- * Exposed Parsers translUnitP, extDeclP, statementP, expressionP ) where -- Relevant C99 sections: -- -- 6.5 Expressions .1 - .17 and 6.6 (almost literally) -- Supported GNU extensions: -- - Allow a compound statement as an expression -- - Various __builtin_* forms that take type parameters -- - `alignof' expression or type -- - `__extension__' to suppress warnings about extensions -- - Allow taking address of a label with: && label -- - Omitting the `then' part of conditional expressions -- - complex numbers -- -- 6.7 C Declarations .1 -.8 -- Supported GNU extensions: -- - '__thread' thread local storage (6.7.1) -- -- 6.8 Statements .1 - .8 -- Supported GNU extensions: -- - case ranges (C99 6.8.1) -- - '__label__ ident;' declarations (C99 6.8.2) -- - computed gotos (C99 6.8.6) -- -- 6.9 Translation unit -- Supported GNU extensions: -- - allow empty translation_unit -- - allow redundant ';' -- - allow extension keyword before external declaration -- - asm definitions -- -- Since some of the grammar productions are quite difficult to read, -- (especially those involved with the decleration syntax) we document them -- with an extended syntax that allows a more consise representation: -- -- Ordinary rules -- -- foo named terminal or non-terminal -- -- 'c' terminal, literal character token -- -- A B concatenation -- -- A | B alternation -- -- (A) grouping -- -- Extended rules -- -- A? optional, short hand for (A|) or [A]{ 0==A || 1==A } -- -- ... stands for some part of the grammar omitted for clarity -- -- {A} represents sequences, 0 or more. -- -- modifier which states that any permutation of the immediate subterms is valid -- -- --- TODO ---------------------------------------------------------------------- -- -- !* We ignore the C99 static keyword (see C99 6.7.5.3) -- !* We do not distinguish in the AST between incomplete array types and -- complete variable length arrays ([ '*' ] means the latter). (see C99 6.7.5.2) -- !* The AST doesn't allow recording __attribute__ of unnamed struct field -- (see , struct_default_declaring_list, struct_identifier_declarator) -- !* see `We're being far to liberal here' (... struct definition within structs) -- * Documentation isn't complete and consistent yet. import Prelude hiding (reverse) import qualified Data.List as List import Control.Monad (mplus) import Language.C.Parser.Builtin (builtinTypeNames) import Language.C.Parser.Lexer (lexC, parseError) import Language.C.Parser.Tokens (CToken(..), GnuCTok(..), posLenOfTok) import Language.C.Parser.ParserMonad (P, failP, execParser, getNewName, addTypedef, shadowTypedef, getCurrentPosition, enterScope, leaveScope, getLastToken, getSavedToken, ParseError(..)) import Language.C.Data.RList import Language.C.Data.InputStream import Language.C.Data.Ident import Language.C.Data.Name import Language.C.Data.Node import Language.C.Data.Position import Language.C.Syntax #if __GLASGOW_HASKELL__ >= 503 import Data.Array #else import Array #endif #if __GLASGOW_HASKELL__ >= 503 import GHC.Exts #else import GlaExts #endif -- parser produced by Happy Version 1.16 newtype HappyAbsSyn = HappyAbsSyn (() -> ()) happyIn7 :: (CTranslUnit) -> (HappyAbsSyn ) happyIn7 x = unsafeCoerce# x {-# INLINE happyIn7 #-} happyOut7 :: (HappyAbsSyn ) -> (CTranslUnit) happyOut7 x = unsafeCoerce# x {-# INLINE happyOut7 #-} happyIn8 :: (Reversed [CExtDecl]) -> (HappyAbsSyn ) happyIn8 x = unsafeCoerce# x {-# INLINE happyIn8 #-} happyOut8 :: (HappyAbsSyn ) -> (Reversed [CExtDecl]) happyOut8 x = unsafeCoerce# x {-# INLINE happyOut8 #-} happyIn9 :: (CExtDecl) -> (HappyAbsSyn ) happyIn9 x = unsafeCoerce# x {-# INLINE happyIn9 #-} happyOut9 :: (HappyAbsSyn ) -> (CExtDecl) happyOut9 x = unsafeCoerce# x {-# INLINE happyOut9 #-} happyIn10 :: (CFunDef) -> (HappyAbsSyn ) happyIn10 x = unsafeCoerce# x {-# INLINE happyIn10 #-} happyOut10 :: (HappyAbsSyn ) -> (CFunDef) happyOut10 x = unsafeCoerce# x {-# INLINE happyOut10 #-} happyIn11 :: (CDeclr) -> (HappyAbsSyn ) happyIn11 x = unsafeCoerce# x {-# INLINE happyIn11 #-} happyOut11 :: (HappyAbsSyn ) -> (CDeclr) happyOut11 x = unsafeCoerce# x {-# INLINE happyOut11 #-} happyIn12 :: (CStat) -> (HappyAbsSyn ) happyIn12 x = unsafeCoerce# x {-# INLINE happyIn12 #-} happyOut12 :: (HappyAbsSyn ) -> (CStat) happyOut12 x = unsafeCoerce# x {-# INLINE happyOut12 #-} happyIn13 :: (CStat) -> (HappyAbsSyn ) happyIn13 x = unsafeCoerce# x {-# INLINE happyIn13 #-} happyOut13 :: (HappyAbsSyn ) -> (CStat) happyOut13 x = unsafeCoerce# x {-# INLINE happyOut13 #-} happyIn14 :: (CStat) -> (HappyAbsSyn ) happyIn14 x = unsafeCoerce# x {-# INLINE happyIn14 #-} happyOut14 :: (HappyAbsSyn ) -> (CStat) happyOut14 x = unsafeCoerce# x {-# INLINE happyOut14 #-} happyIn15 :: (()) -> (HappyAbsSyn ) happyIn15 x = unsafeCoerce# x {-# INLINE happyIn15 #-} happyOut15 :: (HappyAbsSyn ) -> (()) happyOut15 x = unsafeCoerce# x {-# INLINE happyOut15 #-} happyIn16 :: (()) -> (HappyAbsSyn ) happyIn16 x = unsafeCoerce# x {-# INLINE happyIn16 #-} happyOut16 :: (HappyAbsSyn ) -> (()) happyOut16 x = unsafeCoerce# x {-# INLINE happyOut16 #-} happyIn17 :: (Reversed [CBlockItem]) -> (HappyAbsSyn ) happyIn17 x = unsafeCoerce# x {-# INLINE happyIn17 #-} happyOut17 :: (HappyAbsSyn ) -> (Reversed [CBlockItem]) happyOut17 x = unsafeCoerce# x {-# INLINE happyOut17 #-} happyIn18 :: (CBlockItem) -> (HappyAbsSyn ) happyIn18 x = unsafeCoerce# x {-# INLINE happyIn18 #-} happyOut18 :: (HappyAbsSyn ) -> (CBlockItem) happyOut18 x = unsafeCoerce# x {-# INLINE happyOut18 #-} happyIn19 :: (CBlockItem) -> (HappyAbsSyn ) happyIn19 x = unsafeCoerce# x {-# INLINE happyIn19 #-} happyOut19 :: (HappyAbsSyn ) -> (CBlockItem) happyOut19 x = unsafeCoerce# x {-# INLINE happyOut19 #-} happyIn20 :: (CFunDef) -> (HappyAbsSyn ) happyIn20 x = unsafeCoerce# x {-# INLINE happyIn20 #-} happyOut20 :: (HappyAbsSyn ) -> (CFunDef) happyOut20 x = unsafeCoerce# x {-# INLINE happyOut20 #-} happyIn21 :: (Reversed [Ident]) -> (HappyAbsSyn ) happyIn21 x = unsafeCoerce# x {-# INLINE happyIn21 #-} happyOut21 :: (HappyAbsSyn ) -> (Reversed [Ident]) happyOut21 x = unsafeCoerce# x {-# INLINE happyOut21 #-} happyIn22 :: (CStat) -> (HappyAbsSyn ) happyIn22 x = unsafeCoerce# x {-# INLINE happyIn22 #-} happyOut22 :: (HappyAbsSyn ) -> (CStat) happyOut22 x = unsafeCoerce# x {-# INLINE happyOut22 #-} happyIn23 :: (CStat) -> (HappyAbsSyn ) happyIn23 x = unsafeCoerce# x {-# INLINE happyIn23 #-} happyOut23 :: (HappyAbsSyn ) -> (CStat) happyOut23 x = unsafeCoerce# x {-# INLINE happyOut23 #-} happyIn24 :: (CStat) -> (HappyAbsSyn ) happyIn24 x = unsafeCoerce# x {-# INLINE happyIn24 #-} happyOut24 :: (HappyAbsSyn ) -> (CStat) happyOut24 x = unsafeCoerce# x {-# INLINE happyOut24 #-} happyIn25 :: (CStat) -> (HappyAbsSyn ) happyIn25 x = unsafeCoerce# x {-# INLINE happyIn25 #-} happyOut25 :: (HappyAbsSyn ) -> (CStat) happyOut25 x = unsafeCoerce# x {-# INLINE happyOut25 #-} happyIn26 :: (CAsmStmt) -> (HappyAbsSyn ) happyIn26 x = unsafeCoerce# x {-# INLINE happyIn26 #-} happyOut26 :: (HappyAbsSyn ) -> (CAsmStmt) happyOut26 x = unsafeCoerce# x {-# INLINE happyOut26 #-} happyIn27 :: (Maybe CTypeQual) -> (HappyAbsSyn ) happyIn27 x = unsafeCoerce# x {-# INLINE happyIn27 #-} happyOut27 :: (HappyAbsSyn ) -> (Maybe CTypeQual) happyOut27 x = unsafeCoerce# x {-# INLINE happyOut27 #-} happyIn28 :: ([CAsmOperand]) -> (HappyAbsSyn ) happyIn28 x = unsafeCoerce# x {-# INLINE happyIn28 #-} happyOut28 :: (HappyAbsSyn ) -> ([CAsmOperand]) happyOut28 x = unsafeCoerce# x {-# INLINE happyOut28 #-} happyIn29 :: (Reversed [CAsmOperand]) -> (HappyAbsSyn ) happyIn29 x = unsafeCoerce# x {-# INLINE happyIn29 #-} happyOut29 :: (HappyAbsSyn ) -> (Reversed [CAsmOperand]) happyOut29 x = unsafeCoerce# x {-# INLINE happyOut29 #-} happyIn30 :: (CAsmOperand) -> (HappyAbsSyn ) happyIn30 x = unsafeCoerce# x {-# INLINE happyIn30 #-} happyOut30 :: (HappyAbsSyn ) -> (CAsmOperand) happyOut30 x = unsafeCoerce# x {-# INLINE happyOut30 #-} happyIn31 :: (Reversed [CStrLit]) -> (HappyAbsSyn ) happyIn31 x = unsafeCoerce# x {-# INLINE happyIn31 #-} happyOut31 :: (HappyAbsSyn ) -> (Reversed [CStrLit]) happyOut31 x = unsafeCoerce# x {-# INLINE happyOut31 #-} happyIn32 :: (CDecl) -> (HappyAbsSyn ) happyIn32 x = unsafeCoerce# x {-# INLINE happyIn32 #-} happyOut32 :: (HappyAbsSyn ) -> (CDecl) happyOut32 x = unsafeCoerce# x {-# INLINE happyOut32 #-} happyIn33 :: (Reversed [CDecl]) -> (HappyAbsSyn ) happyIn33 x = unsafeCoerce# x {-# INLINE happyIn33 #-} happyOut33 :: (HappyAbsSyn ) -> (Reversed [CDecl]) happyOut33 x = unsafeCoerce# x {-# INLINE happyOut33 #-} happyIn34 :: (CDecl) -> (HappyAbsSyn ) happyIn34 x = unsafeCoerce# x {-# INLINE happyIn34 #-} happyOut34 :: (HappyAbsSyn ) -> (CDecl) happyOut34 x = unsafeCoerce# x {-# INLINE happyOut34 #-} happyIn35 :: ((Maybe CStrLit, [CAttr])) -> (HappyAbsSyn ) happyIn35 x = unsafeCoerce# x {-# INLINE happyIn35 #-} happyOut35 :: (HappyAbsSyn ) -> ((Maybe CStrLit, [CAttr])) happyOut35 x = unsafeCoerce# x {-# INLINE happyOut35 #-} happyIn36 :: (CDecl) -> (HappyAbsSyn ) happyIn36 x = unsafeCoerce# x {-# INLINE happyIn36 #-} happyOut36 :: (HappyAbsSyn ) -> (CDecl) happyOut36 x = unsafeCoerce# x {-# INLINE happyOut36 #-} happyIn37 :: ([CDeclSpec]) -> (HappyAbsSyn ) happyIn37 x = unsafeCoerce# x {-# INLINE happyIn37 #-} happyOut37 :: (HappyAbsSyn ) -> ([CDeclSpec]) happyOut37 x = unsafeCoerce# x {-# INLINE happyOut37 #-} happyIn38 :: (Reversed [CDeclSpec]) -> (HappyAbsSyn ) happyIn38 x = unsafeCoerce# x {-# INLINE happyIn38 #-} happyOut38 :: (HappyAbsSyn ) -> (Reversed [CDeclSpec]) happyOut38 x = unsafeCoerce# x {-# INLINE happyOut38 #-} happyIn39 :: (CDeclSpec) -> (HappyAbsSyn ) happyIn39 x = unsafeCoerce# x {-# INLINE happyIn39 #-} happyOut39 :: (HappyAbsSyn ) -> (CDeclSpec) happyOut39 x = unsafeCoerce# x {-# INLINE happyOut39 #-} happyIn40 :: (CStorageSpec) -> (HappyAbsSyn ) happyIn40 x = unsafeCoerce# x {-# INLINE happyIn40 #-} happyOut40 :: (HappyAbsSyn ) -> (CStorageSpec) happyOut40 x = unsafeCoerce# x {-# INLINE happyOut40 #-} happyIn41 :: ([CDeclSpec]) -> (HappyAbsSyn ) happyIn41 x = unsafeCoerce# x {-# INLINE happyIn41 #-} happyOut41 :: (HappyAbsSyn ) -> ([CDeclSpec]) happyOut41 x = unsafeCoerce# x {-# INLINE happyOut41 #-} happyIn42 :: (CTypeSpec) -> (HappyAbsSyn ) happyIn42 x = unsafeCoerce# x {-# INLINE happyIn42 #-} happyOut42 :: (HappyAbsSyn ) -> (CTypeSpec) happyOut42 x = unsafeCoerce# x {-# INLINE happyOut42 #-} happyIn43 :: (Reversed [CDeclSpec]) -> (HappyAbsSyn ) happyIn43 x = unsafeCoerce# x {-# INLINE happyIn43 #-} happyOut43 :: (HappyAbsSyn ) -> (Reversed [CDeclSpec]) happyOut43 x = unsafeCoerce# x {-# INLINE happyOut43 #-} happyIn44 :: (Reversed [CDeclSpec]) -> (HappyAbsSyn ) happyIn44 x = unsafeCoerce# x {-# INLINE happyIn44 #-} happyOut44 :: (HappyAbsSyn ) -> (Reversed [CDeclSpec]) happyOut44 x = unsafeCoerce# x {-# INLINE happyOut44 #-} happyIn45 :: (Reversed [CDeclSpec]) -> (HappyAbsSyn ) happyIn45 x = unsafeCoerce# x {-# INLINE happyIn45 #-} happyOut45 :: (HappyAbsSyn ) -> (Reversed [CDeclSpec]) happyOut45 x = unsafeCoerce# x {-# INLINE happyOut45 #-} happyIn46 :: (Reversed [CDeclSpec]) -> (HappyAbsSyn ) happyIn46 x = unsafeCoerce# x {-# INLINE happyIn46 #-} happyOut46 :: (HappyAbsSyn ) -> (Reversed [CDeclSpec]) happyOut46 x = unsafeCoerce# x {-# INLINE happyOut46 #-} happyIn47 :: (Reversed [CDeclSpec]) -> (HappyAbsSyn ) happyIn47 x = unsafeCoerce# x {-# INLINE happyIn47 #-} happyOut47 :: (HappyAbsSyn ) -> (Reversed [CDeclSpec]) happyOut47 x = unsafeCoerce# x {-# INLINE happyOut47 #-} happyIn48 :: (Reversed [CDeclSpec]) -> (HappyAbsSyn ) happyIn48 x = unsafeCoerce# x {-# INLINE happyIn48 #-} happyOut48 :: (HappyAbsSyn ) -> (Reversed [CDeclSpec]) happyOut48 x = unsafeCoerce# x {-# INLINE happyOut48 #-} happyIn49 :: (CTypeSpec) -> (HappyAbsSyn ) happyIn49 x = unsafeCoerce# x {-# INLINE happyIn49 #-} happyOut49 :: (HappyAbsSyn ) -> (CTypeSpec) happyOut49 x = unsafeCoerce# x {-# INLINE happyOut49 #-} happyIn50 :: (CStructUnion) -> (HappyAbsSyn ) happyIn50 x = unsafeCoerce# x {-# INLINE happyIn50 #-} happyOut50 :: (HappyAbsSyn ) -> (CStructUnion) happyOut50 x = unsafeCoerce# x {-# INLINE happyOut50 #-} happyIn51 :: (Located CStructTag) -> (HappyAbsSyn ) happyIn51 x = unsafeCoerce# x {-# INLINE happyIn51 #-} happyOut51 :: (HappyAbsSyn ) -> (Located CStructTag) happyOut51 x = unsafeCoerce# x {-# INLINE happyOut51 #-} happyIn52 :: (Reversed [CDecl]) -> (HappyAbsSyn ) happyIn52 x = unsafeCoerce# x {-# INLINE happyIn52 #-} happyOut52 :: (HappyAbsSyn ) -> (Reversed [CDecl]) happyOut52 x = unsafeCoerce# x {-# INLINE happyOut52 #-} happyIn53 :: (CDecl) -> (HappyAbsSyn ) happyIn53 x = unsafeCoerce# x {-# INLINE happyIn53 #-} happyOut53 :: (HappyAbsSyn ) -> (CDecl) happyOut53 x = unsafeCoerce# x {-# INLINE happyOut53 #-} happyIn54 :: (CDecl) -> (HappyAbsSyn ) happyIn54 x = unsafeCoerce# x {-# INLINE happyIn54 #-} happyOut54 :: (HappyAbsSyn ) -> (CDecl) happyOut54 x = unsafeCoerce# x {-# INLINE happyOut54 #-} happyIn55 :: (CDecl) -> (HappyAbsSyn ) happyIn55 x = unsafeCoerce# x {-# INLINE happyIn55 #-} happyOut55 :: (HappyAbsSyn ) -> (CDecl) happyOut55 x = unsafeCoerce# x {-# INLINE happyOut55 #-} happyIn56 :: ((Maybe CDeclr, Maybe CExpr)) -> (HappyAbsSyn ) happyIn56 x = unsafeCoerce# x {-# INLINE happyIn56 #-} happyOut56 :: (HappyAbsSyn ) -> ((Maybe CDeclr, Maybe CExpr)) happyOut56 x = unsafeCoerce# x {-# INLINE happyOut56 #-} happyIn57 :: ((Maybe CDeclr, Maybe CExpr)) -> (HappyAbsSyn ) happyIn57 x = unsafeCoerce# x {-# INLINE happyIn57 #-} happyOut57 :: (HappyAbsSyn ) -> ((Maybe CDeclr, Maybe CExpr)) happyOut57 x = unsafeCoerce# x {-# INLINE happyOut57 #-} happyIn58 :: (CEnum) -> (HappyAbsSyn ) happyIn58 x = unsafeCoerce# x {-# INLINE happyIn58 #-} happyOut58 :: (HappyAbsSyn ) -> (CEnum) happyOut58 x = unsafeCoerce# x {-# INLINE happyOut58 #-} happyIn59 :: (Reversed [(Ident, Maybe CExpr)]) -> (HappyAbsSyn ) happyIn59 x = unsafeCoerce# x {-# INLINE happyIn59 #-} happyOut59 :: (HappyAbsSyn ) -> (Reversed [(Ident, Maybe CExpr)]) happyOut59 x = unsafeCoerce# x {-# INLINE happyOut59 #-} happyIn60 :: ((Ident, Maybe CExpr)) -> (HappyAbsSyn ) happyIn60 x = unsafeCoerce# x {-# INLINE happyIn60 #-} happyOut60 :: (HappyAbsSyn ) -> ((Ident, Maybe CExpr)) happyOut60 x = unsafeCoerce# x {-# INLINE happyOut60 #-} happyIn61 :: (CTypeQual) -> (HappyAbsSyn ) happyIn61 x = unsafeCoerce# x {-# INLINE happyIn61 #-} happyOut61 :: (HappyAbsSyn ) -> (CTypeQual) happyOut61 x = unsafeCoerce# x {-# INLINE happyOut61 #-} happyIn62 :: (Reversed [CTypeQual]) -> (HappyAbsSyn ) happyIn62 x = unsafeCoerce# x {-# INLINE happyIn62 #-} happyOut62 :: (HappyAbsSyn ) -> (Reversed [CTypeQual]) happyOut62 x = unsafeCoerce# x {-# INLINE happyOut62 #-} happyIn63 :: (CDeclrR) -> (HappyAbsSyn ) happyIn63 x = unsafeCoerce# x {-# INLINE happyIn63 #-} happyOut63 :: (HappyAbsSyn ) -> (CDeclrR) happyOut63 x = unsafeCoerce# x {-# INLINE happyOut63 #-} happyIn64 :: (Maybe CStrLit) -> (HappyAbsSyn ) happyIn64 x = unsafeCoerce# x {-# INLINE happyIn64 #-} happyOut64 :: (HappyAbsSyn ) -> (Maybe CStrLit) happyOut64 x = unsafeCoerce# x {-# INLINE happyOut64 #-} happyIn65 :: (CDeclrR) -> (HappyAbsSyn ) happyIn65 x = unsafeCoerce# x {-# INLINE happyIn65 #-} happyOut65 :: (HappyAbsSyn ) -> (CDeclrR) happyOut65 x = unsafeCoerce# x {-# INLINE happyOut65 #-} happyIn66 :: (CDeclrR) -> (HappyAbsSyn ) happyIn66 x = unsafeCoerce# x {-# INLINE happyIn66 #-} happyOut66 :: (HappyAbsSyn ) -> (CDeclrR) happyOut66 x = unsafeCoerce# x {-# INLINE happyOut66 #-} happyIn67 :: (CDeclrR) -> (HappyAbsSyn ) happyIn67 x = unsafeCoerce# x {-# INLINE happyIn67 #-} happyOut67 :: (HappyAbsSyn ) -> (CDeclrR) happyOut67 x = unsafeCoerce# x {-# INLINE happyOut67 #-} happyIn68 :: (CDeclrR) -> (HappyAbsSyn ) happyIn68 x = unsafeCoerce# x {-# INLINE happyIn68 #-} happyOut68 :: (HappyAbsSyn ) -> (CDeclrR) happyOut68 x = unsafeCoerce# x {-# INLINE happyOut68 #-} happyIn69 :: (CDeclrR) -> (HappyAbsSyn ) happyIn69 x = unsafeCoerce# x {-# INLINE happyIn69 #-} happyOut69 :: (HappyAbsSyn ) -> (CDeclrR) happyOut69 x = unsafeCoerce# x {-# INLINE happyOut69 #-} happyIn70 :: (CDeclrR) -> (HappyAbsSyn ) happyIn70 x = unsafeCoerce# x {-# INLINE happyIn70 #-} happyOut70 :: (HappyAbsSyn ) -> (CDeclrR) happyOut70 x = unsafeCoerce# x {-# INLINE happyOut70 #-} happyIn71 :: (CDeclrR) -> (HappyAbsSyn ) happyIn71 x = unsafeCoerce# x {-# INLINE happyIn71 #-} happyOut71 :: (HappyAbsSyn ) -> (CDeclrR) happyOut71 x = unsafeCoerce# x {-# INLINE happyOut71 #-} happyIn72 :: (CDeclrR) -> (HappyAbsSyn ) happyIn72 x = unsafeCoerce# x {-# INLINE happyIn72 #-} happyOut72 :: (HappyAbsSyn ) -> (CDeclrR) happyOut72 x = unsafeCoerce# x {-# INLINE happyOut72 #-} happyIn73 :: (CDeclrR) -> (HappyAbsSyn ) happyIn73 x = unsafeCoerce# x {-# INLINE happyIn73 #-} happyOut73 :: (HappyAbsSyn ) -> (CDeclrR) happyOut73 x = unsafeCoerce# x {-# INLINE happyOut73 #-} happyIn74 :: (CDeclrR) -> (HappyAbsSyn ) happyIn74 x = unsafeCoerce# x {-# INLINE happyIn74 #-} happyOut74 :: (HappyAbsSyn ) -> (CDeclrR) happyOut74 x = unsafeCoerce# x {-# INLINE happyOut74 #-} happyIn75 :: (CDeclrR) -> (HappyAbsSyn ) happyIn75 x = unsafeCoerce# x {-# INLINE happyIn75 #-} happyOut75 :: (HappyAbsSyn ) -> (CDeclrR) happyOut75 x = unsafeCoerce# x {-# INLINE happyOut75 #-} happyIn76 :: (CDeclr) -> (HappyAbsSyn ) happyIn76 x = unsafeCoerce# x {-# INLINE happyIn76 #-} happyOut76 :: (HappyAbsSyn ) -> (CDeclr) happyOut76 x = unsafeCoerce# x {-# INLINE happyOut76 #-} happyIn77 :: (CDeclrR) -> (HappyAbsSyn ) happyIn77 x = unsafeCoerce# x {-# INLINE happyIn77 #-} happyOut77 :: (HappyAbsSyn ) -> (CDeclrR) happyOut77 x = unsafeCoerce# x {-# INLINE happyOut77 #-} happyIn78 :: (CDeclrR) -> (HappyAbsSyn ) happyIn78 x = unsafeCoerce# x {-# INLINE happyIn78 #-} happyOut78 :: (HappyAbsSyn ) -> (CDeclrR) happyOut78 x = unsafeCoerce# x {-# INLINE happyOut78 #-} happyIn79 :: (([CDecl], Bool)) -> (HappyAbsSyn ) happyIn79 x = unsafeCoerce# x {-# INLINE happyIn79 #-} happyOut79 :: (HappyAbsSyn ) -> (([CDecl], Bool)) happyOut79 x = unsafeCoerce# x {-# INLINE happyOut79 #-} happyIn80 :: (Reversed [CDecl]) -> (HappyAbsSyn ) happyIn80 x = unsafeCoerce# x {-# INLINE happyIn80 #-} happyOut80 :: (HappyAbsSyn ) -> (Reversed [CDecl]) happyOut80 x = unsafeCoerce# x {-# INLINE happyOut80 #-} happyIn81 :: (CDecl) -> (HappyAbsSyn ) happyIn81 x = unsafeCoerce# x {-# INLINE happyIn81 #-} happyOut81 :: (HappyAbsSyn ) -> (CDecl) happyOut81 x = unsafeCoerce# x {-# INLINE happyOut81 #-} happyIn82 :: (Reversed [Ident]) -> (HappyAbsSyn ) happyIn82 x = unsafeCoerce# x {-# INLINE happyIn82 #-} happyOut82 :: (HappyAbsSyn ) -> (Reversed [Ident]) happyOut82 x = unsafeCoerce# x {-# INLINE happyOut82 #-} happyIn83 :: (CDecl) -> (HappyAbsSyn ) happyIn83 x = unsafeCoerce# x {-# INLINE happyIn83 #-} happyOut83 :: (HappyAbsSyn ) -> (CDecl) happyOut83 x = unsafeCoerce# x {-# INLINE happyOut83 #-} happyIn84 :: (CDeclrR) -> (HappyAbsSyn ) happyIn84 x = unsafeCoerce# x {-# INLINE happyIn84 #-} happyOut84 :: (HappyAbsSyn ) -> (CDeclrR) happyOut84 x = unsafeCoerce# x {-# INLINE happyOut84 #-} happyIn85 :: (CDeclrR -> CDeclrR) -> (HappyAbsSyn ) happyIn85 x = unsafeCoerce# x {-# INLINE happyIn85 #-} happyOut85 :: (HappyAbsSyn ) -> (CDeclrR -> CDeclrR) happyOut85 x = unsafeCoerce# x {-# INLINE happyOut85 #-} happyIn86 :: (CDeclrR -> CDeclrR) -> (HappyAbsSyn ) happyIn86 x = unsafeCoerce# x {-# INLINE happyIn86 #-} happyOut86 :: (HappyAbsSyn ) -> (CDeclrR -> CDeclrR) happyOut86 x = unsafeCoerce# x {-# INLINE happyOut86 #-} happyIn87 :: (CDeclrR -> CDeclrR) -> (HappyAbsSyn ) happyIn87 x = unsafeCoerce# x {-# INLINE happyIn87 #-} happyOut87 :: (HappyAbsSyn ) -> (CDeclrR -> CDeclrR) happyOut87 x = unsafeCoerce# x {-# INLINE happyOut87 #-} happyIn88 :: (CDeclrR) -> (HappyAbsSyn ) happyIn88 x = unsafeCoerce# x {-# INLINE happyIn88 #-} happyOut88 :: (HappyAbsSyn ) -> (CDeclrR) happyOut88 x = unsafeCoerce# x {-# INLINE happyOut88 #-} happyIn89 :: (CDeclrR) -> (HappyAbsSyn ) happyIn89 x = unsafeCoerce# x {-# INLINE happyIn89 #-} happyOut89 :: (HappyAbsSyn ) -> (CDeclrR) happyOut89 x = unsafeCoerce# x {-# INLINE happyOut89 #-} happyIn90 :: (CInit) -> (HappyAbsSyn ) happyIn90 x = unsafeCoerce# x {-# INLINE happyIn90 #-} happyOut90 :: (HappyAbsSyn ) -> (CInit) happyOut90 x = unsafeCoerce# x {-# INLINE happyOut90 #-} happyIn91 :: (Maybe CInit) -> (HappyAbsSyn ) happyIn91 x = unsafeCoerce# x {-# INLINE happyIn91 #-} happyOut91 :: (HappyAbsSyn ) -> (Maybe CInit) happyOut91 x = unsafeCoerce# x {-# INLINE happyOut91 #-} happyIn92 :: (Reversed CInitList) -> (HappyAbsSyn ) happyIn92 x = unsafeCoerce# x {-# INLINE happyIn92 #-} happyOut92 :: (HappyAbsSyn ) -> (Reversed CInitList) happyOut92 x = unsafeCoerce# x {-# INLINE happyOut92 #-} happyIn93 :: ([CDesignator]) -> (HappyAbsSyn ) happyIn93 x = unsafeCoerce# x {-# INLINE happyIn93 #-} happyOut93 :: (HappyAbsSyn ) -> ([CDesignator]) happyOut93 x = unsafeCoerce# x {-# INLINE happyOut93 #-} happyIn94 :: (Reversed [CDesignator]) -> (HappyAbsSyn ) happyIn94 x = unsafeCoerce# x {-# INLINE happyIn94 #-} happyOut94 :: (HappyAbsSyn ) -> (Reversed [CDesignator]) happyOut94 x = unsafeCoerce# x {-# INLINE happyOut94 #-} happyIn95 :: (CDesignator) -> (HappyAbsSyn ) happyIn95 x = unsafeCoerce# x {-# INLINE happyIn95 #-} happyOut95 :: (HappyAbsSyn ) -> (CDesignator) happyOut95 x = unsafeCoerce# x {-# INLINE happyOut95 #-} happyIn96 :: (CDesignator) -> (HappyAbsSyn ) happyIn96 x = unsafeCoerce# x {-# INLINE happyIn96 #-} happyOut96 :: (HappyAbsSyn ) -> (CDesignator) happyOut96 x = unsafeCoerce# x {-# INLINE happyOut96 #-} happyIn97 :: (CExpr) -> (HappyAbsSyn ) happyIn97 x = unsafeCoerce# x {-# INLINE happyIn97 #-} happyOut97 :: (HappyAbsSyn ) -> (CExpr) happyOut97 x = unsafeCoerce# x {-# INLINE happyOut97 #-} happyIn98 :: (Reversed [CDesignator]) -> (HappyAbsSyn ) happyIn98 x = unsafeCoerce# x {-# INLINE happyIn98 #-} happyOut98 :: (HappyAbsSyn ) -> (Reversed [CDesignator]) happyOut98 x = unsafeCoerce# x {-# INLINE happyOut98 #-} happyIn99 :: (CExpr) -> (HappyAbsSyn ) happyIn99 x = unsafeCoerce# x {-# INLINE happyIn99 #-} happyOut99 :: (HappyAbsSyn ) -> (CExpr) happyOut99 x = unsafeCoerce# x {-# INLINE happyOut99 #-} happyIn100 :: (Reversed [CExpr]) -> (HappyAbsSyn ) happyIn100 x = unsafeCoerce# x {-# INLINE happyIn100 #-} happyOut100 :: (HappyAbsSyn ) -> (Reversed [CExpr]) happyOut100 x = unsafeCoerce# x {-# INLINE happyOut100 #-} happyIn101 :: (CExpr) -> (HappyAbsSyn ) happyIn101 x = unsafeCoerce# x {-# INLINE happyIn101 #-} happyOut101 :: (HappyAbsSyn ) -> (CExpr) happyOut101 x = unsafeCoerce# x {-# INLINE happyOut101 #-} happyIn102 :: (Located CUnaryOp) -> (HappyAbsSyn ) happyIn102 x = unsafeCoerce# x {-# INLINE happyIn102 #-} happyOut102 :: (HappyAbsSyn ) -> (Located CUnaryOp) happyOut102 x = unsafeCoerce# x {-# INLINE happyOut102 #-} happyIn103 :: (CExpr) -> (HappyAbsSyn ) happyIn103 x = unsafeCoerce# x {-# INLINE happyIn103 #-} happyOut103 :: (HappyAbsSyn ) -> (CExpr) happyOut103 x = unsafeCoerce# x {-# INLINE happyOut103 #-} happyIn104 :: (CExpr) -> (HappyAbsSyn ) happyIn104 x = unsafeCoerce# x {-# INLINE happyIn104 #-} happyOut104 :: (HappyAbsSyn ) -> (CExpr) happyOut104 x = unsafeCoerce# x {-# INLINE happyOut104 #-} happyIn105 :: (CExpr) -> (HappyAbsSyn ) happyIn105 x = unsafeCoerce# x {-# INLINE happyIn105 #-} happyOut105 :: (HappyAbsSyn ) -> (CExpr) happyOut105 x = unsafeCoerce# x {-# INLINE happyOut105 #-} happyIn106 :: (CExpr) -> (HappyAbsSyn ) happyIn106 x = unsafeCoerce# x {-# INLINE happyIn106 #-} happyOut106 :: (HappyAbsSyn ) -> (CExpr) happyOut106 x = unsafeCoerce# x {-# INLINE happyOut106 #-} happyIn107 :: (CExpr) -> (HappyAbsSyn ) happyIn107 x = unsafeCoerce# x {-# INLINE happyIn107 #-} happyOut107 :: (HappyAbsSyn ) -> (CExpr) happyOut107 x = unsafeCoerce# x {-# INLINE happyOut107 #-} happyIn108 :: (CExpr) -> (HappyAbsSyn ) happyIn108 x = unsafeCoerce# x {-# INLINE happyIn108 #-} happyOut108 :: (HappyAbsSyn ) -> (CExpr) happyOut108 x = unsafeCoerce# x {-# INLINE happyOut108 #-} happyIn109 :: (CExpr) -> (HappyAbsSyn ) happyIn109 x = unsafeCoerce# x {-# INLINE happyIn109 #-} happyOut109 :: (HappyAbsSyn ) -> (CExpr) happyOut109 x = unsafeCoerce# x {-# INLINE happyOut109 #-} happyIn110 :: (CExpr) -> (HappyAbsSyn ) happyIn110 x = unsafeCoerce# x {-# INLINE happyIn110 #-} happyOut110 :: (HappyAbsSyn ) -> (CExpr) happyOut110 x = unsafeCoerce# x {-# INLINE happyOut110 #-} happyIn111 :: (CExpr) -> (HappyAbsSyn ) happyIn111 x = unsafeCoerce# x {-# INLINE happyIn111 #-} happyOut111 :: (HappyAbsSyn ) -> (CExpr) happyOut111 x = unsafeCoerce# x {-# INLINE happyOut111 #-} happyIn112 :: (CExpr) -> (HappyAbsSyn ) happyIn112 x = unsafeCoerce# x {-# INLINE happyIn112 #-} happyOut112 :: (HappyAbsSyn ) -> (CExpr) happyOut112 x = unsafeCoerce# x {-# INLINE happyOut112 #-} happyIn113 :: (CExpr) -> (HappyAbsSyn ) happyIn113 x = unsafeCoerce# x {-# INLINE happyIn113 #-} happyOut113 :: (HappyAbsSyn ) -> (CExpr) happyOut113 x = unsafeCoerce# x {-# INLINE happyOut113 #-} happyIn114 :: (CExpr) -> (HappyAbsSyn ) happyIn114 x = unsafeCoerce# x {-# INLINE happyIn114 #-} happyOut114 :: (HappyAbsSyn ) -> (CExpr) happyOut114 x = unsafeCoerce# x {-# INLINE happyOut114 #-} happyIn115 :: (CExpr) -> (HappyAbsSyn ) happyIn115 x = unsafeCoerce# x {-# INLINE happyIn115 #-} happyOut115 :: (HappyAbsSyn ) -> (CExpr) happyOut115 x = unsafeCoerce# x {-# INLINE happyOut115 #-} happyIn116 :: (Located CAssignOp) -> (HappyAbsSyn ) happyIn116 x = unsafeCoerce# x {-# INLINE happyIn116 #-} happyOut116 :: (HappyAbsSyn ) -> (Located CAssignOp) happyOut116 x = unsafeCoerce# x {-# INLINE happyOut116 #-} happyIn117 :: (CExpr) -> (HappyAbsSyn ) happyIn117 x = unsafeCoerce# x {-# INLINE happyIn117 #-} happyOut117 :: (HappyAbsSyn ) -> (CExpr) happyOut117 x = unsafeCoerce# x {-# INLINE happyOut117 #-} happyIn118 :: (Reversed [CExpr]) -> (HappyAbsSyn ) happyIn118 x = unsafeCoerce# x {-# INLINE happyIn118 #-} happyOut118 :: (HappyAbsSyn ) -> (Reversed [CExpr]) happyOut118 x = unsafeCoerce# x {-# INLINE happyOut118 #-} happyIn119 :: (Maybe CExpr) -> (HappyAbsSyn ) happyIn119 x = unsafeCoerce# x {-# INLINE happyIn119 #-} happyOut119 :: (HappyAbsSyn ) -> (Maybe CExpr) happyOut119 x = unsafeCoerce# x {-# INLINE happyOut119 #-} happyIn120 :: (Maybe CExpr) -> (HappyAbsSyn ) happyIn120 x = unsafeCoerce# x {-# INLINE happyIn120 #-} happyOut120 :: (HappyAbsSyn ) -> (Maybe CExpr) happyOut120 x = unsafeCoerce# x {-# INLINE happyOut120 #-} happyIn121 :: (CExpr) -> (HappyAbsSyn ) happyIn121 x = unsafeCoerce# x {-# INLINE happyIn121 #-} happyOut121 :: (HappyAbsSyn ) -> (CExpr) happyOut121 x = unsafeCoerce# x {-# INLINE happyOut121 #-} happyIn122 :: (CConst) -> (HappyAbsSyn ) happyIn122 x = unsafeCoerce# x {-# INLINE happyIn122 #-} happyOut122 :: (HappyAbsSyn ) -> (CConst) happyOut122 x = unsafeCoerce# x {-# INLINE happyOut122 #-} happyIn123 :: (CStrLit) -> (HappyAbsSyn ) happyIn123 x = unsafeCoerce# x {-# INLINE happyIn123 #-} happyOut123 :: (HappyAbsSyn ) -> (CStrLit) happyOut123 x = unsafeCoerce# x {-# INLINE happyOut123 #-} happyIn124 :: (Reversed [CString]) -> (HappyAbsSyn ) happyIn124 x = unsafeCoerce# x {-# INLINE happyIn124 #-} happyOut124 :: (HappyAbsSyn ) -> (Reversed [CString]) happyOut124 x = unsafeCoerce# x {-# INLINE happyOut124 #-} happyIn125 :: (Ident) -> (HappyAbsSyn ) happyIn125 x = unsafeCoerce# x {-# INLINE happyIn125 #-} happyOut125 :: (HappyAbsSyn ) -> (Ident) happyOut125 x = unsafeCoerce# x {-# INLINE happyOut125 #-} happyIn126 :: ([CAttr]) -> (HappyAbsSyn ) happyIn126 x = unsafeCoerce# x {-# INLINE happyIn126 #-} happyOut126 :: (HappyAbsSyn ) -> ([CAttr]) happyOut126 x = unsafeCoerce# x {-# INLINE happyOut126 #-} happyIn127 :: ([CAttr]) -> (HappyAbsSyn ) happyIn127 x = unsafeCoerce# x {-# INLINE happyIn127 #-} happyOut127 :: (HappyAbsSyn ) -> ([CAttr]) happyOut127 x = unsafeCoerce# x {-# INLINE happyOut127 #-} happyIn128 :: ([CAttr]) -> (HappyAbsSyn ) happyIn128 x = unsafeCoerce# x {-# INLINE happyIn128 #-} happyOut128 :: (HappyAbsSyn ) -> ([CAttr]) happyOut128 x = unsafeCoerce# x {-# INLINE happyOut128 #-} happyIn129 :: (Reversed [CAttr]) -> (HappyAbsSyn ) happyIn129 x = unsafeCoerce# x {-# INLINE happyIn129 #-} happyOut129 :: (HappyAbsSyn ) -> (Reversed [CAttr]) happyOut129 x = unsafeCoerce# x {-# INLINE happyOut129 #-} happyIn130 :: (Maybe CAttr) -> (HappyAbsSyn ) happyIn130 x = unsafeCoerce# x {-# INLINE happyIn130 #-} happyOut130 :: (HappyAbsSyn ) -> (Maybe CAttr) happyOut130 x = unsafeCoerce# x {-# INLINE happyOut130 #-} happyIn131 :: (Reversed [CExpr]) -> (HappyAbsSyn ) happyIn131 x = unsafeCoerce# x {-# INLINE happyIn131 #-} happyOut131 :: (HappyAbsSyn ) -> (Reversed [CExpr]) happyOut131 x = unsafeCoerce# x {-# INLINE happyOut131 #-} happyInTok :: CToken -> (HappyAbsSyn ) happyInTok x = unsafeCoerce# x {-# INLINE happyInTok #-} happyOutTok :: (HappyAbsSyn ) -> CToken happyOutTok x = unsafeCoerce# x {-# INLINE happyOutTok #-} happyActOffsets :: HappyAddr happyActOffsets = HappyA# "\x00\x00\x1d\x0f\xd3\x09\x31\x0f\x00\x00\x80\x07\x00\x00\x7f\x09\x77\x0f\x31\x0f\x00\x00\xc8\x09\x1f\x05\x05\x05\x7f\x03\xf0\x04\x65\x08\x54\x08\x49\x08\x3e\x08\xc6\x04\x00\x00\x2b\x08\xef\x07\x00\x00\x00\x00\x0b\x09\x00\x00\x00\x00\xcd\x0e\xcd\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x82\x04\xaf\x0e\x96\x0e\x00\x00\x00\x00\x00\x00\xf6\x07\x00\x00\x32\x0e\x14\x0e\x14\x0e\x48\x08\x47\x08\x24\x08\xb6\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\x07\xe6\x07\x00\x00\x00\x00\x4a\x05\xd2\x07\xfb\x0d\xd0\x07\xd6\x07\xd3\x09\xf5\x07\x24\x00\xed\x07\xfb\x0d\xec\x07\xd5\x07\xc6\x07\x00\x00\x76\x07\x00\x00\xae\x07\x00\x00\x95\x04\x8e\x04\x01\x01\xd5\x11\x00\x00\x01\x01\x00\x00\x9a\x19\x9a\x19\x11\x18\x01\x18\x21\x08\x21\x08\x00\x00\x00\x00\x71\x07\x00\x00\xa6\x11\x00\x00\x00\x00\x00\x00\xd9\x01\x00\x00\x00\x00\x00\x00\x4a\x05\x89\x12\x00\x00\x3d\x01\x3d\x01\xcb\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6b\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb\x07\x1d\x0f\x55\x07\x00\x00\xb8\x07\x6f\x09\x7a\x01\x59\x07\x5b\x07\xb3\x12\x00\x00\x00\x00\x4b\x00\xb2\x07\xb4\x09\xaa\x07\x4b\x00\x86\x07\x00\x00\x00\x00\x00\x00\xed\x01\x00\x00\x00\x00\xa7\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x38\x18\x00\x00\x9d\x07\x00\x00\x94\x18\xff\x0a\x72\x07\x00\x00\x00\x00\x00\x00\x00\x00\xed\x01\x00\x00\x77\x11\x97\x07\x00\x00\xa3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x67\x07\x5f\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x62\x07\x00\x00\x6e\x02\x48\x02\x0f\x00\x52\x07\x00\x00\x00\x00\x00\x00\xed\x01\x00\x00\x00\x00\x7b\x07\x00\x00\x4f\x07\x53\x07\x00\x00\x1b\x07\x00\x00\x1b\x07\x00\x00\x00\x00\xfb\x0d\xfb\x0d\x00\x00\x4d\x07\xfb\x0d\x41\x07\xfb\x0d\x00\x00\x43\x08\x14\x07\xd3\x09\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x65\x07\x00\x00\x2e\x07\xf4\x06\x00\x00\xc3\x1a\xc3\x1a\xfb\x0d\x00\x00\x0b\x09\x00\x00\x00\x00\xf0\x06\x00\x00\x00\x00\x0b\x09\x00\x00\x0b\x09\x00\x00\x00\x00\x00\x00\x4e\x07\x97\x03\xe7\x1a\xab\x04\xab\x04\x7a\x0a\x4c\x07\x4b\x07\x9f\x1a\xfb\x0d\xfb\x0d\x97\x0d\xfb\x0d\xfb\x0d\xfb\x0d\xfb\x0d\xfb\x0d\xfb\x0d\xfb\x0d\xfb\x0d\xfb\x0d\xfb\x0d\xfb\x0d\xfb\x0d\xfb\x0d\xfb\x0d\xfb\x0d\xfb\x0d\xfb\x0d\x00\x00\xfb\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x0d\xfb\x0d\x36\x04\x36\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x07\x6e\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\x09\xa3\x09\x8a\x04\x8a\x04\x4f\x04\x4f\x04\x4f\x04\x4f\x04\x7f\x03\x7f\x03\x1d\x04\x35\x07\x2b\x07\x16\x07\x0c\x07\xfb\x0d\x25\x07\x00\x00\xfb\x06\x00\x00\x61\x0d\x00\x00\x00\x00\x00\x00\xb7\x06\x57\x1a\x33\x1a\x48\x11\x00\x0f\x00\x00\x00\x00\x0f\x07\x0e\x07\x00\x00\xf3\x06\xdd\x06\xdb\x06\xc7\x06\xd3\x09\xdf\x07\xad\x06\x94\x06\x7c\x06\xd3\x09\xfb\x0d\x00\x00\xcb\x06\x6c\x19\xab\x06\xa7\x06\x00\x00\xc4\x06\x00\x00\xc3\x06\xc1\x06\xea\x00\xd8\x00\x38\x18\xa1\x06\x5d\x06\xaa\x06\x00\x00\x6f\x09\x38\x18\x86\x06\x00\x00\x00\x00\x1e\x19\x5b\x0b\x00\x00\x00\x00\xb1\x01\x93\x01\x8e\x06\x88\x06\x0f\x00\x47\x00\x93\x01\x00\x00\x38\x18\x66\x06\x00\x00\x49\x06\x00\x00\x6f\x09\x3e\x06\x00\x00\x00\x00\x00\x00\x00\x00\xed\x01\x00\x00\x62\x06\x00\x00\x38\x18\x3d\x06\x00\x00\x9b\x0a\x00\x00\x29\x06\xe0\x0b\x09\x00\xce\x05\x74\x02\xff\x0f\x74\x02\x21\x08\x21\x08\xd0\x0f\x24\x06\xfb\x05\x00\x00\x1b\x01\x45\x19\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x00\x19\x11\xd8\x00\xea\x10\x5a\x12\x6f\x09\x38\x18\x04\x06\x00\x00\x19\x06\x9e\x09\x12\x00\x12\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x0f\x00\x00\x00\x00\x00\xdc\x0c\x09\x06\xf4\x05\xcc\x03\x03\x06\xfe\x05\x77\x00\xca\x00\x00\x00\x00\x00\xef\x05\x00\x00\x00\x00\xcd\x02\x00\x00\xcb\x05\xcc\x03\xaa\x05\x00\x00\x00\x00\x00\x00\xdc\x0c\x4b\x09\x00\x00\x0f\x00\x00\x00\xfd\x0c\x00\x00\xc8\x05\xc1\x05\x8c\x05\x8c\x05\xbb\x10\x00\x00\xf1\x00\xc9\x00\x8c\x05\x00\x00\x56\x05\x66\x18\x00\x00\x53\x05\x00\x00\xf0\x18\xc2\x18\xa1\x0f\xde\x12\x53\x05\x53\x05\x00\x00\x72\x0f\x49\x07\x53\x05\x00\x00\x53\x05\x53\x05\x00\x00\xab\x04\x62\x0c\x9d\x05\x9b\x05\x09\x00\x00\x00\x90\x05\x46\x05\x37\x0a\x09\x00\x00\x00\x00\x00\x6f\x09\x38\x18\x6d\x05\x00\x00\x8f\x05\x8d\x05\xdc\x17\x00\x00\x00\x00\x00\x00\x2f\x09\x84\x05\x0e\x00\xbe\x00\x83\x05\x0f\x00\x0f\x00\x2c\x09\x00\x00\x00\x00\x00\x00\xe3\x0a\x65\x00\x00\x00\x00\x00\x81\x05\x79\x05\x10\x05\x00\x00\x00\x00\x00\x00\x35\x05\x35\x05\xd3\x09\xd3\x09\xd3\x09\x00\x00\xfb\x0d\xfb\x0d\xfb\x0d\x42\x05\x00\x00\xaa\x01\xc9\x03\xdf\x07\xf2\x04\x00\x00\x23\x05\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x00\x8c\x10\xd8\x00\x5d\x10\x2d\x05\xa7\x08\x00\x00\x7b\x1a\x9a\x03\x7b\x1a\x1c\x05\x1c\x05\x1c\x05\x30\x0c\x00\x00\xa2\x09\x31\x05\x2f\x05\x2d\x00\x33\x12\x00\x00\x00\x00\xfe\x0b\xfb\x0d\x00\x00\xfb\x0d\x00\x00\xfb\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb3\x02\xfd\x0c\xdc\x02\x00\x00\x99\x01\x00\x00\xd4\x04\xfb\x0d\x9a\x03\xfe\x0b\x21\x05\x0d\x05\x13\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x04\x09\x05\xed\x02\x00\x00\xf9\x04\x00\x00\xc0\x04\x2e\x10\xc0\x04\xc0\x04\xc0\x04\x00\x00\xa3\x03\x89\x04\x00\x00\xa2\x04\x2a\x00\xd3\x09\xc7\x04\x9c\x04\x97\x04\x7f\x04\x00\x00\x00\x00\x88\x04\x88\x04\xa1\x04\x00\x00\x00\x00\x22\x09\x00\x00\x00\x00\x2b\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x0a\x0f\x00\x00\x00\xaf\x17\xd4\x02\x00\x00\xa0\x03\x98\x03\x0f\x1a\xc2\x12\x00\x00\x00\x00\xbe\x19\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x04\x9a\x04\x8b\x04\x86\x04\x09\x00\x0a\x04\x00\x00\x7a\x04\x00\x00\x00\x00\x68\x04\xfb\x0d\x00\x00\x00\x00\x00\x00\xb4\x04\x9f\x00\x04\x12\x00\x00\x00\x00\xdc\x0a\x3e\x09\x24\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x01\x2b\x00\x2b\x00\x16\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x47\x02\xfb\x0d\xf4\x00\x00\x00\xe4\x0c\x64\x04\x77\x00\x00\x00\x00\x00\x00\x00\xa8\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\x00\x00\x00\x2b\x00\x5f\x01\xcd\x00\x3e\x04\x00\x00\x00\x00\xfb\x0d\x3c\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd\x03\x1b\x04\xfb\x0d\x9e\x00\xeb\x19\xc8\x03\x00\x00\xc8\x03\x00\x00\xc8\x03\x06\x04\xfb\x0d\x00\x00\x00\x00\xcd\x00\x1f\x09\x00\x00\x00\x00\x00\x00\x00\x00\xd3\x09\xfb\x0d\xfb\x0d\xf5\x03\x00\x00\x0a\x01\xef\x03\x00\x00\x1a\x04\x49\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\x03\x00\x00\x00\x00\x00\x00\xfb\x0d\x40\x03\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x97\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x0b\x00\x00\x00\x00\x80\x0c\x00\x00\x00\x00\xfb\x0d\x63\x0b\x00\x00\x00\x00\x00\x00\x03\x04\x00\x00\x01\x04\xe1\x03\xfb\x0d\x2a\x00\xb6\x03\x2a\x00\x00\x00\xd8\x03\xd3\x03\x00\x00\x00\x00\x00\x00\xfb\x0d\x00\x00\x9e\x00\xd4\x02\x6a\x03\x00\x00\xfb\x0d\x00\x00\x00\x00\xb9\x03\x00\x00\x00\x00\x00\x00\xfb\x0d\x00\x00\x00\x00\x00\x00\x4a\x03\x4a\x03\x00\x00\xd3\x09\xd3\x09\xd5\x00\x00\x00\x00\x00\xa8\x03\x3b\x03\x3b\x03\x00\x00\x00\x00\x7a\x03\x00\x00\x00\x00\x74\x03\x72\x03\x00\x00\x46\x03\x0b\x03\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x00\x00\xfb\x0d\xfb\x0d\x6c\x03\x5b\x03\x17\x03\xe9\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# happyGotoOffsets :: HappyAddr happyGotoOffsets = HappyA# "\x36\x03\x71\x00\xd3\x06\xc6\x1d\x3c\x03\x38\x00\x00\x00\x00\x00\xc5\x02\x35\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4d\x03\x00\x00\x00\x00\x71\x0d\xa4\x0b\x00\x00\x00\x00\x00\x00\x00\x00\xb8\x02\xd5\x0a\xb9\x0a\x00\x00\x00\x00\x00\x00\xa7\x02\x00\x00\x20\x0c\xbe\x03\x60\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x03\x1a\x00\x00\x00\x76\x1f\x00\x00\x00\x00\xb8\x06\x00\x00\x95\x02\x00\x00\x4c\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x03\x00\x00\x00\x00\x00\x00\x2a\x06\xc3\x00\x00\x00\x8a\x05\x00\x00\x14\x00\x16\x01\x6c\x02\x7d\x01\xa2\x01\xcb\x00\x00\x00\x00\x00\x96\x08\x00\x00\x9a\x00\x00\x00\x00\x00\x00\x00\x99\x08\xe2\x02\x00\x00\x00\x00\xbb\x02\x15\x01\x00\x00\xa8\x0a\xd7\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5c\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\xca\x15\x71\x02\x5d\x02\x6a\x02\x77\x08\x00\x00\x00\x00\x70\x02\x00\x00\x5b\x08\x00\x00\x40\x00\xc6\x02\x00\x00\x00\x00\x00\x00\x52\x02\x9e\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad\x04\x00\x00\x66\x02\x00\x00\xa8\x13\x16\x17\xa9\x02\x00\x00\x00\x00\x00\x00\x00\x00\x51\x02\x90\x02\xec\x00\x00\x00\x00\x00\x1a\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x02\x4f\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x65\x02\x9a\x13\xe8\x16\x35\x08\x75\x02\x00\x00\x00\x00\x00\x00\x4a\x02\x5c\x02\x00\x00\x00\x00\x00\x00\x62\x02\x31\x02\x56\x02\xf3\x07\x00\x00\xee\x07\x00\x00\x00\x00\xab\x1d\x90\x1d\x00\x00\x00\x00\x75\x1d\x00\x00\x5a\x1d\x00\x00\x98\x06\x00\x00\x4e\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeb\x01\xe9\x07\x00\x00\x7b\x16\x53\x16\x5b\x1f\x00\x00\xe7\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1\x02\x00\x00\x5b\x02\x00\x00\x00\x00\x00\x00\x00\x00\x69\x05\x9b\x00\x78\x00\x50\x00\x89\x16\x00\x00\x00\x00\xac\x03\x3f\x1d\xc7\x1f\x24\x1d\xe2\x1f\x08\x15\x84\x15\xfd\x1f\xf1\x0b\x6f\x0b\xf0\x0c\xbb\x0c\x40\x0c\x3a\x0b\x9b\x0c\x1a\x0b\xfc\x07\x26\x07\xc1\x0b\x2c\x0a\x9d\x09\x00\x00\x40\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x1d\xee\x1c\xdb\x01\xcd\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x99\x07\x00\x00\x00\x00\x00\x00\xc6\x01\x61\x04\x00\x00\x73\x13\xda\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x33\x06\x35\x02\x33\x02\xea\x01\x7e\x01\x18\x06\x25\x1f\x00\x00\x00\x00\xa6\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x03\x91\x20\x87\x04\xdd\x01\xce\x07\x00\x00\x00\x00\xa6\x15\x4c\x04\xb7\x01\x00\x00\x00\x00\xda\x13\x26\x03\x00\x00\x00\x00\x6c\x05\x30\x13\x00\x00\x00\x00\xa2\x07\x36\x02\xb6\x0b\x00\x00\x26\x04\xa0\x01\x00\x00\x00\x00\xa7\x01\x4e\x15\xc7\x01\x00\x00\x00\x00\x00\x00\x00\x00\x2e\x02\xb0\x01\x00\x00\x00\x00\xeb\x03\x60\x01\x00\x00\xa9\x16\x00\x00\x00\x00\xc4\x1b\x6a\x07\x14\x01\x40\x20\x18\x14\x28\x20\x9f\x01\x18\x00\x2c\x14\x00\x00\x00\x00\x00\x00\x00\x00\xa6\x03\x00\x00\x00\x00\x00\x00\x00\x00\x84\x20\x47\x07\x77\x20\x68\x14\xaf\x14\x2a\x15\xc5\x03\x4d\x01\x00\x00\x00\x00\x73\x07\xd3\x01\xeb\x04\x27\x07\x00\x00\x20\x07\x00\x00\x15\x07\x00\x00\x00\x00\xbf\x03\x00\x00\x00\x00\xb9\x01\x00\x00\x00\x00\xfd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x01\x00\x00\x00\x00\x00\x00\x00\x00\x44\x04\x15\x07\x00\x00\xd9\x06\x00\x00\xa9\x1b\x00\x00\x00\x00\x00\x00\x16\x02\xf7\x01\xa9\x14\x00\x00\x6f\x13\x0d\x0e\xf4\x01\x00\x00\x00\x00\x0a\x14\x00\x00\x96\x06\x00\x00\x00\x04\x00\x00\x3e\x13\x60\x17\x76\x06\x68\x06\x00\x00\x06\x13\x59\x17\x2b\x06\x00\x00\x10\x06\xe2\x05\x00\x00\xdb\x00\x62\x17\x00\x00\x00\x00\xdf\x05\x00\x00\x00\x00\x00\x00\xe0\x16\xd9\x05\x00\x00\x00\x00\xd2\x14\x64\x03\x42\x01\x00\x00\x00\x00\x00\x00\x31\x16\x5c\x01\x00\x00\x00\x00\xff\x05\x00\x00\xf9\x08\x60\x07\x00\x00\xf1\x05\xe4\x05\xe1\x05\x00\x00\x00\x00\x00\x00\x92\x0c\x18\x04\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x01\x00\x00\x00\x00\x00\x00\x5e\x01\x57\x01\xae\x05\x93\x05\x78\x05\x00\x00\x31\x1c\x16\x1c\xd3\x1c\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x01\x33\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x54\x09\x43\x01\xc4\x07\x3e\x01\x00\x00\x36\x07\x00\x00\x40\x16\xd5\xff\xe1\x14\x00\x00\x00\x00\x00\x00\xc7\x02\x00\x00\x8a\x02\x00\x00\x00\x00\xf9\x00\x96\x14\x00\x00\x00\x00\x13\x1b\x0a\x1f\x00\x00\x91\x1f\x00\x00\xef\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8e\x1b\x9d\x02\x00\x00\x00\x00\x00\x00\x00\x00\xd4\x1e\xd3\x00\xf1\x1a\x00\x00\x00\x00\x7f\x00\x00\x00\xb4\x05\x00\x00\x00\x00\x00\x00\x00\x00\xce\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3c\x01\x67\x01\x36\x01\x1d\x01\x17\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf4\xff\x0e\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\x80\x00\x00\x00\x00\x00\x00\x00\x99\x05\x00\x00\x00\x00\x6b\x0e\x00\x00\x00\x00\x00\x00\x00\x00\xb0\x09\x5c\x05\x00\x00\x31\x16\x6a\x20\x00\x00\x00\x00\x00\x00\x04\x04\xb9\x16\x00\x00\x00\x00\x22\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\x04\xb0\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\x1e\x00\x00\x00\x00\x00\x00\x1a\x17\xfa\x05\x64\x14\x00\x00\x00\x00\x80\x16\x9a\x06\xca\x04\x00\x00\x00\x00\x00\x00\x00\x00\xc3\x02\xaa\x0d\x36\x0d\xfa\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9e\x1e\xd9\xff\x00\x00\x50\x1b\x00\x00\x4d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9\xff\x00\x00\x91\x06\xbf\x03\x5a\x05\x00\x00\x00\x00\x00\x00\x83\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x00\x00\x00\x68\x1e\x57\x04\x61\x04\x78\x04\x00\x00\x09\x04\x00\x00\x86\x03\x00\x00\x4d\x1e\x00\x00\x00\x00\x5a\x05\xab\x03\x00\x00\x00\x00\x00\x00\x00\x00\xf3\x04\xfb\x1b\xe0\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\x00\x00\x00\x00\x00\x00\x00\xb8\x1c\x44\x00\x00\x00\x00\x00\x00\x00\x2c\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x35\x1b\x00\x00\x00\x00\x73\x1b\x00\x00\x00\x00\x32\x1e\x35\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d\x1c\xf5\xff\x00\x00\xf1\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x1e\x00\x00\x5f\x03\x5b\x20\xd0\xff\x00\x00\xfc\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\x1d\x00\x00\x00\x00\x00\x00\xec\x01\xd0\xff\x00\x00\xd6\x04\x9e\x01\x00\x00\x00\x00\x00\x00\x00\x00\x32\x00\xa5\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9\xff\x49\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x1c\x67\x1c\x00\x00\x00\x00\x00\x00\x91\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# happyDefActions :: HappyAddr happyDefActions = HappyA# "\xfa\xff\x3d\xfe\x00\x00\x00\x00\x00\x00\x3d\xfe\x9b\xfe\x8f\xfe\x7d\xfe\x00\x00\x7b\xfe\x77\xfe\x74\xfe\x71\xfe\x6c\xfe\x69\xfe\x67\xfe\x65\xfe\x63\xfe\x61\xfe\x5f\xfe\x5c\xfe\x4f\xfe\x00\x00\xa5\xfe\xa4\xfe\x3d\xfe\x7e\xfe\x7f\xfe\x00\x00\x00\x00\x81\xfe\x80\xfe\x82\xfe\x83\xfe\x00\x00\x00\x00\x00\x00\x45\xfe\x46\xfe\x44\xfe\x43\xfe\xa6\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\xff\xe3\xff\xe2\xff\xe1\xff\xe0\xff\xdf\xff\xde\xff\x00\x00\x00\x00\xc7\xff\xd7\xff\xb5\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4b\xfe\x00\x00\x00\x00\xa6\xfe\x3e\xfe\x00\x00\xf7\xff\x00\x00\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00\x98\xff\x00\x00\x77\xff\x9b\xff\x8a\xff\x9a\xff\x89\xff\x99\xff\x88\xff\x6c\xff\x52\xff\x3d\xfe\x51\xff\x00\x00\xe5\xff\x0a\xff\x08\xff\x09\xff\xa6\xff\xfb\xfe\xfa\xfe\x00\x00\x3c\xfe\x3b\xfe\x00\x00\x3d\xfe\x00\x00\x8d\xff\x7e\xff\x86\xff\x7d\xff\x81\xff\x3d\xfe\x8f\xff\x82\xff\x84\xff\x83\xff\x8c\xff\x85\xff\x80\xff\x8e\xff\x4d\xff\x90\xff\x00\x00\x8b\xff\x4c\xff\x7f\xff\x87\xff\xfe\xfe\x60\xff\x00\x00\x3d\xfe\x00\x00\xf5\xff\x00\x00\x3d\xfe\x00\x00\x3c\xfe\x00\x00\x00\x00\x07\xff\xf9\xfe\x3c\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97\xff\x76\xff\x6b\xff\x26\xff\xa6\xff\x3a\xfe\x00\x00\x5a\xff\x2b\xff\x2f\xff\x2c\xff\x2d\xff\x2e\xff\x3d\xfe\x03\xff\xd7\xfe\xd5\xfe\xf4\xfe\x49\xfe\x00\x00\x96\xff\x75\xff\x6a\xff\x2a\xff\x26\xff\xa6\xff\x00\x00\x00\x00\x5d\xff\x00\x00\x66\xff\x54\xff\x53\xff\x62\xff\x92\xff\x91\xff\x61\xff\x6f\xff\x68\xff\x67\xff\xa9\xff\x6e\xff\x6d\xff\xaa\xff\x7b\xff\x72\xff\x73\xff\x71\xff\x7a\xff\x79\xff\x78\xff\x00\x00\x26\xff\x27\xff\x23\xff\x20\xff\x1f\xff\x24\xff\x16\xff\x28\xff\xa6\xff\x00\x00\x3d\xfe\x22\xff\x00\x00\x94\xff\x7c\xff\x70\xff\x26\xff\xa6\xff\x93\xff\x00\x00\x65\xff\x00\x00\x26\xff\xa6\xff\x3d\xfe\xa8\xff\x3d\xfe\xa7\xff\xf3\xff\x00\x00\x00\x00\x4a\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x3f\xfe\x4b\xfe\x00\x00\x00\x00\xbc\xff\x7d\xfe\x47\xfe\x00\x00\xbb\xff\x00\x00\xb4\xff\xd5\xff\x3d\xfe\xc6\xff\x3d\xfe\x3d\xfe\x00\x00\x85\xfe\x3d\xfe\x86\xfe\x8c\xfe\x42\xfe\x41\xfe\x8a\xfe\x3d\xfe\x88\xfe\x3d\xfe\x84\xfe\x8d\xfe\x8e\xfe\x00\x00\xde\xfe\x8a\xff\x89\xff\x88\xff\x00\x00\x00\x00\x00\x00\x3c\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\xfe\x00\x00\x5a\xfe\x56\xfe\x55\xfe\x59\xfe\x58\xfe\x57\xfe\x52\xfe\x51\xfe\x50\xfe\x54\xfe\x53\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x95\xfe\x94\xfe\xf8\xff\xf9\xff\x97\xfe\x96\xfe\x00\x00\x00\x00\x91\xfe\x99\xfe\x5b\xfe\x78\xfe\x79\xfe\x7a\xfe\x75\xfe\x76\xfe\x72\xfe\x73\xfe\x6d\xfe\x6f\xfe\x6e\xfe\x70\xfe\x6a\xfe\x6b\xfe\x68\xfe\x66\xfe\x64\xfe\x62\xfe\x00\x00\x00\x00\x60\xfe\x4d\xfe\x4e\xfe\xa3\xfe\x00\x00\xdb\xfe\xd8\xfe\xda\xfe\xd9\xfe\x00\x00\xdc\xfe\xf4\xfe\xc8\xfe\xdd\xfe\xa2\xfe\x00\x00\x00\x00\x40\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd6\xff\xd5\xff\x00\x00\x00\x00\x00\x00\x00\x00\xdb\xff\x00\x00\x3d\xfe\x00\x00\x00\x00\xbe\xff\x00\x00\xba\xff\x00\x00\x00\x00\x00\x00\x00\x00\x3d\xfe\xb6\xfe\x3d\xfe\x00\x00\xf1\xff\x3d\xfe\x3d\xfe\xb6\xfe\xef\xff\x21\xff\xf4\xfe\x00\x00\x1e\xff\x12\xff\x3c\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\xff\x3d\xfe\xb6\xfe\xf0\xff\x4e\xff\x4b\xff\x3d\xfe\x00\x00\x95\xff\x74\xff\x69\xff\x29\xff\x26\xff\xa6\xff\x00\x00\x57\xff\x3d\xfe\xb6\xfe\xee\xff\x49\xfe\x48\xfe\x00\x00\x49\xfe\x82\xfe\x3d\xfe\xef\xfe\xeb\xfe\xe8\xfe\x9a\xff\x89\xff\xe4\xfe\x00\x00\xf3\xfe\xf1\xfe\x00\x00\x3c\xfe\xe0\xfe\xd4\xfe\xec\xff\xa5\xff\x00\x00\x00\x00\x00\x00\x00\x00\x3c\xfe\x3d\xfe\x3d\xfe\xb6\xfe\xf2\xff\x00\x00\x00\x00\x00\x00\x3d\xfe\xf6\xfe\xfd\xfe\x02\xff\x06\xff\x09\xff\x05\xff\xf8\xfe\x00\x00\x00\x00\x34\xff\x00\x00\x00\x00\x00\x00\x36\xfe\x00\x00\x38\xfe\x34\xfe\x35\xfe\x5f\xff\x5e\xff\x00\x00\x33\xff\x31\xff\x00\x00\x00\x00\x04\xff\x01\xff\xf5\xfe\x00\x00\x00\x00\xfc\xfe\x00\xff\xa1\xff\x00\x00\xeb\xff\x00\x00\x00\x00\x26\xff\x26\xff\x00\x00\x28\xff\x00\x00\x3d\xfe\x26\xff\xf7\xfe\x00\x00\x3d\xfe\xd6\xfe\x3d\xfe\xe2\xfe\x00\x00\xe3\xfe\xf4\xfe\xc8\xfe\x3d\xfe\x3d\xfe\xe7\xfe\xf4\xfe\xc8\xfe\x3d\xfe\xea\xfe\x3d\xfe\x3d\xfe\xee\xfe\x3d\xfe\x00\x00\x00\x00\x00\x00\x82\xfe\xd3\xfe\x00\x00\x00\x00\x49\xfe\x82\xfe\xa3\xff\xe7\xff\x3d\xfe\x3d\xfe\xb6\xfe\xed\xff\x00\x00\x00\x00\x3d\xfe\x4b\xff\x9d\xff\xe9\xff\x00\x00\x00\x00\x00\x00\x3d\xfe\x00\x00\x0f\xff\x1a\xff\x00\x00\x1d\xff\x1c\xff\x11\xff\x00\x00\x00\x00\xa4\xff\xe8\xff\x00\x00\x00\x00\x00\x00\x9f\xff\x9e\xff\xea\xff\x26\xff\x26\xff\x00\x00\x00\x00\x00\x00\xbd\xff\x4b\xfe\x4b\xfe\x00\x00\x00\x00\xdc\xff\x00\x00\x00\x00\xd6\xff\x00\x00\xd3\xff\x00\x00\xd4\xff\xd2\xff\xd0\xff\xd1\xff\x00\x00\x00\x00\x00\x00\x00\x00\x60\xff\x3d\xfe\xdd\xff\x3d\xfe\x00\x00\x3d\xfe\x00\x00\x89\xfe\x87\xfe\x3d\xfe\xc6\xfe\xc4\xfe\x00\x00\x00\x00\x00\x00\x3c\xfe\xba\xfe\x7c\xfe\xb4\xfe\x00\x00\x5d\xfe\x00\x00\x98\xfe\x00\x00\x9a\xfe\x90\xfe\x5e\xfe\x4c\xfe\xb3\xfe\x00\x00\x00\x00\x00\x00\xac\xfe\xad\xfe\xb9\xfe\x00\x00\x00\x00\x00\x00\xb4\xfe\x00\x00\x00\x00\x00\x00\xc1\xfe\xc2\xfe\xc0\xfe\xc3\xfe\xc5\xfe\xc7\xfe\x3c\xfe\x00\x00\x00\x00\x9e\xfe\x00\x00\xcf\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9\xff\x00\x00\x00\x00\xc9\xff\x00\x00\xb3\xff\x00\x00\x00\x00\x00\x00\x00\x00\xc5\xff\xc3\xff\xc2\xff\xb6\xfe\xb6\xfe\x00\x00\x64\xff\x63\xff\x00\x00\x1b\xff\x10\xff\x00\x00\x15\xff\x19\xff\x0d\xff\x0e\xff\x00\x00\x18\xff\x0b\xff\x3d\xfe\x40\xff\x49\xff\x00\x00\x00\x00\x3d\xfe\x3c\xfe\x4a\xff\x4f\xff\x3d\xfe\x5c\xff\x5b\xff\xa2\xff\xe6\xff\x00\x00\x00\x00\x00\x00\x00\x00\x82\xfe\x3d\xfe\xd1\xfe\x00\x00\xd2\xfe\xcc\xfe\x00\x00\x00\x00\xed\xfe\xec\xfe\xe9\xfe\x3d\xfe\xc4\xfe\x3c\xfe\xe6\xfe\xe5\xfe\x3d\xfe\xc4\xfe\x3c\xfe\xe1\xfe\xf0\xfe\xf2\xfe\xdf\xfe\x00\x00\x00\x00\x00\x00\x26\xff\x59\xff\x58\xff\xb5\xfe\xff\xfe\xf4\xff\x00\x00\x00\x00\x00\x00\x38\xff\x00\x00\x00\x00\x36\xfe\x37\xfe\x39\xfe\x31\xfe\x00\x00\x32\xfe\x32\xff\x37\xff\x30\xff\x00\x00\x36\xff\x00\x00\x3c\xfe\x3c\xfe\x00\x00\xcf\xfe\xcb\xfe\x00\x00\x00\x00\xd0\xfe\xca\xfe\x56\xff\x55\xff\x46\xff\x44\xff\x3c\xff\x00\x00\x00\x00\x3c\xfe\x3d\xfe\x48\xff\x3d\xfe\x47\xff\x3d\xfe\x3f\xff\x00\x00\x50\xff\x17\xff\x00\x00\x00\x00\x14\xff\x25\xff\x9c\xff\xa0\xff\x00\x00\x4b\xfe\x4b\xfe\x00\x00\xda\xff\x00\x00\xb2\xff\xb1\xff\x00\x00\x00\x00\xb9\xff\xd8\xff\xc8\xff\xce\xff\xcc\xff\xcd\xff\x00\x00\xcb\xff\x9f\xfe\xa0\xfe\x00\x00\x00\x00\xa1\xfe\xbf\xfe\xbd\xfe\xbe\xfe\xbc\xfe\x00\x00\xa9\xfe\x00\x00\xae\xfe\xab\xfe\xa8\xfe\xaf\xfe\xb2\xfe\x00\x00\x93\xfe\xb1\xfe\x00\x00\x92\xfe\xaa\xfe\x00\x00\x00\x00\xb8\xfe\xbb\xfe\x9d\xfe\x00\x00\xca\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb3\xff\xc1\xff\x00\x00\x00\x00\xc4\xff\x13\xff\x3e\xff\x00\x00\x42\xff\x00\x00\x00\x00\x45\xff\x3b\xff\x00\x00\x39\xff\xc9\xfe\x00\x00\xce\xfe\x35\xff\x33\xfe\x00\x00\x30\xfe\xcd\xfe\x3a\xff\x3d\xfe\x43\xff\x3d\xff\x00\x00\x00\x00\x00\x00\xb8\xff\xb0\xff\x00\x00\x00\x00\x00\x00\x9c\xfe\xb7\xfe\x00\x00\xb0\xfe\xa7\xfe\x00\x00\x00\x00\xaf\xff\x00\x00\x00\x00\xd6\xff\xc0\xff\x41\xff\xbf\xff\x00\x00\xac\xff\xb7\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\xff\xb6\xff\xad\xff\xae\xff"# happyCheck :: HappyAddr happyCheck = HappyA# "\xff\xff\x02\x00\x03\x00\x04\x00\x36\x00\x74\x00\x15\x00\x16\x00\x17\x00\x15\x00\x16\x00\x17\x00\x17\x00\x04\x00\x35\x00\x01\x00\x01\x00\x18\x00\x03\x00\x01\x00\x04\x00\x02\x00\x1c\x00\x02\x00\x19\x00\x74\x00\x1b\x00\x0d\x00\x1d\x00\x1e\x00\x1f\x00\x0d\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x01\x00\x03\x00\x14\x00\x02\x00\x5b\x00\x0d\x00\x33\x00\x39\x00\x20\x00\x21\x00\x37\x00\x23\x00\x0d\x00\x21\x00\x02\x00\x03\x00\x04\x00\x1e\x00\x2e\x00\x2a\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x79\x00\x01\x00\x79\x00\x36\x00\x76\x00\x01\x00\x2e\x00\x36\x00\x76\x00\x36\x00\x19\x00\x09\x00\x1b\x00\x0d\x00\x1d\x00\x1e\x00\x1f\x00\x0d\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x74\x00\x01\x00\x5e\x00\x74\x00\x74\x00\x5c\x00\x33\x00\x5e\x00\x74\x00\x5c\x00\x37\x00\x5e\x00\x5e\x00\x0d\x00\x02\x00\x03\x00\x04\x00\x77\x00\x78\x00\x79\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x5c\x00\x5d\x00\x42\x00\x43\x00\x44\x00\x5b\x00\x36\x00\x5c\x00\x5d\x00\x5e\x00\x19\x00\x5e\x00\x1b\x00\x79\x00\x1d\x00\x1e\x00\x1f\x00\x79\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x04\x00\x01\x00\x01\x00\x79\x00\x03\x00\x5c\x00\x33\x00\x5e\x00\x74\x00\x5c\x00\x37\x00\x5e\x00\x02\x00\x0d\x00\x0d\x00\x36\x00\x36\x00\x77\x00\x78\x00\x79\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x79\x00\x76\x00\x21\x00\x1e\x00\x23\x00\x23\x00\x01\x00\x07\x00\x5c\x00\x5d\x00\x5e\x00\x2a\x00\x2b\x00\x2c\x00\x04\x00\x7b\x00\x79\x00\x01\x00\x0d\x00\x02\x00\x33\x00\x01\x00\x2c\x00\x36\x00\x36\x00\x2a\x00\x5c\x00\x54\x00\x36\x00\x0d\x00\x02\x00\x54\x00\x01\x00\x0d\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x43\x00\x20\x00\x21\x00\x0d\x00\x23\x00\x48\x00\x77\x00\x78\x00\x79\x00\x01\x00\x21\x00\x2a\x00\x2b\x00\x2c\x00\x04\x00\x79\x00\x01\x00\x1e\x00\x2a\x00\x56\x00\x33\x00\x0d\x00\x79\x00\x36\x00\x5c\x00\x5c\x00\x5d\x00\x5e\x00\x0d\x00\x5c\x00\x5d\x00\x36\x00\x01\x00\x36\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x2d\x00\x02\x00\x21\x00\x0d\x00\x23\x00\x43\x00\x36\x00\x78\x00\x79\x00\x79\x00\x48\x00\x2a\x00\x2b\x00\x2c\x00\x04\x00\x5c\x00\x5d\x00\x5e\x00\x02\x00\x07\x00\x33\x00\x01\x00\x2d\x00\x36\x00\x56\x00\x07\x00\x5c\x00\x5d\x00\x5e\x00\x1e\x00\x5c\x00\x5d\x00\x5e\x00\x0d\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x5c\x00\x5d\x00\x21\x00\x21\x00\x23\x00\x23\x00\x5c\x00\x5d\x00\x79\x00\x07\x00\x01\x00\x2a\x00\x2b\x00\x2c\x00\x04\x00\x07\x00\x79\x00\x2a\x00\x5c\x00\x04\x00\x33\x00\x76\x00\x0d\x00\x37\x00\x36\x00\x5c\x00\x5d\x00\x5e\x00\x5c\x00\x5d\x00\x77\x00\x78\x00\x79\x00\x36\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x5c\x00\x5d\x00\x21\x00\x01\x00\x23\x00\x43\x00\x20\x00\x21\x00\x79\x00\x23\x00\x48\x00\x2a\x00\x2b\x00\x2c\x00\x04\x00\x0d\x00\x2a\x00\x2b\x00\x2c\x00\x02\x00\x33\x00\x79\x00\x1c\x00\x36\x00\x56\x00\x33\x00\x7a\x00\x7b\x00\x36\x00\x1c\x00\x5c\x00\x5d\x00\x5e\x00\x4b\x00\x41\x00\x42\x00\x43\x00\x44\x00\x74\x00\x41\x00\x42\x00\x43\x00\x44\x00\x21\x00\x2d\x00\x23\x00\x77\x00\x78\x00\x79\x00\x79\x00\x79\x00\x39\x00\x2a\x00\x2b\x00\x2c\x00\x01\x00\x36\x00\x54\x00\x39\x00\x2a\x00\x5c\x00\x33\x00\x5e\x00\x03\x00\x36\x00\x21\x00\x06\x00\x0d\x00\x54\x00\x43\x00\x05\x00\x06\x00\x07\x00\x2c\x00\x48\x00\x41\x00\x42\x00\x43\x00\x44\x00\x02\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x01\x00\x36\x00\x54\x00\x56\x00\x78\x00\x79\x00\x1f\x00\x34\x00\x35\x00\x5c\x00\x79\x00\x5e\x00\x0d\x00\x20\x00\x21\x00\x2a\x00\x20\x00\x21\x00\x2d\x00\x05\x00\x06\x00\x07\x00\x1e\x00\x09\x00\x1a\x00\x0b\x00\x0c\x00\x0d\x00\x07\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x2d\x00\x36\x00\x5c\x00\x5d\x00\x36\x00\x19\x00\x01\x00\x1b\x00\x03\x00\x1d\x00\x1e\x00\x1f\x00\x79\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x34\x00\x35\x00\x5c\x00\x5d\x00\x5e\x00\x74\x00\x33\x00\x54\x00\x0a\x00\x79\x00\x37\x00\x5a\x00\x0e\x00\x5c\x00\x76\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x54\x00\x6e\x00\x5c\x00\x5d\x00\x5e\x00\x1c\x00\x73\x00\x74\x00\x1c\x00\x76\x00\x42\x00\x43\x00\x44\x00\x79\x00\x2c\x00\x5a\x00\x79\x00\x5c\x00\x30\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x39\x00\x6e\x00\x76\x00\x39\x00\x54\x00\x1c\x00\x73\x00\x74\x00\x4b\x00\x76\x00\x77\x00\x78\x00\x79\x00\x05\x00\x06\x00\x07\x00\x0a\x00\x09\x00\x79\x00\x0b\x00\x0c\x00\x0d\x00\x76\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x01\x00\x1c\x00\x78\x00\x79\x00\x1c\x00\x19\x00\x39\x00\x1b\x00\x76\x00\x1d\x00\x1e\x00\x1f\x00\x0d\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x07\x00\x77\x00\x78\x00\x79\x00\x1c\x00\x39\x00\x33\x00\x07\x00\x39\x00\x1c\x00\x37\x00\x1c\x00\x1c\x00\x01\x00\x1a\x00\x2a\x00\x3c\x00\x3d\x00\x2d\x00\x01\x00\x1a\x00\x03\x00\x42\x00\x43\x00\x44\x00\x0d\x00\x07\x00\x22\x00\x23\x00\x1a\x00\x25\x00\x0d\x00\x27\x00\x39\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x39\x00\x07\x00\x39\x00\x39\x00\x20\x00\x21\x00\x33\x00\x5a\x00\x76\x00\x5c\x00\x37\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x36\x00\x6e\x00\x5c\x00\x5d\x00\x5e\x00\x4c\x00\x73\x00\x74\x00\x1a\x00\x76\x00\x77\x00\x78\x00\x79\x00\x79\x00\x07\x00\x41\x00\x42\x00\x43\x00\x44\x00\x5a\x00\x50\x00\x5c\x00\x1a\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x07\x00\x6e\x00\x5c\x00\x5d\x00\x5e\x00\x07\x00\x73\x00\x74\x00\x5c\x00\x5d\x00\x77\x00\x78\x00\x79\x00\x01\x00\x79\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x2a\x00\x74\x00\x03\x00\x2d\x00\x0d\x00\x06\x00\x22\x00\x23\x00\x79\x00\x25\x00\x76\x00\x27\x00\x79\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x07\x00\x02\x00\x03\x00\x36\x00\x1e\x00\x06\x00\x33\x00\x58\x00\x59\x00\x2a\x00\x37\x00\x36\x00\x2d\x00\x1f\x00\x1a\x00\x36\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x79\x00\x41\x00\x42\x00\x43\x00\x44\x00\x07\x00\x22\x00\x23\x00\x76\x00\x25\x00\x4c\x00\x27\x00\x08\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x33\x00\x5a\x00\x75\x00\x5c\x00\x37\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x76\x00\x6e\x00\x5c\x00\x5d\x00\x6d\x00\x4c\x00\x73\x00\x74\x00\x00\x00\x01\x00\x77\x00\x78\x00\x79\x00\x78\x00\x79\x00\x01\x00\x77\x00\x78\x00\x79\x00\x5a\x00\x2b\x00\x5c\x00\x5b\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x07\x00\x6e\x00\x41\x00\x42\x00\x43\x00\x44\x00\x73\x00\x74\x00\x36\x00\x02\x00\x77\x00\x78\x00\x79\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x5b\x00\x41\x00\x42\x00\x43\x00\x44\x00\x07\x00\x46\x00\x47\x00\x02\x00\x22\x00\x23\x00\x2b\x00\x25\x00\x01\x00\x27\x00\x01\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x4e\x00\x4f\x00\x50\x00\x19\x00\x04\x00\x1b\x00\x33\x00\x1d\x00\x1e\x00\x1f\x00\x37\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x32\x00\x13\x00\x14\x00\x15\x00\x16\x00\x5b\x00\x33\x00\x01\x00\x4c\x00\x03\x00\x37\x00\x5c\x00\x5d\x00\x78\x00\x79\x00\x41\x00\x42\x00\x43\x00\x44\x00\x0d\x00\x5c\x00\x5d\x00\x5a\x00\x5e\x00\x5c\x00\x02\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x5a\x00\x6e\x00\x5c\x00\x04\x00\x5e\x00\x5f\x00\x73\x00\x74\x00\x2a\x00\x2b\x00\x77\x00\x78\x00\x79\x00\x21\x00\x5e\x00\x23\x00\x2a\x00\x2b\x00\x07\x00\x2a\x00\x2b\x00\x23\x00\x2a\x00\x2b\x00\x2c\x00\x73\x00\x74\x00\x02\x00\x2a\x00\x2b\x00\x2c\x00\x33\x00\x02\x00\x77\x00\x78\x00\x79\x00\x19\x00\x33\x00\x1b\x00\x2b\x00\x1d\x00\x1e\x00\x1f\x00\x04\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x07\x00\x2a\x00\x2b\x00\x36\x00\x5c\x00\x5d\x00\x33\x00\x4e\x00\x4f\x00\x50\x00\x37\x00\x77\x00\x78\x00\x79\x00\x41\x00\x42\x00\x43\x00\x44\x00\x19\x00\x04\x00\x1b\x00\x04\x00\x1d\x00\x1e\x00\x1f\x00\x2c\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x5a\x00\x2a\x00\x5c\x00\x01\x00\x5e\x00\x5f\x00\x33\x00\x79\x00\x2b\x00\x21\x00\x37\x00\x23\x00\x1e\x00\x79\x00\x5e\x00\x23\x00\x5c\x00\x5d\x00\x2a\x00\x2b\x00\x2c\x00\x07\x00\x2a\x00\x2b\x00\x2c\x00\x73\x00\x74\x00\x33\x00\x17\x00\x18\x00\x36\x00\x33\x00\x79\x00\x1e\x00\x36\x00\x5e\x00\x77\x00\x78\x00\x79\x00\x19\x00\x04\x00\x1b\x00\x04\x00\x1d\x00\x1e\x00\x1f\x00\x30\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x07\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x33\x00\x42\x00\x43\x00\x44\x00\x37\x00\x46\x00\x47\x00\x11\x00\x12\x00\x77\x00\x78\x00\x79\x00\x19\x00\x02\x00\x1b\x00\x5e\x00\x1d\x00\x1e\x00\x1f\x00\x04\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x79\x00\x36\x00\x77\x00\x78\x00\x79\x00\x04\x00\x33\x00\x77\x00\x78\x00\x79\x00\x37\x00\x23\x00\x41\x00\x42\x00\x43\x00\x44\x00\x32\x00\x04\x00\x2a\x00\x2b\x00\x2c\x00\x07\x00\x04\x00\x78\x00\x79\x00\x5c\x00\x5d\x00\x33\x00\x0b\x00\x0c\x00\x36\x00\x41\x00\x42\x00\x43\x00\x44\x00\x02\x00\x77\x00\x78\x00\x79\x00\x19\x00\x02\x00\x1b\x00\x02\x00\x1d\x00\x1e\x00\x1f\x00\x1f\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x07\x00\x01\x00\x2d\x00\x03\x00\x2a\x00\x2b\x00\x33\x00\x3c\x00\x78\x00\x79\x00\x37\x00\x2a\x00\x2b\x00\x0d\x00\x2b\x00\x77\x00\x78\x00\x79\x00\x19\x00\x2b\x00\x1b\x00\x02\x00\x1d\x00\x1e\x00\x1f\x00\x2b\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x79\x00\x05\x00\x06\x00\x07\x00\x5c\x00\x5d\x00\x33\x00\x36\x00\x1c\x00\x1d\x00\x37\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x36\x00\x21\x00\x2c\x00\x23\x00\x43\x00\x77\x00\x78\x00\x79\x00\x1e\x00\x48\x00\x2a\x00\x2b\x00\x2c\x00\x43\x00\x05\x00\x06\x00\x07\x00\x02\x00\x48\x00\x33\x00\x77\x00\x78\x00\x79\x00\x56\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x17\x00\x18\x00\x5e\x00\x56\x00\x02\x00\x42\x00\x43\x00\x44\x00\x02\x00\x5c\x00\x5d\x00\x5e\x00\x05\x00\x06\x00\x07\x00\x11\x00\x12\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x37\x00\x02\x00\x77\x00\x78\x00\x79\x00\x77\x00\x78\x00\x79\x00\x0b\x00\x0c\x00\x41\x00\x42\x00\x43\x00\x44\x00\x5a\x00\x02\x00\x5c\x00\x02\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x79\x00\x6e\x00\x77\x00\x78\x00\x79\x00\x2c\x00\x73\x00\x74\x00\x1e\x00\x76\x00\x5a\x00\x5c\x00\x5c\x00\x2d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x1e\x00\x6e\x00\x77\x00\x78\x00\x79\x00\x30\x00\x73\x00\x74\x00\x5a\x00\x76\x00\x5c\x00\x5b\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x02\x00\x6e\x00\x05\x00\x06\x00\x07\x00\x36\x00\x73\x00\x74\x00\x02\x00\x76\x00\x02\x00\x02\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x1f\x00\x43\x00\x04\x00\x02\x00\x36\x00\x02\x00\x48\x00\x4d\x00\x04\x00\x3b\x00\x3c\x00\x3d\x00\x05\x00\x06\x00\x07\x00\x41\x00\x42\x00\x43\x00\x44\x00\x04\x00\x56\x00\x04\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x3b\x00\x3c\x00\x3d\x00\x4e\x00\x4f\x00\x50\x00\x41\x00\x42\x00\x43\x00\x44\x00\x5e\x00\x5c\x00\x05\x00\x06\x00\x07\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x30\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x38\x00\x02\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x02\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x5a\x00\x79\x00\x5c\x00\x2b\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x79\x00\x6e\x00\x4e\x00\x4f\x00\x50\x00\x1f\x00\x73\x00\x74\x00\x5a\x00\x76\x00\x5c\x00\x01\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x02\x00\x6e\x00\x4e\x00\x4f\x00\x50\x00\x02\x00\x73\x00\x74\x00\x5a\x00\x76\x00\x5c\x00\x02\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x02\x00\x6e\x00\x05\x00\x06\x00\x07\x00\x2c\x00\x73\x00\x74\x00\x1f\x00\x76\x00\x2a\x00\x02\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x5e\x00\x04\x00\x04\x00\x4e\x00\x4f\x00\x50\x00\x4e\x00\x4f\x00\x50\x00\x3b\x00\x3c\x00\x3d\x00\x05\x00\x06\x00\x07\x00\x41\x00\x42\x00\x43\x00\x44\x00\x4e\x00\x4f\x00\x50\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x4e\x00\x4f\x00\x50\x00\x77\x00\x78\x00\x79\x00\x05\x00\x06\x00\x07\x00\x77\x00\x78\x00\x79\x00\x77\x00\x78\x00\x79\x00\x1f\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x38\x00\x01\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x2c\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x5a\x00\x79\x00\x5c\x00\x2c\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x1f\x00\x6e\x00\x77\x00\x78\x00\x79\x00\x02\x00\x73\x00\x74\x00\x5a\x00\x76\x00\x5c\x00\x02\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x08\x00\x6e\x00\x77\x00\x78\x00\x79\x00\x1f\x00\x73\x00\x74\x00\x5a\x00\x76\x00\x5c\x00\x01\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x5e\x00\x6e\x00\x05\x00\x06\x00\x07\x00\x1f\x00\x73\x00\x74\x00\x02\x00\x76\x00\x02\x00\x02\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x01\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x2b\x00\x42\x00\x43\x00\x44\x00\x2b\x00\x5b\x00\x05\x00\x06\x00\x07\x00\x41\x00\x42\x00\x43\x00\x44\x00\x77\x00\x78\x00\x79\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x77\x00\x78\x00\x79\x00\x5c\x00\x2a\x00\x5a\x00\x46\x00\x5c\x00\x02\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x2a\x00\x6e\x00\x2a\x00\x70\x00\x78\x00\x79\x00\x73\x00\x74\x00\x77\x00\x78\x00\x79\x00\x02\x00\x02\x00\x5a\x00\x79\x00\x5c\x00\x5e\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x2a\x00\x6e\x00\x4e\x00\x4f\x00\x50\x00\x1e\x00\x73\x00\x74\x00\x5a\x00\x76\x00\x5c\x00\x1a\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x1b\x00\x6e\x00\x0c\x00\x0d\x00\x19\x00\x10\x00\x73\x00\x74\x00\x04\x00\x76\x00\x01\x00\x5b\x00\x03\x00\x02\x00\x02\x00\x19\x00\x02\x00\x1b\x00\x5e\x00\x1d\x00\x1e\x00\x1f\x00\x0d\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x4e\x00\x4f\x00\x50\x00\x01\x00\x20\x00\x21\x00\x33\x00\x23\x00\x57\x00\x2b\x00\x37\x00\x4e\x00\x4f\x00\x50\x00\x2a\x00\x2b\x00\x2c\x00\x46\x00\x4e\x00\x4f\x00\x50\x00\x2b\x00\x5e\x00\x33\x00\x2c\x00\x01\x00\x36\x00\x2c\x00\x36\x00\x5a\x00\x01\x00\x5c\x00\x30\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x41\x00\x42\x00\x43\x00\x44\x00\x43\x00\x0d\x00\x2c\x00\x30\x00\x5a\x00\x48\x00\x5c\x00\x2c\x00\x5e\x00\x5f\x00\x60\x00\x37\x00\x01\x00\x73\x00\x74\x00\x3b\x00\x3c\x00\x3d\x00\x2c\x00\x56\x00\x03\x00\x41\x00\x42\x00\x43\x00\x44\x00\x5c\x00\x5d\x00\x5e\x00\x01\x00\x73\x00\x74\x00\x2b\x00\x02\x00\x77\x00\x78\x00\x79\x00\x30\x00\x31\x00\x2c\x00\x33\x00\x02\x00\x35\x00\x5b\x00\x5e\x00\x38\x00\x01\x00\x65\x00\x3b\x00\x01\x00\x3d\x00\x3e\x00\x3f\x00\x79\x00\x4e\x00\x4f\x00\x50\x00\x44\x00\x45\x00\x01\x00\x47\x00\x04\x00\x5e\x00\x4a\x00\x4b\x00\x01\x00\x4d\x00\x4e\x00\x5e\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x01\x00\x77\x00\x78\x00\x79\x00\x2c\x00\x65\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x01\x00\x77\x00\x78\x00\x79\x00\x1e\x00\x65\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x01\x00\x01\x00\x10\x00\x4e\x00\x4f\x00\x50\x00\x5a\x00\x1e\x00\x5c\x00\x01\x00\x5e\x00\x5f\x00\x60\x00\x1b\x00\x2b\x00\x38\x00\x2b\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x1e\x00\x41\x00\x42\x00\x43\x00\x44\x00\x2b\x00\x2b\x00\x2c\x00\x73\x00\x74\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x65\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x01\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\x77\x00\x78\x00\x79\x00\x01\x00\x01\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x5b\x00\x31\x00\x10\x00\x65\x00\x2a\x00\x5a\x00\x36\x00\x5c\x00\x1b\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x1b\x00\x3e\x00\x77\x00\x78\x00\x79\x00\x1a\x00\x43\x00\x77\x00\x78\x00\x79\x00\x47\x00\x48\x00\x77\x00\x78\x00\x79\x00\x19\x00\x4d\x00\x73\x00\x74\x00\x50\x00\x2f\x00\x52\x00\x31\x00\x10\x00\x33\x00\x56\x00\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x5e\x00\x3d\x00\x3e\x00\x3f\x00\x4e\x00\x4f\x00\x50\x00\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\x4e\x00\x4f\x00\x50\x00\xff\xff\x36\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\x46\x00\x47\x00\x19\x00\xff\xff\x1b\x00\x1b\x00\x1d\x00\x1e\x00\x1f\x00\xff\xff\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x77\x00\x78\x00\x79\x00\x2f\x00\xff\xff\x31\x00\x33\x00\x33\x00\xff\xff\x35\x00\x37\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\x4e\x00\x4f\x00\x50\x00\xff\xff\x44\x00\x45\x00\xff\xff\x47\x00\x78\x00\x79\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\xff\xff\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\x77\x00\x78\x00\x79\x00\xff\xff\x37\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\xff\xff\x77\x00\x78\x00\x79\x00\x01\x00\x02\x00\x03\x00\x01\x00\x02\x00\x03\x00\x1b\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x01\x00\x02\x00\x03\x00\x01\x00\x02\x00\x03\x00\xff\xff\xff\xff\x3c\x00\x3d\x00\x2c\x00\xff\xff\xff\xff\x2f\x00\x42\x00\x43\x00\x44\x00\x33\x00\x01\x00\x35\x00\x03\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\xff\xff\x3f\x00\x0d\x00\x01\x00\x02\x00\x03\x00\x44\x00\x45\x00\x77\x00\x78\x00\x79\x00\xff\xff\x4a\x00\x4b\x00\x4c\x00\x04\x00\x4e\x00\xff\xff\xff\xff\x51\x00\xff\xff\x53\x00\x54\x00\x55\x00\xff\xff\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\x78\x00\x79\x00\xff\xff\x36\x00\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\x01\x00\x43\x00\x03\x00\xff\xff\x05\x00\x06\x00\x48\x00\xff\xff\x09\x00\x0a\x00\x1b\x00\xff\xff\x38\x00\xff\xff\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x56\x00\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\xff\xff\x2f\x00\x01\x00\x02\x00\x03\x00\x33\x00\x01\x00\x35\x00\x03\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\xff\xff\x3f\x00\x0d\x00\x0d\x00\x0e\x00\x0f\x00\x44\x00\x45\x00\x01\x00\x02\x00\x03\x00\xff\xff\x4a\x00\x4b\x00\x4c\x00\xff\xff\x4e\x00\xff\xff\xff\xff\x51\x00\xff\xff\x53\x00\x54\x00\x55\x00\xff\xff\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\x0d\x00\x0e\x00\x0f\x00\x36\x00\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\xff\xff\x43\x00\x36\x00\xff\xff\xff\xff\xff\xff\x48\x00\x3b\x00\x3c\x00\x3d\x00\x1b\x00\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\xff\xff\x5a\x00\x56\x00\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x2b\x00\x2c\x00\x5e\x00\xff\xff\x2f\x00\x30\x00\xff\xff\x32\x00\xff\xff\x34\x00\xff\xff\xff\xff\x37\x00\xff\xff\x39\x00\x3a\x00\x37\x00\xff\xff\x73\x00\x74\x00\xff\xff\x40\x00\x41\x00\x42\x00\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x49\x00\x46\x00\x47\x00\x4c\x00\xff\xff\xff\xff\x4f\x00\xff\xff\xff\xff\x01\x00\xff\xff\x03\x00\x78\x00\x79\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x0d\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\xff\xff\x1b\x00\xff\xff\xff\xff\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\xff\xff\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\x2f\x00\xff\xff\x44\x00\x45\x00\xff\xff\x47\x00\xff\xff\x36\x00\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x43\x00\x01\x00\xff\xff\x03\x00\xff\xff\x48\x00\x5c\x00\x5d\x00\x5e\x00\x4c\x00\x4d\x00\xff\xff\x5a\x00\x0d\x00\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x56\x00\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\xff\xff\xff\xff\x73\x00\x74\x00\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x1b\x00\x3d\x00\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\xff\xff\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\xff\xff\x4e\x00\xff\xff\x2f\x00\x51\x00\xff\xff\x53\x00\x54\x00\x55\x00\x56\x00\x36\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5d\x00\x5e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\x43\x00\x03\x00\xff\xff\x01\x00\xff\xff\x48\x00\x01\x00\xff\xff\xff\xff\x4c\x00\x4d\x00\x0d\x00\x42\x00\x43\x00\x44\x00\x0d\x00\x46\x00\x47\x00\x0d\x00\x56\x00\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\xff\xff\xff\xff\x36\x00\x5a\x00\xff\xff\x5c\x00\x36\x00\x5e\x00\x5f\x00\x36\x00\x1b\x00\xff\xff\xff\xff\xff\xff\xff\xff\x43\x00\x78\x00\x79\x00\xff\xff\x43\x00\x48\x00\xff\xff\x43\x00\xff\xff\x48\x00\xff\xff\xff\xff\x48\x00\x73\x00\x74\x00\x2f\x00\x5a\x00\xff\xff\x5c\x00\x56\x00\x5e\x00\x5f\x00\x36\x00\x56\x00\xff\xff\x5c\x00\x56\x00\x5e\x00\xff\xff\x5c\x00\x5d\x00\x5e\x00\x5c\x00\x5d\x00\x5e\x00\x43\x00\xff\xff\xff\xff\xff\xff\xff\xff\x48\x00\x73\x00\x74\x00\xff\xff\x4c\x00\x4d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x56\x00\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x01\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\xff\xff\x03\x00\xff\xff\x0d\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x01\x00\x1b\x00\x03\x00\xff\xff\xff\xff\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\x73\x00\x74\x00\x2c\x00\x2d\x00\x36\x00\x2f\x00\xff\xff\x5a\x00\xff\xff\x5c\x00\x1b\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x43\x00\xff\xff\xff\xff\xff\xff\xff\xff\x48\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2c\x00\x2d\x00\xff\xff\x2f\x00\xff\xff\x73\x00\x74\x00\x4c\x00\xff\xff\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x4c\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\x73\x00\x74\x00\xff\xff\xff\xff\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\x42\x00\x43\x00\x44\x00\x1b\x00\x46\x00\x47\x00\x5a\x00\x01\x00\x5c\x00\x03\x00\x5e\x00\x5f\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x36\x00\x73\x00\x74\x00\x1b\x00\xff\xff\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\xff\xff\x43\x00\xff\xff\xff\xff\xff\xff\xff\xff\x48\x00\xff\xff\x2c\x00\xff\xff\x4c\x00\x2f\x00\x78\x00\x79\x00\xff\xff\x01\x00\xff\xff\x03\x00\x73\x00\x74\x00\x56\x00\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x0d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x4c\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\x73\x00\x74\x00\x36\x00\xff\xff\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\x43\x00\xff\xff\xff\xff\xff\xff\xff\xff\x48\x00\xff\xff\x5a\x00\xff\xff\x5c\x00\x1b\x00\x5e\x00\x5f\x00\x60\x00\x01\x00\xff\xff\xff\xff\xff\xff\xff\xff\x56\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x5e\x00\xff\xff\x10\x00\x2f\x00\xff\xff\x73\x00\x74\x00\xff\xff\xff\xff\xff\xff\x36\x00\xff\xff\x5a\x00\x1b\x00\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\xff\xff\x43\x00\xff\xff\xff\xff\xff\xff\xff\xff\x48\x00\xff\xff\x2c\x00\xff\xff\x4c\x00\x2f\x00\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\xff\xff\xff\xff\xff\xff\x56\x00\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\xff\xff\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\xff\xff\x36\x00\xff\xff\xff\xff\xff\xff\x4c\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x01\x00\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\x02\x00\xff\xff\xff\xff\x0d\x00\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x01\x00\x1b\x00\xff\xff\xff\xff\xff\xff\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x79\x00\xff\xff\x10\x00\x73\x00\x74\x00\xff\xff\xff\xff\x36\x00\x2f\x00\xff\xff\x5a\x00\xff\xff\x5c\x00\x1b\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x43\x00\xff\xff\xff\xff\xff\xff\xff\xff\x48\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2c\x00\xff\xff\xff\xff\x2f\x00\xff\xff\x73\x00\x74\x00\x4c\x00\xff\xff\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\x5e\x00\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\xff\xff\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x4c\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\xff\xff\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\x73\x00\x74\x00\xff\xff\xff\xff\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\x42\x00\x43\x00\x44\x00\xff\xff\x1b\x00\x01\x00\x02\x00\xff\xff\xff\xff\xff\xff\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\x2c\x00\xff\xff\x5a\x00\x2f\x00\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\xff\xff\x1b\x00\x01\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\x73\x00\x74\x00\xff\xff\x2f\x00\xff\xff\x4c\x00\x78\x00\x79\x00\xff\xff\xff\xff\x1b\x00\xff\xff\xff\xff\x1e\x00\xff\xff\xff\xff\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\xff\xff\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x2f\x00\xff\xff\x4c\x00\xff\xff\xff\xff\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\xff\xff\xff\xff\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\xff\xff\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\xff\xff\xff\xff\x4c\x00\x73\x00\x74\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\x42\x00\x43\x00\x44\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\xff\xff\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\x1b\x00\xff\xff\xff\xff\xff\xff\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x78\x00\x79\x00\x10\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x1b\x00\xff\xff\xff\xff\xff\xff\x01\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\x2f\x00\x37\x00\xff\xff\xff\xff\x4c\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x1b\x00\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\xff\xff\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x4c\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\xff\xff\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x4c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\xff\xff\xff\xff\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\xff\xff\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\x42\x00\x43\x00\x44\x00\x01\x00\x1b\x00\xff\xff\xff\xff\xff\xff\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x1b\x00\xff\xff\xff\xff\xff\xff\x01\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\x2f\x00\xff\xff\xff\xff\xff\xff\x4c\x00\x78\x00\x79\x00\xff\xff\xff\xff\xff\xff\x1b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\xff\xff\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x4c\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\xff\xff\x03\x00\xff\xff\xff\xff\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\xff\xff\x0d\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x4c\x00\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x0d\x00\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x01\x00\xff\xff\xff\xff\xff\xff\x36\x00\xff\xff\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x10\x00\xff\xff\x43\x00\xff\xff\xff\xff\xff\xff\xff\xff\x48\x00\xff\xff\xff\xff\xff\xff\x1b\x00\x30\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\xff\xff\xff\xff\x38\x00\x56\x00\xff\xff\x3b\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\xff\xff\x5e\x00\xff\xff\x2f\x00\x44\x00\x45\x00\xff\xff\x47\x00\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x01\x00\xff\xff\x03\x00\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x4c\x00\xff\xff\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\xff\xff\xff\xff\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\xff\xff\x01\x00\x31\x00\x03\x00\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x01\x00\x31\x00\x03\x00\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x01\x00\x31\x00\x03\x00\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x01\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x01\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x01\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x01\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x01\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x01\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x01\x00\x31\x00\x03\x00\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x01\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5d\x00\x5e\x00\x01\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x01\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x01\x00\x31\x00\x03\x00\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x01\x00\x31\x00\x03\x00\x33\x00\xff\xff\x35\x00\xff\xff\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\xff\xff\x47\x00\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\xff\xff\x01\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\xff\xff\x31\x00\xff\xff\x33\x00\x0d\x00\x35\x00\xff\xff\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\xff\xff\x47\x00\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\xff\xff\x01\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x5d\x00\x5e\x00\x38\x00\xff\xff\xff\xff\x3b\x00\x0d\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\xff\xff\x47\x00\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\xff\xff\x5c\x00\x5d\x00\x5e\x00\xff\xff\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\xff\xff\x0d\x00\x38\x00\xff\xff\x01\x00\x3b\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\x0d\x00\x47\x00\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x01\x00\x1e\x00\x03\x00\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\xff\xff\x36\x00\xff\xff\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x33\x00\x43\x00\x35\x00\xff\xff\xff\xff\x38\x00\x48\x00\xff\xff\x3b\x00\xff\xff\x3d\x00\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\xff\xff\x56\x00\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\x5c\x00\x4e\x00\x5e\x00\xff\xff\x51\x00\x36\x00\x53\x00\x54\x00\x55\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x43\x00\xff\xff\xff\xff\x1e\x00\x1f\x00\x48\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\x33\x00\x5c\x00\xff\xff\x5e\x00\x37\x00\xff\xff\xff\xff\xff\xff\xff\xff\x3c\x00\x3d\x00\xff\xff\xff\xff\xff\xff\xff\xff\x42\x00\x43\x00\x44\x00\xff\xff\xff\xff\xff\xff\x48\x00\x49\x00\x4a\x00\xff\xff\xff\xff\xff\xff\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\xff\xff\xff\xff\xff\xff\x1e\x00\x1f\x00\xff\xff\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x33\x00\x42\x00\x43\x00\x44\x00\x37\x00\x46\x00\x47\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\x42\x00\x43\x00\x44\x00\xff\xff\xff\xff\xff\xff\x48\x00\x49\x00\x4a\x00\xff\xff\xff\xff\xff\xff\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x1e\x00\x1f\x00\xff\xff\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x33\x00\xff\xff\x78\x00\x79\x00\x37\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\x42\x00\x43\x00\x44\x00\xff\xff\x77\x00\x78\x00\x79\x00\xff\xff\xff\xff\xff\xff\x48\x00\x49\x00\x4a\x00\xff\xff\xff\xff\xff\xff\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x1e\x00\x1f\x00\xff\xff\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x33\x00\x42\x00\x43\x00\x44\x00\x37\x00\x46\x00\x47\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x78\x00\x79\x00\xff\xff\x77\x00\x78\x00\x79\x00\xff\xff\xff\xff\xff\xff\x48\x00\x49\x00\x4a\x00\x4b\x00\xff\xff\xff\xff\xff\xff\xff\xff\x1e\x00\x1f\x00\xff\xff\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x33\x00\xff\xff\xff\xff\xff\xff\x37\x00\x78\x00\x79\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\x48\x00\x49\x00\x4a\x00\xff\xff\xff\xff\xff\xff\x1e\x00\x1f\x00\xff\xff\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\x20\x00\x21\x00\xff\xff\x23\x00\xff\xff\x33\x00\xff\xff\xff\xff\xff\xff\x37\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x33\x00\xff\xff\x21\x00\x36\x00\x23\x00\xff\xff\x77\x00\x78\x00\x79\x00\x4a\x00\xff\xff\x2a\x00\x2b\x00\x2c\x00\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\xff\xff\x33\x00\xff\xff\xff\xff\x36\x00\xff\xff\xff\xff\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\xff\xff\x21\x00\xff\xff\x23\x00\xff\xff\x21\x00\xff\xff\x23\x00\xff\xff\xff\xff\x2a\x00\x2b\x00\x2c\x00\x79\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\xff\xff\x33\x00\xff\xff\xff\xff\xff\xff\x33\x00\xff\xff\xff\xff\x36\x00\xff\xff\x3c\x00\x3d\x00\xff\xff\xff\xff\x78\x00\x79\x00\x42\x00\x43\x00\x44\x00\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x21\x00\xff\xff\x23\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\x2c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x33\x00\x21\x00\xff\xff\x23\x00\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\x23\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\x2c\x00\x33\x00\x79\x00\xff\xff\x36\x00\x78\x00\x79\x00\x33\x00\xff\xff\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x22\x00\x23\x00\xff\xff\x25\x00\xff\xff\x27\x00\xff\xff\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\xff\xff\xff\xff\xff\xff\x22\x00\x23\x00\x33\x00\x25\x00\xff\xff\x27\x00\x37\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\x79\x00\xff\xff\xff\xff\xff\xff\xff\xff\x33\x00\xff\xff\xff\xff\xff\xff\x37\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x4c\x00\xff\xff\xff\xff\xff\xff\x79\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x79\x00\xff\xff\xff\xff\xff\xff\x5a\x00\x4c\x00\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\x22\x00\x23\x00\xff\xff\x25\x00\xff\xff\x27\x00\xff\xff\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\x77\x00\x78\x00\x79\x00\xff\xff\xff\xff\x33\x00\xff\xff\xff\xff\xff\xff\x37\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x22\x00\x23\x00\xff\xff\x25\x00\xff\xff\x27\x00\x4c\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x73\x00\x74\x00\xff\xff\xff\xff\xff\xff\xff\xff\x33\x00\xff\xff\xff\xff\x5a\x00\x37\x00\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\x4c\x00\xff\xff\xff\xff\x73\x00\x74\x00\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\x22\x00\x23\x00\xff\xff\x25\x00\xff\xff\x27\x00\xff\xff\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x33\x00\xff\xff\xff\xff\xff\xff\x37\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\x22\x00\x23\x00\xff\xff\x25\x00\xff\xff\x27\x00\x4c\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x73\x00\x74\x00\xff\xff\xff\xff\xff\xff\xff\xff\x33\x00\xff\xff\xff\xff\x5a\x00\x37\x00\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\x4c\x00\xff\xff\xff\xff\x73\x00\x74\x00\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\x22\x00\x23\x00\xff\xff\x25\x00\xff\xff\x27\x00\xff\xff\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\x2e\x00\x2f\x00\x30\x00\x22\x00\x23\x00\x33\x00\x25\x00\xff\xff\x27\x00\x37\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\x2e\x00\x2f\x00\x30\x00\x22\x00\x23\x00\x33\x00\x25\x00\xff\xff\x27\x00\x37\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x33\x00\xff\xff\x22\x00\x23\x00\x37\x00\x25\x00\xff\xff\x27\x00\xff\xff\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x33\x00\xff\xff\xff\xff\xff\xff\x37\x00\xff\xff\x4c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\xff\xff\x22\x00\x23\x00\x4c\x00\x25\x00\xff\xff\x27\x00\xff\xff\x29\x00\x2a\x00\x2b\x00\x2c\x00\x77\x00\x78\x00\x79\x00\xff\xff\x23\x00\xff\xff\x33\x00\xff\xff\xff\xff\xff\xff\x37\x00\x2a\x00\x2b\x00\x2c\x00\x36\x00\x77\x00\x78\x00\x79\x00\xff\xff\xff\xff\x33\x00\xff\xff\xff\xff\x36\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\xff\xff\x4c\x00\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\xff\xff\xff\xff\xff\xff\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x23\x00\xff\xff\xff\xff\x36\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\x2c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x32\x00\x33\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\xff\xff\xff\xff\x78\x00\x79\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x36\x00\xff\xff\xff\xff\xff\xff\x71\x00\xff\xff\x73\x00\x74\x00\xff\xff\x37\x00\x77\x00\x78\x00\x79\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\x46\x00\x47\x00\xff\xff\xff\xff\x79\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x37\x00\xff\xff\xff\xff\x36\x00\x71\x00\xff\xff\x73\x00\x74\x00\x3b\x00\x3c\x00\x3d\x00\xff\xff\x79\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x77\x00\x78\x00\x79\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\xff\xff\xff\xff\xff\xff\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\xff\xff\xff\xff\xff\xff\x71\x00\xff\xff\x73\x00\x74\x00\xff\xff\xff\xff\x77\x00\x78\x00\x79\x00\x37\x00\x77\x00\x78\x00\x79\x00\x3b\x00\x3c\x00\x3d\x00\x37\x00\x36\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\xff\xff\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x77\x00\x78\x00\x79\x00\xff\xff\xff\xff\x73\x00\x74\x00\x77\x00\x78\x00\x79\x00\x2b\x00\xff\xff\x2d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x33\x00\xff\xff\x35\x00\xff\xff\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\xff\xff\xff\xff\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\xff\xff\x4e\x00\xff\xff\xff\xff\x51\x00\xff\xff\x53\x00\x54\x00\x55\x00\xff\xff\xff\xff\x2b\x00\xff\xff\x2d\x00\xff\xff\xff\xff\x5d\x00\x5e\x00\x5f\x00\x33\x00\xff\xff\x35\x00\xff\xff\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\xff\xff\xff\xff\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\xff\xff\x4e\x00\xff\xff\x2b\x00\x51\x00\xff\xff\x53\x00\x54\x00\x55\x00\x31\x00\xff\xff\xff\xff\xff\xff\xff\xff\x36\x00\xff\xff\x5d\x00\x5e\x00\x5f\x00\x2b\x00\xff\xff\xff\xff\x3e\x00\xff\xff\xff\xff\x31\x00\xff\xff\x43\x00\xff\xff\xff\xff\x36\x00\x47\x00\x48\x00\xff\xff\xff\xff\xff\xff\xff\xff\x4d\x00\x3e\x00\xff\xff\x50\x00\xff\xff\x52\x00\x43\x00\xff\xff\xff\xff\x56\x00\x47\x00\x48\x00\xff\xff\xff\xff\xff\xff\xff\xff\x4d\x00\x5e\x00\xff\xff\x50\x00\xff\xff\x52\x00\x2c\x00\xff\xff\xff\xff\x56\x00\xff\xff\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\xff\xff\x5e\x00\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\xff\xff\x47\x00\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2e\x00\x5d\x00\x5e\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\xff\xff\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\xff\xff\x47\x00\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5d\x00\x5e\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\x5d\x00\x5e\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5d\x00\x5e\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5d\x00\x5e\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\xff\xff\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x5d\x00\x5e\x00\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\xff\xff\x47\x00\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\xff\xff\xff\xff\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x5d\x00\x5e\x00\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\xff\xff\x47\x00\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\x4e\x00\xff\xff\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5d\x00\x5e\x00\x31\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\xff\xff\x3e\x00\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\x47\x00\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\x4d\x00\xff\xff\xff\xff\x50\x00\xff\xff\x52\x00\xff\xff\x54\x00\x55\x00\x56\x00\x33\x00\xff\xff\x35\x00\xff\xff\xff\xff\x38\x00\xff\xff\x5e\x00\x3b\x00\xff\xff\x3d\x00\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\xff\xff\xff\xff\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\xff\xff\x4e\x00\xff\xff\xff\xff\x51\x00\xff\xff\x53\x00\x54\x00\x55\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5d\x00\x5e\x00\x5f\x00\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\xff\xff\xff\xff\x3b\x00\xff\xff\x3d\x00\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\xff\xff\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\xff\xff\x4e\x00\xff\xff\xff\xff\x51\x00\xff\xff\x53\x00\x54\x00\x55\x00\x56\x00\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\x5d\x00\x5e\x00\x3b\x00\xff\xff\x3d\x00\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\xff\xff\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\xff\xff\x4e\x00\xff\xff\xff\xff\x51\x00\xff\xff\x53\x00\x54\x00\x55\x00\x56\x00\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\x5d\x00\x5e\x00\x3b\x00\xff\xff\x3d\x00\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\xff\xff\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\xff\xff\x4e\x00\xff\xff\xff\xff\x51\x00\xff\xff\x53\x00\x54\x00\x55\x00\x56\x00\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\x5d\x00\x5e\x00\x3b\x00\xff\xff\x3d\x00\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\xff\xff\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\xff\xff\x4e\x00\xff\xff\xff\xff\x51\x00\xff\xff\x53\x00\x54\x00\x55\x00\x56\x00\x33\x00\xff\xff\x35\x00\xff\xff\xff\xff\x38\x00\x5d\x00\x5e\x00\x3b\x00\xff\xff\x3d\x00\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\xff\xff\xff\xff\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\xff\xff\x4e\x00\xff\xff\xff\xff\x51\x00\xff\xff\x53\x00\x54\x00\x55\x00\xff\xff\x33\x00\xff\xff\x35\x00\xff\xff\xff\xff\x38\x00\x5d\x00\x5e\x00\x3b\x00\xff\xff\x3d\x00\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\xff\xff\xff\xff\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\xff\xff\x4e\x00\xff\xff\xff\xff\x51\x00\xff\xff\x53\x00\x54\x00\x55\x00\xff\xff\x33\x00\xff\xff\x35\x00\xff\xff\xff\xff\x38\x00\x5d\x00\x5e\x00\x3b\x00\xff\xff\x3d\x00\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\xff\xff\x44\x00\x45\x00\xff\xff\xff\xff\xff\xff\xff\xff\x4a\x00\x4b\x00\xff\xff\xff\xff\x4e\x00\xff\xff\xff\xff\x51\x00\xff\xff\x53\x00\x54\x00\x55\x00\xff\xff\x33\x00\xff\xff\x35\x00\x36\x00\xff\xff\x38\x00\x5d\x00\x5e\x00\x3b\x00\xff\xff\xff\xff\xff\xff\x3f\x00\xff\xff\xff\xff\xff\xff\x43\x00\x44\x00\x45\x00\xff\xff\xff\xff\x48\x00\xff\xff\x4a\x00\x4b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x54\x00\x55\x00\x56\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x53\x00\x5e\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x53\x00\x76\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x53\x00\x76\x00\xff\xff\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\x76\x00\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x72\x00\x73\x00\x74\x00\xff\xff\x53\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x53\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x53\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\xff\xff\xff\xff\xff\xff\x71\x00\xff\xff\x73\x00\x74\x00\xff\xff\x5a\x00\xff\xff\x5c\x00\x79\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\x70\x00\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\x70\x00\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\x70\x00\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\x70\x00\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\x70\x00\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\xff\xff\x6f\x00\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x72\x00\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x72\x00\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x72\x00\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x72\x00\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x72\x00\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x72\x00\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x72\x00\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x72\x00\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x72\x00\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x72\x00\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\x5a\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x3b\x00\x3c\x00\x3d\x00\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\xff\xff\xff\xff\x73\x00\x74\x00\xff\xff\xff\xff\xff\xff\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x3b\x00\x3c\x00\x3d\x00\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x31\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x38\x00\xff\xff\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x31\x00\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\xff\xff\x38\x00\xff\xff\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x38\x00\xff\xff\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x38\x00\xff\xff\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x38\x00\xff\xff\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"# happyTable :: HappyAddr happyTable = HappyA# "\x00\x00\x88\x00\x4c\x00\x4d\x00\xa2\x01\x7b\x03\x5e\x03\x12\x03\x13\x03\x11\x03\x12\x03\x13\x03\x60\x03\x3d\xfe\xe6\x02\x25\x02\x8d\x01\x72\x03\xaa\x00\xcb\x01\x35\x03\x25\x03\x1a\x02\x7a\x03\x4e\x00\x69\x03\x4f\x00\x26\x02\x50\x00\x51\x00\x52\x00\xcc\x01\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\xd4\x02\x16\x03\xf8\x00\x7b\x02\x82\x02\xef\x00\x5f\x00\x84\x01\xc7\x00\xb9\x00\x60\x00\xc8\x00\xf7\x01\xbc\x00\x3d\x01\x4c\x00\x4d\x00\x75\x01\x36\x03\x7b\x03\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x9c\x00\x25\x02\x4f\x03\xba\x00\x83\x02\xcb\x01\x76\x01\xbd\x00\xe2\x01\xf9\x00\x4e\x00\x71\x03\x4f\x00\x26\x02\x50\x00\x51\x00\x52\x00\xcc\x01\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x14\x03\x97\x01\x86\x00\x14\x03\x14\x03\x84\x00\x5f\x00\x86\x00\x73\x03\x84\x00\x60\x00\x86\x00\x86\x00\xd6\x00\x4b\x00\x4c\x00\x4d\x00\x68\x00\x69\x00\x6a\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\xf0\x00\x4b\x00\xc8\x01\x63\x00\xc9\x01\x2a\x00\xb6\x00\x84\x00\x98\x01\x86\x00\x4e\x00\x86\x00\x4f\x00\xc9\x00\x50\x00\x51\x00\x52\x00\xbe\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\xaa\x00\xcb\x01\x06\x02\x4f\x03\xaa\x00\x84\x00\x5f\x00\x86\x00\x6a\x03\x84\x00\x60\x00\x86\x00\x55\x03\xcc\x01\x07\x02\xdd\x01\xbd\x00\x68\x00\x69\x00\x6a\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x9c\x00\x39\x03\xab\x00\xfb\x02\xac\x00\xc4\x00\x25\x02\x3b\x03\x84\x00\x98\x01\x86\x00\xad\x00\x5d\x00\x5e\x00\xd7\x00\xe1\x02\xb7\x00\xd3\x02\x26\x02\xe0\x02\x5f\x00\x25\x02\x9d\x01\xae\x00\xc5\x00\x56\x03\xde\x01\x0a\x03\x3c\xfe\xf7\x01\x6d\x03\x0b\x03\xf6\x01\x26\x02\xaf\x00\x62\x00\x63\x00\x64\x00\xb0\x00\x66\x00\x67\x00\x3c\xfe\xd8\x00\xb9\x00\xf7\x01\xd9\x00\x3c\xfe\x68\x00\x69\x00\x6a\x00\xcb\x01\xb5\x00\xda\x00\x5d\x00\x5e\x00\x9e\x01\xbe\x00\xd4\x02\x6e\x03\xe1\x02\x3c\xfe\x5f\x00\xcc\x01\x60\x02\xba\x00\x84\x00\x84\x00\xd7\x00\x86\x00\xf7\x01\xf0\x00\x4b\x00\xb6\x00\xd5\x00\xa1\x00\xdb\x00\x62\x00\x63\x00\x64\x00\xdc\x00\x66\x00\x67\x00\x54\x03\x41\x03\x9f\x01\xd6\x00\xa0\x01\xa2\x00\xae\x00\xb1\x00\x6a\x00\xc6\x00\xa3\x00\xa1\x01\x5d\x00\x5e\x00\x96\x00\x84\x00\xd7\x00\x86\x00\xf9\x01\x19\x03\x5f\x00\xec\x02\xe8\x02\xa2\x01\xa4\x00\x1a\x03\x84\x00\xd7\x00\x86\x00\x42\x03\x84\x00\xd7\x00\x86\x00\xf7\x01\xa3\x01\x62\x00\x63\x00\x64\x00\xa4\x01\x66\x00\x67\x00\x84\x00\xd7\x00\x97\x00\xc3\x00\x98\x00\xc4\x00\xf0\x00\x4b\x00\xdd\x00\x1b\x03\x6c\x00\x99\x00\x5d\x00\x5e\x00\x86\x02\x1d\x03\xb7\x00\xfa\x01\x84\x00\x89\x02\x5f\x00\x28\x03\x6d\x00\x0c\x02\xc5\x00\x84\x00\x98\x01\x86\x00\xf0\x00\x4b\x00\xc1\x02\x80\x02\x6a\x00\xa1\x00\x9a\x00\x62\x00\x63\x00\x64\x00\x9b\x00\x66\x00\x67\x00\x84\x00\xd7\x00\xab\x00\xcb\x01\xac\x00\xa2\x00\xd8\x00\xb9\x00\x9c\x00\xd9\x00\xa3\x00\xad\x00\x5d\x00\x5e\x00\x1c\x03\xcc\x01\xda\x00\x5d\x00\x5e\x00\x67\x02\x5f\x00\x60\x02\x98\x02\xae\x00\xa4\x00\x5f\x00\xda\x01\xdb\x01\xba\x00\x99\x02\x84\x00\xd7\x00\x86\x00\x8c\x02\xaf\x00\x62\x00\x63\x00\xd0\x01\x9a\x02\xdb\x00\x62\x00\x63\x00\xd0\x01\x9f\x01\xa8\x02\xa0\x01\x0d\x02\x8c\x00\x6a\x00\x9c\x00\xc6\x00\x84\x01\xa1\x01\x5d\x00\x5e\x00\x97\x01\xa1\x00\xb4\x02\x84\x01\x68\x02\x84\x00\x5f\x00\x86\x00\xa8\xfe\xa2\x01\xbc\x00\xa8\xfe\xd6\x00\xec\x01\xa2\x00\x6e\x03\x32\x00\x33\x00\xd7\x01\xa3\x00\xa3\x01\x62\x00\x63\x00\xd0\x01\x90\x02\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x25\x02\xbd\x00\x16\x02\xa4\x00\x87\x02\x6a\x00\xa8\xfe\xda\x02\xe1\x01\x84\x00\xdd\x00\x86\x00\x26\x02\xc0\x00\xb9\x00\x37\x03\xb8\x00\xb9\x00\x38\x03\x46\x02\x32\x00\x33\x00\x91\x02\x8d\x02\x19\x02\x48\x02\x49\x02\x4a\x02\x1b\x02\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x1e\x02\xba\x00\xf0\x00\x4b\x00\xba\x00\x4b\x02\xa9\x00\x4f\x00\xaa\x00\x50\x00\x4c\x02\x4d\x02\x9c\x00\x53\x00\x4e\x02\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\xe0\x01\xe1\x01\x84\x00\x98\x01\x86\x00\x42\x02\x5f\x00\x20\x02\x70\x01\xbe\x00\x4f\x02\x06\x00\x71\x01\x07\x00\xe2\x01\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x2f\x02\x39\x00\x84\x00\xd7\x00\x86\x00\x89\x01\x18\x00\x19\x00\xa8\x01\x3a\x00\x92\x00\x63\x00\xe9\x01\xc1\x00\xe5\xff\x06\x00\xbb\x00\x07\x00\x86\x01\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x84\x01\x39\x00\xe2\x01\x84\x01\x35\x02\xc6\x01\x18\x00\x19\x00\x43\x02\x3a\x00\x68\x00\xc3\x01\x6a\x00\x46\x02\x32\x00\x33\x00\x44\x02\x47\x02\x60\x02\x48\x02\x49\x02\x4a\x02\x3f\x01\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x92\x01\x1a\x02\x95\x00\x6a\x00\x83\x01\x4b\x02\x84\x01\x4f\x00\x40\x01\x50\x00\x4c\x02\x4d\x02\xd6\x00\x53\x00\x4e\x02\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x0d\x01\x70\x03\x8c\x00\x6a\x00\x89\x01\x84\x01\x5f\x00\x86\x01\x84\x01\x99\x01\x4f\x02\xa8\x01\xc6\x01\x97\x01\x82\x01\xea\x02\x23\x02\xcf\x00\xeb\x02\x06\x02\x88\x01\xaa\x00\xc8\x01\x63\x00\xc9\x01\xd6\x00\x8a\x01\x0e\x01\x55\x00\x98\x01\x0f\x01\x07\x02\x10\x01\x84\x01\x11\x01\x5c\x00\x5d\x00\x5e\x00\x84\x01\x9a\x01\x84\x01\x84\x01\xc0\x00\xb9\x00\x5f\x00\x06\x00\x9b\x01\x07\x00\x12\x01\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\xba\x00\x39\x00\x84\x00\xd7\x00\x86\x00\x68\x01\x18\x00\x19\x00\xa7\x01\x3a\x00\x68\x00\xc3\x01\x6a\x00\x9c\x00\xa9\x01\xcf\x01\x62\x00\x63\x00\xd0\x01\x06\x00\xbc\x01\x07\x00\xc5\x01\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x0d\x01\x14\x01\x84\x00\x98\x01\x86\x00\xc7\x01\x18\x00\x19\x00\x84\x00\xd7\x00\x68\x00\x15\x01\x6a\x00\xf6\x01\x9c\x00\x7d\x02\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\x30\x03\xd4\x01\x75\x02\x31\x03\xf7\x01\x76\x02\x0e\x01\x55\x00\xc1\x00\x0f\x01\xd5\x01\x10\x01\x9c\x00\x11\x01\x5c\x00\x5d\x00\x5e\x00\x0d\x01\x20\x03\x21\x03\x9f\x00\x04\x03\x22\x03\x5f\x00\x2b\x03\x2c\x03\xdd\x02\x12\x01\xae\x00\xde\x02\x2e\x03\xa4\x00\xae\x00\x2b\x02\xce\x00\xcf\x00\x2c\x02\xd1\x00\x9c\x00\xd1\x01\x62\x00\x63\x00\xd0\x01\xe7\x00\x0e\x01\x55\x00\xed\x00\x0f\x01\x69\x01\x10\x01\xfa\x00\x11\x01\x5c\x00\x5d\x00\x5e\x00\x7e\x02\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\x5f\x00\x06\x00\x04\x01\x07\x00\x12\x01\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x0a\x01\x14\x01\x84\x00\xd7\x00\x2b\x01\x6b\x01\x18\x00\x19\x00\x87\x00\x05\x00\x68\x00\x15\x01\x6a\x00\x2d\x02\x6a\x00\x05\x00\x7f\x02\x80\x02\x6a\x00\x06\x00\x7d\x03\x07\x00\x2a\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x0d\x01\x14\x01\x38\x02\x62\x00\x63\x00\xd0\x01\x18\x00\x19\x00\xae\x00\x7e\x03\x68\x00\x15\x01\x6a\x00\x2b\x02\xce\x00\xcf\x00\x2c\x02\xd1\x00\x2a\x00\xd1\x01\x62\x00\x63\x00\x64\x00\xb5\x02\xd2\x01\x67\x00\x7f\x03\x0e\x01\x55\x00\x75\x03\x0f\x01\x76\x03\x10\x01\x77\x03\x11\x01\x5c\x00\x5d\x00\x5e\x00\x38\x03\xa6\x00\xa7\x00\xbe\x01\x69\x03\x4f\x00\x5f\x00\x50\x00\xbf\x01\xc0\x01\x12\x01\x53\x00\xc1\x01\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5a\x03\x20\x01\x21\x01\x22\x01\x23\x01\x2a\x00\x5f\x00\x65\x01\x13\x01\xaa\x00\xc2\x01\xf0\x00\x4b\x00\x2d\x02\x6a\x00\xf9\x02\x62\x00\x63\x00\xd0\x01\x66\x01\x3d\x03\x3e\x03\x06\x00\x86\x00\x07\x00\x6c\x03\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x06\x00\x14\x01\x07\x00\x58\x03\x00\x01\x09\x00\x18\x00\x19\x00\xfe\x02\xff\x02\x68\x00\x15\x01\x6a\x00\x97\x00\x86\x00\x98\x00\x00\x03\x01\x03\xee\x01\xfa\x01\x19\x03\x98\x00\x99\x00\x5d\x00\x5e\x00\x18\x00\x19\x00\x5d\x03\x99\x00\x5d\x00\x5e\x00\x5f\x00\x5e\x03\x68\x00\xc3\x01\x6a\x00\xbe\x01\x5f\x00\x4f\x00\x60\x03\x50\x00\xbf\x01\xc0\x01\x63\x03\x53\x00\xc1\x01\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x17\x02\xfa\x01\x8f\x02\xa2\x01\xf0\x00\x4b\x00\x5f\x00\x26\x02\xa6\x00\xa7\x00\xc2\x01\x49\x03\x8c\x00\x6a\x00\xe5\x01\x62\x00\x63\x00\xd0\x01\xbe\x01\x64\x03\x4f\x00\x65\x03\x50\x00\xbf\x01\xc0\x01\x3d\x00\x53\x00\xc1\x01\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x06\x00\x40\x03\x07\x00\x3f\x03\x02\x01\x09\x00\x5f\x00\x9c\x00\x43\x03\x9f\x01\xc2\x01\xa0\x01\x49\x03\x9c\x00\x86\x00\xac\x00\xf0\x00\x4b\x00\xa1\x01\x5d\x00\x5e\x00\x21\x02\xad\x00\x5d\x00\x5e\x00\x18\x00\x19\x00\x5f\x00\x1e\x01\x1f\x01\xa2\x01\x5f\x00\x9c\x00\x4f\x03\xae\x00\x86\x00\x68\x00\xc3\x01\x6a\x00\xbe\x01\x51\x03\x4f\x00\x53\x03\x50\x00\xbf\x01\xc0\x01\x86\x01\x53\x00\xc1\x01\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x30\x02\x92\x01\xcf\x00\x93\x01\xd1\x00\x9d\x02\x5f\x00\x92\x00\x63\x00\x93\x00\xc2\x01\x94\x00\x67\x00\x24\x01\x25\x01\x68\x00\xc3\x01\x6a\x00\xbe\x01\xe3\x02\x4f\x00\x86\x00\x50\x00\xbf\x01\xc0\x01\xf0\x02\x53\x00\xc1\x01\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x9c\x00\xae\x00\xfb\x02\xfc\x02\x6a\x00\xf1\x02\x5f\x00\x4a\x03\x8c\x00\x6a\x00\xc2\x01\xa0\x01\xd1\x01\x62\x00\x63\x00\xd0\x01\x4c\x03\xf4\x02\xa1\x01\x5d\x00\x5e\x00\x36\x02\xf5\x02\x95\x01\x6a\x00\xf0\x00\x4b\x00\x5f\x00\x26\x01\x27\x01\xa2\x01\xf9\x02\x62\x00\x63\x00\xd0\x01\xf6\x02\x68\x00\xc3\x01\x6a\x00\xbe\x01\xf7\x02\x4f\x00\x0a\x03\x50\x00\xbf\x01\xc0\x01\xee\x01\x53\x00\xc1\x01\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\xbd\x01\x06\x02\x18\x03\xaa\x00\xe4\x00\xe5\x00\x5f\x00\x0d\x03\xd3\x01\x6a\x00\xc2\x01\xe6\x00\xe7\x00\x07\x02\x0e\x03\x68\x00\xc3\x01\x6a\x00\xbe\x01\x0f\x03\x4f\x00\x10\x03\x50\x00\xbf\x01\xc0\x01\x17\x03\x53\x00\xc1\x01\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x9c\x00\x6f\x03\x32\x00\x33\x00\xf0\x00\x4b\x00\x5f\x00\xa1\x00\x18\x01\x19\x01\xc2\x01\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\xa1\x00\x97\x00\x3d\x00\x98\x00\xa2\x00\x4b\x03\x8c\x00\x6a\x00\x2b\x03\xa3\x00\x99\x00\x5d\x00\x5e\x00\xa2\x00\x45\x03\x32\x00\x33\x00\x1f\x03\xa3\x00\x5f\x00\x68\x00\xc3\x01\x6a\x00\xa4\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x1e\x01\x1f\x01\x86\x00\xa4\x00\x23\x03\xc8\x01\x63\x00\xc9\x01\x26\x03\x84\x00\xd7\x00\x86\x00\x10\x03\x32\x00\x33\x00\x24\x01\x25\x01\x77\x02\xa6\x00\xa7\x00\x78\x02\x79\x02\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\xe8\x01\x27\x03\x68\x00\xc3\x01\x6a\x00\xf1\x02\x8c\x00\x6a\x00\x26\x01\x27\x01\x8f\x00\x62\x00\x63\x00\xd0\x01\x06\x00\x7c\x02\x07\x00\x7d\x02\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x9c\x00\x39\x00\xf2\x02\x8c\x00\x6a\x00\x63\x02\x18\x00\x19\x00\x3e\xfe\x3a\x00\x06\x00\xbc\x01\x07\x00\x8c\x02\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x92\x02\x39\x00\x68\x00\x91\x00\x6a\x00\x86\x01\x18\x00\x19\x00\x06\x00\x3a\x00\x07\x00\x2a\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x9c\x02\x39\x00\x95\x02\x32\x00\x33\x00\xa1\x00\x18\x00\x19\x00\x9d\x02\x3a\x00\xa5\x02\xa7\x02\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\xee\x01\xa2\x00\xca\x00\xb3\x02\xa2\x01\xb4\x02\xa3\x00\xbc\x02\xbd\x02\x9e\x02\xce\x00\xcf\x00\x96\x02\x32\x00\x33\x00\xe5\x01\x62\x00\x63\x00\xd0\x01\xbf\x02\xa4\x00\xc0\x02\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x2a\x02\xce\x00\xcf\x00\x05\x03\xa6\x00\xa7\x00\xcf\x01\x62\x00\x63\x00\xd0\x01\x86\x00\xd1\x02\x97\x02\x32\x00\x33\x00\x66\x01\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\x86\x01\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\xcb\x00\xd6\x02\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd7\x02\xd2\x00\x62\x00\x63\x00\x64\x00\xd3\x00\x66\x00\x67\x00\x06\x00\x9c\x00\x07\x00\xda\x02\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x9c\x00\x39\x00\x26\x02\xa6\x00\xa7\x00\xdc\x02\x18\x00\x19\x00\x06\x00\x3a\x00\x07\x00\xdf\x02\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\xdf\x01\x39\x00\x23\x03\xa6\x00\xa7\x00\xe0\x01\x18\x00\x19\x00\x06\x00\x3a\x00\x07\x00\xe5\x01\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\xec\x01\x39\x00\x41\x02\x32\x00\x33\x00\xe4\x01\x18\x00\x19\x00\xee\x01\x3a\x00\xfb\x01\xfc\x01\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x86\x00\x12\x02\xe0\x00\x26\x02\xa6\x00\xa7\x00\xa2\x02\xa6\x00\xa7\x00\x2a\x02\xce\x00\xcf\x00\x52\x02\x32\x00\x33\x00\xcf\x01\x62\x00\x63\x00\xd0\x01\xa3\x02\xa6\x00\xa7\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x7d\x02\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\x26\x02\xa6\x00\xa7\x00\xb8\x02\x8c\x00\x6a\x00\x76\x01\x32\x00\x33\x00\xbd\x02\x8c\x00\x6a\x00\xc2\x02\x8c\x00\x6a\x00\xee\x01\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\xe1\x00\x19\x02\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\x3d\x00\xd2\x00\x62\x00\x63\x00\x64\x00\xe2\x00\x66\x00\x67\x00\x06\x00\x9c\x00\x07\x00\x20\x02\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\xee\x01\x39\x00\xc3\x02\x8c\x00\x6a\x00\x28\x02\x18\x00\x19\x00\x06\x00\x3a\x00\x07\x00\x29\x02\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x78\x01\x39\x00\xc4\x02\x8c\x00\x6a\x00\xee\x01\x18\x00\x19\x00\x06\x00\x3a\x00\x07\x00\x34\x02\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x86\x00\x39\x00\xf1\x00\x32\x00\x33\x00\xee\x01\x18\x00\x19\x00\x3a\x02\x3a\x00\x3b\x02\x3c\x02\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x40\x02\x92\x01\xcf\x00\x93\x01\xd1\x00\x9d\x02\x3d\x02\x92\x00\x63\x00\xe9\x01\x3e\x02\x2a\x00\x31\x00\x32\x00\x33\x00\xcf\x01\x62\x00\x63\x00\xd0\x01\xc8\x02\x8c\x00\x6a\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x7d\x02\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\xc9\x02\x8c\x00\x6a\x00\xbc\x01\x54\x02\x06\x00\x46\x02\x07\x00\x57\x02\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x55\x02\xea\x00\x56\x02\x79\x01\x95\x01\x6a\x00\x18\x00\x19\x00\xcd\x02\x8c\x00\x6a\x00\x58\x02\x59\x02\x06\x00\x9c\x00\x07\x00\x86\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x64\x02\x39\x00\xd8\x02\xa6\x00\xa7\x00\x66\x02\x18\x00\x19\x00\x06\x00\x3a\x00\x07\x00\x1b\x01\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x1a\x01\x39\x00\x85\x02\x4a\x02\x1c\x01\x1d\x01\x18\x00\x19\x00\x69\x02\x3a\x00\x06\x02\x6b\x01\xaa\x00\x5d\x01\x5e\x01\x4b\x02\x68\x01\x4f\x00\x86\x00\x50\x00\x4c\x02\x4d\x02\x07\x02\x53\x00\x4e\x02\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\xa5\x00\xa6\x00\xa7\x00\x74\x01\xd8\x00\xb9\x00\x5f\x00\xd9\x00\x78\x01\x7c\x01\x4f\x02\xe6\x01\xa6\x00\xa7\x00\xda\x00\x5d\x00\x5e\x00\x73\x01\xe7\x01\xa6\x00\xa7\x00\x7e\x01\x86\x00\x5f\x00\x3d\x00\x88\x01\xba\x00\x3d\x00\x3d\xfe\x06\x00\x6c\x00\x07\x00\x86\x01\xf4\x00\x09\x00\x0a\x00\x49\x01\xf7\x01\x62\x00\x63\x00\xd0\x01\x3d\xfe\x6d\x00\xe5\xff\x86\x01\x06\x00\x3d\xfe\x07\x00\x3d\x00\xf4\x00\x09\x00\x03\x01\xa5\x02\x9e\x01\x18\x00\x19\x00\x8e\x01\xce\x00\xcf\x00\x3d\x00\x3d\xfe\xaa\x00\x8f\x00\x62\x00\x63\x00\xd0\x01\x84\x00\xd7\x00\x86\x00\xc5\x01\x18\x00\x19\x00\x3f\x01\xcd\x01\x68\x00\xc3\x01\x6a\x00\x6e\x00\x6f\x00\x3d\x00\x70\x00\xcf\x01\x71\x00\x2a\x00\x86\x00\x72\x00\xda\x01\xff\xff\x73\x00\x8a\x00\x74\x00\x75\x00\x76\x00\xdd\x00\xa5\x00\xa6\x00\xa7\x00\x77\x00\x78\x00\x8b\x00\x79\x00\x88\x02\x86\x00\x7a\x00\x7b\x00\x8e\x00\x7c\x00\x7d\x00\x86\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\xe9\x00\x68\x00\x90\x01\x6a\x00\x3d\x00\xff\xff\x84\x00\x85\x00\x86\x00\x87\x00\x1b\x00\x0e\x02\x8c\x00\x6a\x00\x3f\xfe\xfb\xff\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\xea\x00\xed\x00\x23\x00\x26\x02\xa6\x00\xa7\x00\x06\x00\xf3\x00\x07\x00\xf1\x00\xf4\x00\x09\x00\x61\x02\x24\x00\xf4\x00\xcb\x00\xf8\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xfc\x00\xd2\x00\x62\x00\x63\x00\xd0\x01\xfd\x00\x3c\x00\x3d\x00\x18\x00\x19\x00\x25\x00\x3e\x00\x6f\x00\x3f\x00\x70\x00\x40\x00\x71\x00\x3d\xfe\x41\x00\x72\x00\x42\x00\x43\x00\x73\x00\xff\xff\x74\x00\x75\x00\x76\x00\x44\x00\x45\x00\x46\x00\x3d\xfe\x77\x00\x78\x00\xfe\x00\x79\x00\x3d\xfe\x47\x00\x7a\x00\x7b\x00\x26\x00\x7c\x00\x7d\x00\x48\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x3d\xfe\x49\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x4a\x00\x51\x02\x86\x00\x52\x02\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\x34\x02\x8c\x00\x6a\x00\xff\x00\x00\x01\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x06\x01\x6f\x00\x23\x00\xff\xff\x17\x01\x06\x00\xa1\x00\x07\x00\x1a\x01\xf4\x00\x09\x00\x0a\x00\x4a\x01\x24\x00\x75\x00\x6f\x01\x8c\x00\x6a\x00\x1b\x01\xa2\x00\x80\x01\x8c\x00\x6a\x00\x79\x00\xa3\x00\x81\x01\x8c\x00\x6a\x00\x1c\x01\x7c\x00\x18\x00\x19\x00\x7e\x00\x25\x00\x80\x00\xd7\xff\x1d\x01\xd7\xff\xa4\x00\xd7\xff\xd7\xff\x00\x00\xd7\xff\x00\x00\x00\x00\xd7\xff\x86\x00\xd7\xff\xd7\xff\xd7\xff\x8b\x01\xa6\x00\xa7\x00\xd7\xff\xd7\xff\xd7\xff\x00\x00\xd7\xff\xd7\xff\x00\x00\xd7\xff\xd7\xff\x26\x00\xd7\xff\xd7\xff\x00\x00\xd7\xff\xd7\xff\xd7\xff\xd7\xff\xd7\xff\xd7\xff\xd7\xff\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\xd7\xff\xd7\xff\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\xa5\x00\xa6\x00\xa7\x00\x00\x00\xae\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\xd1\x01\x62\x00\x63\x00\x64\x00\x00\x00\xd2\x01\x67\x00\x3e\x02\x00\x00\x4f\x00\x24\x00\x50\x00\xbf\x01\xc0\x01\x00\x00\x53\x00\xc1\x01\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x8b\x00\x8c\x00\x6a\x00\x25\x00\x00\x00\x6f\x00\x5f\x00\x70\x00\x00\x00\x71\x00\xc2\x01\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x75\x00\x76\x00\xa5\x00\xa6\x00\xa7\x00\x00\x00\x77\x00\x78\x00\x00\x00\x79\x00\xd3\x01\x6a\x00\x7a\x00\x7b\x00\x26\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x00\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x85\x00\x86\x00\x52\x02\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\xb4\x00\x8c\x00\x6a\x00\x00\x00\x59\x02\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x00\x00\x68\x00\xc3\x01\x6a\x00\x8d\x01\x47\x03\xaa\x00\x8d\x01\x09\x03\xaa\x00\x24\x00\x5a\x02\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\x8d\x01\xa2\x02\xaa\x00\x8d\x01\xa8\x02\xaa\x00\x00\x00\x00\x00\x92\x01\xcf\x00\x3d\x00\x00\x00\x00\x00\x25\x00\x92\x00\x63\x00\xe9\x01\x70\x00\x01\x02\x71\x00\xaa\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x00\x00\x76\x00\x02\x02\x8d\x01\xce\x01\xaa\x00\x77\x00\x78\x00\x68\x00\x5b\x02\x6a\x00\x00\x00\x7a\x00\x7b\x00\x26\x00\x8a\x02\x7d\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x81\x00\x82\x00\x83\x00\x00\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x85\x00\x86\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\x95\x01\x6a\x00\x00\x00\x3c\xfe\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x38\x01\x3c\xfe\x39\x01\x00\x00\x3a\x01\x3b\x01\x3c\xfe\x00\x00\x3c\x01\x3d\x01\x24\x00\x00\x00\xe1\x00\x00\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\x3c\xfe\xd2\x00\x62\x00\x63\x00\xd0\x01\x00\x00\x84\x00\x00\x00\x86\x00\x00\x00\x25\x00\x8d\x01\xeb\x01\xaa\x00\x70\x00\x65\x01\x71\x00\xaa\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x00\x00\x76\x00\x66\x01\x28\x01\x29\x01\x2a\x01\x77\x00\x78\x00\xa9\x00\xce\x01\xaa\x00\x00\x00\x7a\x00\x7b\x00\x26\x00\x00\x00\x7d\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x81\x00\x82\x00\x83\x00\x00\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x85\x00\x86\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\x28\x01\x29\x01\x2a\x01\x3c\xfe\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x00\x00\x3c\xfe\xae\x00\x00\x00\x00\x00\x00\x00\x3c\xfe\x2b\x02\xce\x00\xcf\x00\x24\x00\x00\x00\x00\x00\xd1\x01\x62\x00\x63\x00\xd0\x01\x00\x00\x00\x00\x06\x00\x3c\xfe\x07\x00\x00\x00\xf4\x00\x09\x00\x46\x01\x3c\x00\x3d\x00\x86\x00\x00\x00\x25\x00\x3e\x00\x00\x00\x3f\x00\x00\x00\x40\x00\x00\x00\x00\x00\x41\x00\x00\x00\x42\x00\x43\x00\x8e\x00\x00\x00\x18\x00\x19\x00\x00\x00\x44\x00\x45\x00\x46\x00\x00\x00\x00\x00\x8f\x00\x62\x00\x63\x00\x64\x00\x47\x00\x90\x00\x67\x00\x26\x00\x00\x00\x00\x00\x48\x00\x00\x00\x00\x00\x01\x02\x00\x00\xaa\x00\x06\x03\x6a\x00\x49\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x4a\x00\x4b\x00\x02\x02\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\xbb\x02\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x00\x91\x00\x6a\x00\x00\x00\x24\x00\x00\x00\x00\x00\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\x00\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x25\x00\x00\x00\x77\x00\x78\x00\x00\x00\x79\x00\x00\x00\xa1\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x9e\x00\x80\x00\x81\x00\x82\x00\x83\x00\xa2\x00\x65\x01\x00\x00\xaa\x00\x00\x00\xa3\x00\x84\x00\x9f\x00\x86\x00\x26\x00\x3c\xfe\x00\x00\x06\x00\x66\x01\x07\x00\x00\x00\xf4\x00\x09\x00\x47\x01\xa4\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x00\x00\x86\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\x00\x00\x00\x00\x18\x00\x19\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x16\x02\x00\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x24\x00\x74\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x00\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x00\x00\x7d\x00\x00\x00\x25\x00\xb3\x00\x00\x00\x81\x00\x82\x00\x83\x00\xa4\x00\xa1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x00\x86\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\xa2\x00\xaa\x00\x00\x00\x25\x02\x00\x00\xa3\x00\xa1\x02\x00\x00\x00\x00\x26\x00\x3d\xfe\x02\x02\x92\x00\x63\x00\x93\x00\x26\x02\x94\x00\x67\x00\xf7\x01\xa4\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x00\x00\x86\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\xaf\x01\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\xa1\x00\x06\x00\x00\x00\x07\x00\xa1\x00\x06\x01\x09\x00\xa1\x00\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x95\x00\x6a\x00\x00\x00\xa2\x00\xa3\x00\x00\x00\xa2\x00\x00\x00\xa3\x00\x00\x00\x00\x00\xa3\x00\x18\x00\x19\x00\x25\x00\x06\x00\x00\x00\x07\x00\xa4\x00\x08\x01\x09\x00\x3d\xfe\xa4\x00\x00\x00\x84\x00\xa4\x00\x86\x00\x00\x00\x84\x00\xd7\x00\x86\x00\x84\x00\xd7\x00\x86\x00\x3d\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x3d\xfe\x18\x00\x19\x00\x00\x00\x26\x00\xb0\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3d\xfe\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2f\x02\x86\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\x00\x00\x75\x02\x00\x00\xd6\x00\x76\x02\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x4b\x01\x1b\x00\x24\x00\x75\x02\x00\x00\x00\x00\x76\x02\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x18\x00\x19\x00\x77\x02\x66\x03\xa1\x00\x25\x00\x00\x00\x06\x00\x00\x00\x07\x00\x24\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x4d\x01\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x02\x34\x03\x00\x00\x25\x00\x00\x00\x18\x00\x19\x00\x26\x00\x00\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\xd7\x00\x86\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x4a\x00\x4b\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x26\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x51\x01\x27\x00\x28\x00\x29\x00\x2a\x00\x4a\x00\x4b\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\x18\x00\x19\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x11\x02\x00\x00\x00\x00\x23\x00\x00\x00\x92\x01\xcf\x00\x93\x01\xd1\x00\x22\x02\x00\x00\x92\x00\x63\x00\x93\x00\x24\x00\x94\x00\x67\x00\x06\x00\x1b\x00\x07\x00\x75\x02\x0b\x01\x09\x00\x76\x02\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3c\xfe\x18\x00\x19\x00\x24\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x48\x01\x00\x00\x3c\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x3c\xfe\x00\x00\x77\x02\x00\x00\x26\x00\x25\x00\x95\x01\x6a\x00\x00\x00\x65\x01\x00\x00\xaa\x00\x18\x00\x19\x00\x3c\xfe\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x66\x01\x86\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x26\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x52\x01\x27\x00\x28\x00\x29\x00\x2a\x00\x4a\x00\x4b\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\x18\x00\x19\x00\xa1\x00\x00\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\x00\x00\x00\x06\x00\x00\x00\x07\x00\x24\x00\xf4\x00\x09\x00\x03\x01\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x86\x00\x00\x00\x23\x00\x25\x00\x00\x00\x18\x00\x19\x00\x00\x00\x00\x00\x00\x00\xa1\x00\x00\x00\x06\x00\x24\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x4e\x01\x00\x00\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\x00\x00\x00\x77\x02\x00\x00\x26\x00\x25\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x00\x00\x00\x00\x00\x00\xa4\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x00\x00\xa2\x01\x00\x00\x00\x00\x00\x00\x26\x00\x9e\x02\xce\x00\xcf\x00\x9f\x02\xd1\x00\x00\x00\xe5\x01\x62\x00\x63\x00\xd0\x01\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\xcb\x01\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\xe6\x02\x00\x00\x00\x00\xcc\x01\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x4c\x01\x1b\x00\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x9c\x00\x00\x00\x23\x00\x18\x00\x19\x00\x00\x00\x00\x00\xa1\x00\x25\x00\x00\x00\x06\x00\x00\x00\x07\x00\x24\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x4f\x01\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x02\x00\x00\x00\x00\x25\x00\x00\x00\x18\x00\x19\x00\x26\x00\x00\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\x00\x00\x86\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x26\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x50\x01\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\x18\x00\x19\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x92\x01\xcf\x00\x93\x01\xd1\x00\x22\x02\x00\x00\x92\x00\x63\x00\xe9\x01\x00\x00\x24\x00\x1b\x00\x45\x01\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x63\x02\x00\x00\x06\x00\x25\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x2a\x01\x00\x00\x24\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x18\x00\x19\x00\x00\x00\x25\x00\x00\x00\x26\x00\x95\x01\x6a\x00\x00\x00\x00\x00\x24\x00\x00\x00\x00\x00\x59\x01\x00\x00\x00\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x25\x00\x00\x00\x26\x00\x00\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x0c\x01\x09\x00\x00\x00\x00\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x00\x00\x00\x00\x26\x00\x18\x00\x19\x00\x92\x01\xcf\x00\x93\x01\xd1\x00\x29\x02\x00\x00\x92\x00\x63\x00\xe9\x01\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x01\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x95\x01\x6a\x00\x23\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x24\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x25\x00\xd1\x02\x00\x00\x00\x00\x26\x00\x8e\x01\xce\x00\xcf\x00\x8f\x01\xd1\x00\x24\x00\x8f\x00\x62\x00\x63\x00\xd0\x01\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x26\x00\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x26\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x00\x90\x01\x6a\x00\x00\x00\x00\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x08\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x92\x01\xcf\x00\x93\x01\xd1\x00\x07\x03\x00\x00\x92\x00\x63\x00\xe9\x01\x0a\x01\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x24\x00\x00\x00\x00\x00\x00\x00\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x25\x00\x00\x00\x00\x00\x00\x00\x26\x00\x95\x01\x6a\x00\x00\x00\x00\x00\x00\x00\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x26\x00\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x65\x01\x00\x00\xaa\x00\x00\x00\x00\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x00\x00\x66\x01\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x26\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x6d\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x3d\xfe\x00\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x00\x00\x00\x00\x23\x00\x00\x00\x3d\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x3d\xfe\x00\x00\x00\x00\x00\x00\x24\x00\x6e\x00\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\x00\x00\x00\x00\x72\x00\x3d\xfe\x00\x00\x73\x00\x00\x00\x74\x00\x75\x00\x76\x00\x00\x00\x86\x00\x00\x00\x25\x00\x77\x00\x78\x00\x00\x00\x79\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x06\x02\x00\x00\xaa\x00\x00\x00\x00\x00\x00\x00\x84\x00\x85\x00\x86\x00\x87\x00\x26\x00\x00\x00\x07\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x2d\x01\x2e\x01\x2f\x01\x30\x01\x31\x01\x32\x01\x33\x01\x34\x01\x35\x01\x36\x01\x37\x01\x00\x00\x01\x02\x6f\x00\xaa\x00\x70\x00\x00\x00\x71\x00\x3d\xfe\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x02\x02\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\x3d\xfe\x77\x00\x78\x00\x00\x00\x79\x00\x3d\xfe\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x3d\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\x85\x00\x86\x00\x01\x02\x6f\x00\xaa\x00\x70\x00\x00\x00\x71\x00\x3d\xfe\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x02\x02\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\x3d\xfe\x77\x00\x78\x00\x00\x00\x79\x00\x3d\xfe\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x3d\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\x85\x00\x86\x00\x01\x02\x6f\x00\xaa\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x02\x02\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x79\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\xb3\x00\x80\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\xb4\x00\x86\x00\xcb\x01\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\xcc\x01\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x79\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\xdf\x00\x80\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\xe0\x00\x86\x00\xcb\x01\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\xcc\x01\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x79\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\xa6\x01\x80\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\xa7\x01\x86\x00\xcb\x01\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\xcc\x01\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x79\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\xb3\x00\x80\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\xb4\x00\x86\x00\xcb\x01\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\xcc\x01\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x79\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\xdf\x00\x80\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\xe0\x00\x86\x00\xcb\x01\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\xcc\x01\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x79\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\xa6\x01\x80\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\xa7\x01\x86\x00\xcb\x01\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\xcc\x01\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x79\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\xb3\x00\x80\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\xb4\x00\x86\x00\x65\x01\x6f\x00\xaa\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x66\x01\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x79\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\xdf\x00\x80\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\xe0\x00\x86\x00\x6c\x00\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\x3d\xfe\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\x3d\xfe\x77\x00\x78\x00\x00\x00\x79\x00\x3d\xfe\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x3d\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x00\x86\x00\x6c\x00\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x79\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\xa6\x01\x80\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\xa7\x01\x86\x00\x6c\x00\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x79\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\xb3\x00\x80\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\xb4\x00\x86\x00\x06\x02\x6f\x00\xaa\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x07\x02\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x79\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\xdf\x00\x80\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\xe0\x00\x86\x00\x65\x01\x6f\x00\xaa\x00\x70\x00\x00\x00\x71\x00\x00\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x66\x01\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\x00\x00\x79\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x9e\x00\x80\x00\x81\x00\x82\x00\x83\x00\x00\x00\xcb\x01\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\x9f\x00\x86\x00\x00\x00\x6f\x00\x00\x00\x70\x00\xcc\x01\x71\x00\x00\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\x00\x00\x79\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x9e\x00\x80\x00\x81\x00\x82\x00\x83\x00\x00\x00\x6c\x00\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\x9f\x00\x86\x00\x72\x00\x00\x00\x00\x00\x73\x00\x6d\x00\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\x00\x00\x79\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x9e\x00\x80\x00\x81\x00\x82\x00\x83\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x00\x00\x00\x84\x00\x9f\x00\x86\x00\x00\x00\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\x00\x00\x6d\x00\x72\x00\x00\x00\xcb\x01\x73\x00\x00\x00\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\xcc\x01\x79\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x9e\x00\x80\x00\x81\x00\x82\x00\x83\x00\x01\x02\xfb\x02\xaa\x00\x00\x00\x00\x00\x00\x00\x84\x00\x9f\x00\x86\x00\x00\x00\xa1\x00\x00\x00\x02\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\xa2\x00\x71\x00\x00\x00\x00\x00\x72\x00\xa3\x00\x00\x00\x73\x00\x00\x00\x74\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\x00\x00\xa4\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x84\x00\x7d\x00\x86\x00\x00\x00\x9e\x00\x3d\xfe\x81\x00\x82\x00\x83\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\x9f\x00\x86\x00\x3d\xfe\x00\x00\x00\x00\xb0\x01\xb1\x01\x3d\xfe\x53\x00\xb2\x01\x55\x00\x56\x00\x57\x00\xb3\x01\xb4\x01\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x00\x00\x3d\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x84\x00\x00\x00\x86\x00\xb5\x01\x00\x00\x00\x00\x00\x00\x00\x00\x92\x01\xcf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\x00\x63\x00\xe9\x01\x00\x00\x00\x00\x00\x00\xb6\x01\xb7\x01\xb8\x01\x00\x00\x00\x00\x00\x00\x5c\x02\xa6\x00\xa7\x00\x5d\x02\x5e\x02\x00\x00\x00\x00\x00\x00\xb0\x01\xb1\x01\x00\x00\x53\x00\xb2\x01\x55\x00\x56\x00\x57\x00\xb3\x01\xb4\x01\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x00\x00\x92\x01\xcf\x00\x93\x01\xd1\x00\x29\x02\x5f\x00\x92\x00\x63\x00\x93\x00\xb5\x01\x94\x00\x67\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x00\xc7\x02\x6a\x00\x92\x00\x63\x00\xe9\x01\x00\x00\x00\x00\x00\x00\xb6\x01\xb7\x01\xb8\x01\x00\x00\x00\x00\x00\x00\x5c\x02\xa6\x00\xa7\x00\x5d\x02\x5e\x02\xb0\x01\xb1\x01\x00\x00\x53\x00\xb2\x01\x55\x00\x56\x00\x57\x00\xb3\x01\xb4\x01\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x95\x01\x6a\x00\xb5\x01\x92\x01\xcf\x00\x93\x01\xd1\x00\x94\x01\x00\x00\x92\x00\x63\x00\xe9\x01\x00\x00\x68\x00\xcc\x02\x6a\x00\x00\x00\x00\x00\x00\x00\xb6\x01\xb7\x01\xb8\x01\x00\x00\x00\x00\x00\x00\x5c\x02\xa6\x00\xa7\x00\x5d\x02\x5e\x02\xb0\x01\xb1\x01\x00\x00\x53\x00\xb2\x01\x55\x00\x56\x00\x57\x00\xb3\x01\xb4\x01\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x00\x00\x92\x01\xcf\x00\x93\x01\xd1\x00\x94\x01\x5f\x00\x92\x00\x63\x00\x93\x00\xb5\x01\x94\x00\x67\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\x01\x6a\x00\x00\x00\x68\x00\x5f\x02\x6a\x00\x00\x00\x00\x00\x00\x00\xb6\x01\xb7\x01\xb8\x01\xb9\x01\x00\x00\x00\x00\x00\x00\x00\x00\xb0\x01\xb1\x01\x00\x00\x53\x00\xb2\x01\x55\x00\x56\x00\x57\x00\xb3\x01\xb4\x01\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x00\x00\x00\x00\xb5\x01\x95\x01\x6a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x00\xba\x01\x6a\x00\xb6\x01\xb7\x01\xb8\x01\x00\x00\x00\x00\x00\x00\xb0\x01\xb1\x01\x00\x00\x53\x00\xb2\x01\x55\x00\x56\x00\x57\x00\xb3\x01\xb4\x01\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x00\x00\xd8\x00\xb9\x00\x00\x00\xd9\x00\x00\x00\x5f\x00\x00\x00\x00\x00\x00\x00\xb5\x01\xda\x00\x5d\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x00\x00\xab\x00\xba\x00\xac\x00\x00\x00\x68\x00\xba\x01\x6a\x00\xce\x02\x00\x00\xad\x00\x5d\x00\x5e\x00\x07\x02\x62\x00\x63\x00\xd0\x01\x00\x00\x00\x00\x5f\x00\x00\x00\x00\x00\xae\x00\x00\x00\x00\x00\x08\x02\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\x00\x00\x00\x00\xfc\x01\x62\x00\x63\x00\xd0\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd\x01\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\x00\x00\x00\x00\x68\x00\xba\x01\x6a\x00\x00\x00\x97\x00\x00\x00\x98\x00\x00\x00\xab\x00\x00\x00\xac\x00\x00\x00\x00\x00\x99\x00\x5d\x00\x5e\x00\xdd\x00\xad\x00\x5d\x00\x5e\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x00\x00\xae\x00\x00\x00\x23\x02\xcf\x00\x00\x00\x00\x00\xfe\x01\xff\x01\xc8\x01\x63\x00\xc9\x01\xf2\x01\x62\x00\x63\x00\xd0\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x02\xa6\x00\xa7\x00\x78\x02\x79\x02\x97\x00\x00\x00\x98\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\x00\x5d\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x9f\x01\x00\x00\xa0\x01\x00\x00\x00\x00\x00\x00\x97\x00\x00\x00\x98\x00\xa1\x01\x5d\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x99\x00\x5d\x00\x5e\x00\x5f\x00\x9c\x00\x00\x00\xa2\x01\xf3\x01\x6a\x00\x5f\x00\x00\x00\x77\x02\xa6\x00\xa7\x00\x78\x02\x79\x02\x00\x00\xd4\x02\x62\x00\x63\x00\xd0\x01\x00\x00\x00\x00\xf1\x01\x62\x00\x63\x00\xd0\x01\x0e\x01\x55\x00\x00\x00\x0f\x01\x00\x00\x10\x01\x00\x00\x11\x01\x5c\x00\x5d\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x01\x55\x00\x5f\x00\x0f\x01\x00\x00\x10\x01\x12\x01\x11\x01\x5c\x00\x5d\x00\x5e\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x00\x00\x00\x00\x12\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb6\x02\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x00\x00\x06\x00\x81\x02\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\xb7\x02\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x00\x00\x00\x00\x68\x00\x15\x01\x6a\x00\x0e\x01\x55\x00\x00\x00\x0f\x01\x00\x00\x10\x01\x00\x00\x11\x01\x5c\x00\x5d\x00\x5e\x00\x00\x00\x68\x00\x15\x01\x6a\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x00\x00\x00\x00\x12\x01\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x55\x01\x0e\x01\x55\x00\x00\x00\x0f\x01\x00\x00\x10\x01\xef\x01\x11\x01\x5c\x00\x5d\x00\x5e\x00\x18\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x00\x00\x06\x00\x12\x01\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\xf0\x01\x00\x00\x1c\x02\x00\x00\x00\x00\x18\x00\x19\x00\x00\x00\x00\x00\x68\x00\x15\x01\x6a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x1d\x02\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x00\x00\x00\x00\x68\x00\x15\x01\x6a\x00\x0e\x01\x55\x00\x00\x00\x0f\x01\x00\x00\x10\x01\x00\x00\x11\x01\x5c\x00\x5d\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x00\x00\x00\x00\x12\x01\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x54\x01\x00\x00\x0e\x01\x55\x00\x00\x00\x0f\x01\x00\x00\x10\x01\x31\x02\x11\x01\x5c\x00\x5d\x00\x5e\x00\x18\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x00\x00\x06\x00\x12\x01\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x32\x02\x00\x00\xd7\x01\x00\x00\x00\x00\x18\x00\x19\x00\x00\x00\x00\x00\x68\x00\x15\x01\x6a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\xd8\x01\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x00\x00\x00\x00\x68\x00\x15\x01\x6a\x00\xa9\x02\x55\x00\x00\x00\x0f\x01\x00\x00\x10\x01\x00\x00\x11\x01\x5c\x00\x5d\x00\x5e\x00\x00\x00\xf7\x02\xab\x02\xac\x02\xa9\x02\x55\x00\x5f\x00\x0f\x01\x00\x00\x10\x01\xad\x02\x11\x01\x5c\x00\x5d\x00\x5e\x00\x00\x00\xaa\x02\xab\x02\xac\x02\x0e\x01\x55\x00\x5f\x00\x0f\x01\x00\x00\x10\x01\xad\x02\x11\x01\x5c\x00\x5d\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x0e\x01\x55\x00\x12\x01\x0f\x01\x00\x00\x10\x01\x00\x00\x11\x01\x5c\x00\x5d\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x00\x00\x00\x00\x12\x01\x00\x00\x84\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x00\xae\x02\x6a\x00\x00\x00\x0e\x01\x55\x00\x6d\x01\x0f\x01\x00\x00\x10\x01\x00\x00\x11\x01\x5c\x00\x5d\x00\x5e\x00\x68\x00\xae\x02\x6a\x00\x00\x00\xac\x00\x00\x00\x5f\x00\x00\x00\x00\x00\x00\x00\x12\x01\xad\x00\x5d\x00\x5e\x00\xae\x00\x68\x00\x15\x01\x6a\x00\x00\x00\x00\x00\x5f\x00\x00\x00\x00\x00\xae\x00\x00\x00\xd1\x01\x62\x00\x63\x00\xd0\x01\x00\x00\x00\x00\x6e\x01\x00\x00\x00\x00\x68\x00\x15\x01\x6a\x00\x7e\x02\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\x00\x00\x00\x00\x00\x00\x5e\x01\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\x98\x00\x00\x00\x00\x00\xae\x00\x00\x00\x00\x00\x00\x00\x99\x00\x5d\x00\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x02\x5f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x00\x15\x01\x6a\x00\x00\x00\x00\x00\x7f\x02\xec\x02\x6a\x00\xf9\x02\x62\x00\x63\x00\xd0\x01\x00\x00\x00\x00\x00\x00\x62\x01\x63\x01\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\xab\x01\xa2\x01\x00\x00\x00\x00\x00\x00\x12\x02\x00\x00\x18\x00\x19\x00\x00\x00\x8d\x01\x13\x02\x14\x02\x6a\x00\x8e\x01\xce\x00\xcf\x00\x8f\x01\xd1\x00\x00\x00\x8f\x00\x62\x00\x63\x00\x64\x00\x00\x00\x90\x00\x67\x00\x00\x00\x00\x00\x9c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\xab\x01\xaa\x01\x00\x00\x00\x00\xae\x00\xb9\x02\x00\x00\x18\x00\x19\x00\x2b\x02\xce\x00\xcf\x00\x00\x00\x9c\x00\x00\x00\xd1\x01\x62\x00\x63\x00\xd0\x01\x68\x00\x90\x01\x6a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7e\x02\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\xab\x01\x00\x00\x00\x00\x00\x00\x00\x00\xac\x01\x00\x00\x18\x00\x19\x00\x00\x00\x00\x00\x68\x00\xad\x01\x6a\x00\xc5\x02\x7f\x02\xed\x02\x6a\x00\x8e\x01\xce\x00\xcf\x00\xca\x02\x9f\x00\x00\x00\x8f\x00\x62\x00\x63\x00\xd0\x01\x00\x00\x00\x00\x00\x00\x8f\x00\x62\x00\x63\x00\xd0\x01\x00\x00\x5a\x02\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\x00\x00\x5a\x02\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\xc0\x02\x00\x00\x68\x00\xc6\x02\x6a\x00\x00\x00\x00\x00\x18\x00\x19\x00\x68\x00\xcb\x02\x6a\x00\xb0\x02\x00\x00\x05\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x71\x00\x00\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x00\x00\x7d\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x81\x00\x82\x00\x83\x00\x00\x00\x00\x00\xb0\x02\x00\x00\xb1\x02\x00\x00\x00\x00\x85\x00\x86\x00\xb2\x02\x70\x00\x00\x00\x71\x00\x00\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x00\x00\x7d\x00\x00\x00\xc0\x00\x7f\x00\x00\x00\x81\x00\x82\x00\x83\x00\x6f\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\x00\x00\x00\x85\x00\x86\x00\xb2\x02\xc3\x00\x00\x00\x00\x00\x75\x00\x00\x00\x00\x00\x6f\x00\x00\x00\xa2\x00\x00\x00\x00\x00\xa1\x00\x79\x00\xa3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x00\x75\x00\x00\x00\x7e\x00\x00\x00\x80\x00\xa2\x00\x00\x00\x00\x00\xa4\x00\x79\x00\xa3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x00\x86\x00\x00\x00\x7e\x00\x00\x00\x80\x00\x3d\x00\x00\x00\x00\x00\xa4\x00\x00\x00\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\x00\x00\x86\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\x00\x00\x79\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x02\x85\x00\x86\x00\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\x00\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\x00\x00\x79\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x00\x86\x00\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\x3d\xfe\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\x3d\xfe\x77\x00\x78\x00\x00\x00\x79\x00\x3d\xfe\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x3d\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x01\x85\x00\x86\x00\x3b\xfe\x00\x00\x3b\xfe\x00\x00\x3b\xfe\x3b\xfe\x00\x00\x3b\xfe\x00\x00\x00\x00\x3b\xfe\x00\x00\x3b\xfe\x3b\xfe\x3b\xfe\x00\x00\x00\x00\x00\x00\x3b\xfe\x3b\xfe\x3b\xfe\x00\x00\x3b\xfe\x3b\xfe\x00\x00\x3b\xfe\x3b\xfe\x00\x00\x3b\xfe\x3b\xfe\x00\x00\x3b\xfe\x3b\xfe\x3b\xfe\x3b\xfe\x3b\xfe\x3b\xfe\x3b\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3b\xfe\x3b\xfe\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x79\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\xa6\x01\x80\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x01\x86\x00\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\x3d\xfe\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\x3d\xfe\x77\x00\x78\x00\x00\x00\x79\x00\x3d\xfe\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x3d\xfe\x00\x00\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\x85\x00\x86\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\x00\x00\x79\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x9e\x00\x80\x00\x81\x00\x82\x00\x83\x00\x00\x00\x00\x00\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\x9f\x00\x86\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\x00\x00\x79\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x7d\x00\x00\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x00\x86\x00\x6f\x00\x00\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x00\x00\x75\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x79\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x7c\x00\x00\x00\x00\x00\x7e\x00\x00\x00\x80\x00\x00\x00\x82\x00\x83\x00\xa4\x00\x70\x00\x00\x00\x71\x00\x00\x00\x00\x00\x72\x00\x00\x00\x86\x00\x73\x00\x00\x00\x74\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x00\x00\x7d\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x81\x00\x82\x00\x83\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x00\x86\x00\xb2\x02\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x00\x00\x00\x00\x73\x00\x00\x00\x74\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x00\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x00\x00\x7d\x00\x00\x00\x00\x00\xa6\x01\x00\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\xa7\x01\x86\x00\x73\x00\x00\x00\x74\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x00\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x00\x00\x7d\x00\x00\x00\x00\x00\xb3\x00\x00\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x3b\xfe\x00\x00\x3b\xfe\x3b\xfe\x00\x00\x3b\xfe\xb4\x00\x86\x00\x3b\xfe\x00\x00\x3b\xfe\x00\x00\x3b\xfe\x00\x00\x00\x00\x00\x00\x3b\xfe\x3b\xfe\x3b\xfe\x00\x00\x00\x00\x3b\xfe\x00\x00\x3b\xfe\x3b\xfe\x00\x00\x00\x00\x3b\xfe\x00\x00\x00\x00\x3b\xfe\x00\x00\x3b\xfe\x3b\xfe\x3b\xfe\x3b\xfe\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x3b\xfe\x3b\xfe\x73\x00\x00\x00\x74\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x00\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x00\x00\x7d\x00\x00\x00\x00\x00\xa6\x01\x00\x00\x81\x00\x82\x00\x83\x00\xa4\x00\x70\x00\x00\x00\x71\x00\x00\x00\x00\x00\x72\x00\xa7\x01\x86\x00\x73\x00\x00\x00\x74\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x00\x00\x7d\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x81\x00\x82\x00\x83\x00\x00\x00\x70\x00\x00\x00\x71\x00\x00\x00\x00\x00\x72\x00\x85\x00\x86\x00\x73\x00\x00\x00\x74\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x00\x00\x7d\x00\x00\x00\x00\x00\x9e\x00\x00\x00\x81\x00\x82\x00\x83\x00\x00\x00\x70\x00\x00\x00\x71\x00\x00\x00\x00\x00\x72\x00\x9f\x00\x86\x00\x73\x00\x00\x00\x74\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x77\x00\x78\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x00\x00\x7d\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x81\x00\x82\x00\x83\x00\x00\x00\x70\x00\x00\x00\x71\x00\xa1\x00\x00\x00\x72\x00\x85\x00\x86\x00\x73\x00\x00\x00\x00\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\xa2\x00\x77\x00\x78\x00\x00\x00\x00\x00\xa3\x00\x00\x00\x7a\x00\x7b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x00\x83\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x02\x86\x00\x27\x03\x6e\x02\x6f\x02\x70\x02\x71\x02\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x72\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x6c\x02\x73\x02\x6d\x02\x6e\x02\x6f\x02\x70\x02\x71\x02\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x72\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x31\x03\x73\x02\x00\x00\x32\x03\x6f\x02\x70\x02\x71\x02\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x72\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x73\x02\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\xf5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\x02\x18\x00\x19\x00\x00\x00\x67\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x02\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x72\x02\x00\x00\x2e\x03\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x72\x02\x00\x00\xd7\x02\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x72\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\xab\x01\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x02\x00\x00\x18\x00\x19\x00\x00\x00\x06\x00\x00\x00\x07\x00\x9c\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\xea\x00\x00\x00\x43\x03\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\xea\x00\x00\x00\x44\x03\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\xea\x00\x00\x00\x93\x02\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\xea\x00\x00\x00\x94\x02\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\xea\x00\x00\x00\xeb\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x77\x03\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x78\x03\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x61\x03\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x3a\x03\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x92\x02\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x41\x01\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x42\x01\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x43\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x57\x01\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x5a\x01\x00\x00\x00\x00\x5b\x01\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x7a\x01\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x7c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x7e\x01\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x7f\x01\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\xf5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x56\x03\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\xf5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x03\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\xf5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5b\x03\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\xf5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x66\x03\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\xf5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x47\x03\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\xf5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4d\x03\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x51\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\xf5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x02\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\xee\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\xf5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x29\x03\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x69\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x6b\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\xf5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x02\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x45\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x6c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\xf5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x6a\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x64\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x59\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x56\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x06\x00\x00\x00\x07\x00\x00\x00\xf4\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x53\x01\x02\x02\xce\x00\xcf\x00\x00\x00\x00\x00\x00\x00\x03\x02\x62\x00\x63\x00\xd0\x01\x00\x00\x00\x00\x00\x00\x18\x00\x19\x00\x00\x00\x00\x00\x00\x00\x04\x02\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\x09\x02\xce\x00\xcf\x00\x00\x00\x00\x00\x00\x00\x0a\x02\x62\x00\x63\x00\xd0\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x59\x03\x0b\x02\x5f\x01\xa6\x00\xa7\x00\x60\x01\x61\x01\x02\x03\x00\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\x01\x03\xf4\x01\x62\x00\x63\x00\xd0\x01\x00\x00\x00\x00\x02\x03\x00\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\x00\x00\xf4\x01\x62\x00\x63\x00\xd0\x01\xcb\x00\x00\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\x00\x00\xf4\x01\x62\x00\x63\x00\xd0\x01\xe1\x00\x00\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\x00\x00\xf4\x01\x62\x00\x63\x00\xd0\x01\x37\x02\x00\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\x00\x00\xf4\x01\x62\x00\x63\x00\xd0\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# happyReduceArr = array (4, 463) [ (4 , happyReduce_4), (5 , happyReduce_5), (6 , happyReduce_6), (7 , happyReduce_7), (8 , happyReduce_8), (9 , happyReduce_9), (10 , happyReduce_10), (11 , happyReduce_11), (12 , happyReduce_12), (13 , happyReduce_13), (14 , happyReduce_14), (15 , happyReduce_15), (16 , happyReduce_16), (17 , happyReduce_17), (18 , happyReduce_18), (19 , happyReduce_19), (20 , happyReduce_20), (21 , happyReduce_21), (22 , happyReduce_22), (23 , happyReduce_23), (24 , happyReduce_24), (25 , happyReduce_25), (26 , happyReduce_26), (27 , happyReduce_27), (28 , happyReduce_28), (29 , happyReduce_29), (30 , happyReduce_30), (31 , happyReduce_31), (32 , happyReduce_32), (33 , happyReduce_33), (34 , happyReduce_34), (35 , happyReduce_35), (36 , happyReduce_36), (37 , happyReduce_37), (38 , happyReduce_38), (39 , happyReduce_39), (40 , happyReduce_40), (41 , happyReduce_41), (42 , happyReduce_42), (43 , happyReduce_43), (44 , happyReduce_44), (45 , happyReduce_45), (46 , happyReduce_46), (47 , happyReduce_47), (48 , happyReduce_48), (49 , happyReduce_49), (50 , happyReduce_50), (51 , happyReduce_51), (52 , happyReduce_52), (53 , happyReduce_53), (54 , happyReduce_54), (55 , happyReduce_55), (56 , happyReduce_56), (57 , happyReduce_57), (58 , happyReduce_58), (59 , happyReduce_59), (60 , happyReduce_60), (61 , happyReduce_61), (62 , happyReduce_62), (63 , happyReduce_63), (64 , happyReduce_64), (65 , happyReduce_65), (66 , happyReduce_66), (67 , happyReduce_67), (68 , happyReduce_68), (69 , happyReduce_69), (70 , happyReduce_70), (71 , happyReduce_71), (72 , happyReduce_72), (73 , happyReduce_73), (74 , happyReduce_74), (75 , happyReduce_75), (76 , happyReduce_76), (77 , happyReduce_77), (78 , happyReduce_78), (79 , happyReduce_79), (80 , happyReduce_80), (81 , happyReduce_81), (82 , happyReduce_82), (83 , happyReduce_83), (84 , happyReduce_84), (85 , happyReduce_85), (86 , happyReduce_86), (87 , happyReduce_87), (88 , happyReduce_88), (89 , happyReduce_89), (90 , happyReduce_90), (91 , happyReduce_91), (92 , happyReduce_92), (93 , happyReduce_93), (94 , happyReduce_94), (95 , happyReduce_95), (96 , happyReduce_96), (97 , happyReduce_97), (98 , happyReduce_98), (99 , happyReduce_99), (100 , happyReduce_100), (101 , happyReduce_101), (102 , happyReduce_102), (103 , happyReduce_103), (104 , happyReduce_104), (105 , happyReduce_105), (106 , happyReduce_106), (107 , happyReduce_107), (108 , happyReduce_108), (109 , happyReduce_109), (110 , happyReduce_110), (111 , happyReduce_111), (112 , happyReduce_112), (113 , happyReduce_113), (114 , happyReduce_114), (115 , happyReduce_115), (116 , happyReduce_116), (117 , happyReduce_117), (118 , happyReduce_118), (119 , happyReduce_119), (120 , happyReduce_120), (121 , happyReduce_121), (122 , happyReduce_122), (123 , happyReduce_123), (124 , happyReduce_124), (125 , happyReduce_125), (126 , happyReduce_126), (127 , happyReduce_127), (128 , happyReduce_128), (129 , happyReduce_129), (130 , happyReduce_130), (131 , happyReduce_131), (132 , happyReduce_132), (133 , happyReduce_133), (134 , happyReduce_134), (135 , happyReduce_135), (136 , happyReduce_136), (137 , happyReduce_137), (138 , happyReduce_138), (139 , happyReduce_139), (140 , happyReduce_140), (141 , happyReduce_141), (142 , happyReduce_142), (143 , happyReduce_143), (144 , happyReduce_144), (145 , happyReduce_145), (146 , happyReduce_146), (147 , happyReduce_147), (148 , happyReduce_148), (149 , happyReduce_149), (150 , happyReduce_150), (151 , happyReduce_151), (152 , happyReduce_152), (153 , happyReduce_153), (154 , happyReduce_154), (155 , happyReduce_155), (156 , happyReduce_156), (157 , happyReduce_157), (158 , happyReduce_158), (159 , happyReduce_159), (160 , happyReduce_160), (161 , happyReduce_161), (162 , happyReduce_162), (163 , happyReduce_163), (164 , happyReduce_164), (165 , happyReduce_165), (166 , happyReduce_166), (167 , happyReduce_167), (168 , happyReduce_168), (169 , happyReduce_169), (170 , happyReduce_170), (171 , happyReduce_171), (172 , happyReduce_172), (173 , happyReduce_173), (174 , happyReduce_174), (175 , happyReduce_175), (176 , happyReduce_176), (177 , happyReduce_177), (178 , happyReduce_178), (179 , happyReduce_179), (180 , happyReduce_180), (181 , happyReduce_181), (182 , happyReduce_182), (183 , happyReduce_183), (184 , happyReduce_184), (185 , happyReduce_185), (186 , happyReduce_186), (187 , happyReduce_187), (188 , happyReduce_188), (189 , happyReduce_189), (190 , happyReduce_190), (191 , happyReduce_191), (192 , happyReduce_192), (193 , happyReduce_193), (194 , happyReduce_194), (195 , happyReduce_195), (196 , happyReduce_196), (197 , happyReduce_197), (198 , happyReduce_198), (199 , happyReduce_199), (200 , happyReduce_200), (201 , happyReduce_201), (202 , happyReduce_202), (203 , happyReduce_203), (204 , happyReduce_204), (205 , happyReduce_205), (206 , happyReduce_206), (207 , happyReduce_207), (208 , happyReduce_208), (209 , happyReduce_209), (210 , happyReduce_210), (211 , happyReduce_211), (212 , happyReduce_212), (213 , happyReduce_213), (214 , happyReduce_214), (215 , happyReduce_215), (216 , happyReduce_216), (217 , happyReduce_217), (218 , happyReduce_218), (219 , happyReduce_219), (220 , happyReduce_220), (221 , happyReduce_221), (222 , happyReduce_222), (223 , happyReduce_223), (224 , happyReduce_224), (225 , happyReduce_225), (226 , happyReduce_226), (227 , happyReduce_227), (228 , happyReduce_228), (229 , happyReduce_229), (230 , happyReduce_230), (231 , happyReduce_231), (232 , happyReduce_232), (233 , happyReduce_233), (234 , happyReduce_234), (235 , happyReduce_235), (236 , happyReduce_236), (237 , happyReduce_237), (238 , happyReduce_238), (239 , happyReduce_239), (240 , happyReduce_240), (241 , happyReduce_241), (242 , happyReduce_242), (243 , happyReduce_243), (244 , happyReduce_244), (245 , happyReduce_245), (246 , happyReduce_246), (247 , happyReduce_247), (248 , happyReduce_248), (249 , happyReduce_249), (250 , happyReduce_250), (251 , happyReduce_251), (252 , happyReduce_252), (253 , happyReduce_253), (254 , happyReduce_254), (255 , happyReduce_255), (256 , happyReduce_256), (257 , happyReduce_257), (258 , happyReduce_258), (259 , happyReduce_259), (260 , happyReduce_260), (261 , happyReduce_261), (262 , happyReduce_262), (263 , happyReduce_263), (264 , happyReduce_264), (265 , happyReduce_265), (266 , happyReduce_266), (267 , happyReduce_267), (268 , happyReduce_268), (269 , happyReduce_269), (270 , happyReduce_270), (271 , happyReduce_271), (272 , happyReduce_272), (273 , happyReduce_273), (274 , happyReduce_274), (275 , happyReduce_275), (276 , happyReduce_276), (277 , happyReduce_277), (278 , happyReduce_278), (279 , happyReduce_279), (280 , happyReduce_280), (281 , happyReduce_281), (282 , happyReduce_282), (283 , happyReduce_283), (284 , happyReduce_284), (285 , happyReduce_285), (286 , happyReduce_286), (287 , happyReduce_287), (288 , happyReduce_288), (289 , happyReduce_289), (290 , happyReduce_290), (291 , happyReduce_291), (292 , happyReduce_292), (293 , happyReduce_293), (294 , happyReduce_294), (295 , happyReduce_295), (296 , happyReduce_296), (297 , happyReduce_297), (298 , happyReduce_298), (299 , happyReduce_299), (300 , happyReduce_300), (301 , happyReduce_301), (302 , happyReduce_302), (303 , happyReduce_303), (304 , happyReduce_304), (305 , happyReduce_305), (306 , happyReduce_306), (307 , happyReduce_307), (308 , happyReduce_308), (309 , happyReduce_309), (310 , happyReduce_310), (311 , happyReduce_311), (312 , happyReduce_312), (313 , happyReduce_313), (314 , happyReduce_314), (315 , happyReduce_315), (316 , happyReduce_316), (317 , happyReduce_317), (318 , happyReduce_318), (319 , happyReduce_319), (320 , happyReduce_320), (321 , happyReduce_321), (322 , happyReduce_322), (323 , happyReduce_323), (324 , happyReduce_324), (325 , happyReduce_325), (326 , happyReduce_326), (327 , happyReduce_327), (328 , happyReduce_328), (329 , happyReduce_329), (330 , happyReduce_330), (331 , happyReduce_331), (332 , happyReduce_332), (333 , happyReduce_333), (334 , happyReduce_334), (335 , happyReduce_335), (336 , happyReduce_336), (337 , happyReduce_337), (338 , happyReduce_338), (339 , happyReduce_339), (340 , happyReduce_340), (341 , happyReduce_341), (342 , happyReduce_342), (343 , happyReduce_343), (344 , happyReduce_344), (345 , happyReduce_345), (346 , happyReduce_346), (347 , happyReduce_347), (348 , happyReduce_348), (349 , happyReduce_349), (350 , happyReduce_350), (351 , happyReduce_351), (352 , happyReduce_352), (353 , happyReduce_353), (354 , happyReduce_354), (355 , happyReduce_355), (356 , happyReduce_356), (357 , happyReduce_357), (358 , happyReduce_358), (359 , happyReduce_359), (360 , happyReduce_360), (361 , happyReduce_361), (362 , happyReduce_362), (363 , happyReduce_363), (364 , happyReduce_364), (365 , happyReduce_365), (366 , happyReduce_366), (367 , happyReduce_367), (368 , happyReduce_368), (369 , happyReduce_369), (370 , happyReduce_370), (371 , happyReduce_371), (372 , happyReduce_372), (373 , happyReduce_373), (374 , happyReduce_374), (375 , happyReduce_375), (376 , happyReduce_376), (377 , happyReduce_377), (378 , happyReduce_378), (379 , happyReduce_379), (380 , happyReduce_380), (381 , happyReduce_381), (382 , happyReduce_382), (383 , happyReduce_383), (384 , happyReduce_384), (385 , happyReduce_385), (386 , happyReduce_386), (387 , happyReduce_387), (388 , happyReduce_388), (389 , happyReduce_389), (390 , happyReduce_390), (391 , happyReduce_391), (392 , happyReduce_392), (393 , happyReduce_393), (394 , happyReduce_394), (395 , happyReduce_395), (396 , happyReduce_396), (397 , happyReduce_397), (398 , happyReduce_398), (399 , happyReduce_399), (400 , happyReduce_400), (401 , happyReduce_401), (402 , happyReduce_402), (403 , happyReduce_403), (404 , happyReduce_404), (405 , happyReduce_405), (406 , happyReduce_406), (407 , happyReduce_407), (408 , happyReduce_408), (409 , happyReduce_409), (410 , happyReduce_410), (411 , happyReduce_411), (412 , happyReduce_412), (413 , happyReduce_413), (414 , happyReduce_414), (415 , happyReduce_415), (416 , happyReduce_416), (417 , happyReduce_417), (418 , happyReduce_418), (419 , happyReduce_419), (420 , happyReduce_420), (421 , happyReduce_421), (422 , happyReduce_422), (423 , happyReduce_423), (424 , happyReduce_424), (425 , happyReduce_425), (426 , happyReduce_426), (427 , happyReduce_427), (428 , happyReduce_428), (429 , happyReduce_429), (430 , happyReduce_430), (431 , happyReduce_431), (432 , happyReduce_432), (433 , happyReduce_433), (434 , happyReduce_434), (435 , happyReduce_435), (436 , happyReduce_436), (437 , happyReduce_437), (438 , happyReduce_438), (439 , happyReduce_439), (440 , happyReduce_440), (441 , happyReduce_441), (442 , happyReduce_442), (443 , happyReduce_443), (444 , happyReduce_444), (445 , happyReduce_445), (446 , happyReduce_446), (447 , happyReduce_447), (448 , happyReduce_448), (449 , happyReduce_449), (450 , happyReduce_450), (451 , happyReduce_451), (452 , happyReduce_452), (453 , happyReduce_453), (454 , happyReduce_454), (455 , happyReduce_455), (456 , happyReduce_456), (457 , happyReduce_457), (458 , happyReduce_458), (459 , happyReduce_459), (460 , happyReduce_460), (461 , happyReduce_461), (462 , happyReduce_462), (463 , happyReduce_463) ] happy_n_terms = 102 :: Int happy_n_nonterms = 125 :: Int happyReduce_4 = happyMonadReduce 1# 0# happyReduction_4 happyReduction_4 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut8 happy_x_1 of { happy_var_1 -> ( let decls = reverse happy_var_1 in case decls of [] -> do{ n <- getNewName; p <- getCurrentPosition; return $ CTranslUnit decls (mkNodeInfo' p (p,0) n) } (d:ds) -> withNodeInfo d $ CTranslUnit decls)} ) (\r -> happyReturn (happyIn7 r)) happyReduce_5 = happySpecReduce_0 1# happyReduction_5 happyReduction_5 = happyIn8 (empty ) happyReduce_6 = happySpecReduce_2 1# happyReduction_6 happyReduction_6 happy_x_2 happy_x_1 = case happyOut8 happy_x_1 of { happy_var_1 -> happyIn8 (happy_var_1 )} happyReduce_7 = happySpecReduce_2 1# happyReduction_7 happyReduction_7 happy_x_2 happy_x_1 = case happyOut8 happy_x_1 of { happy_var_1 -> case happyOut9 happy_x_2 of { happy_var_2 -> happyIn8 (happy_var_1 `snoc` happy_var_2 )}} happyReduce_8 = happySpecReduce_1 2# happyReduction_8 happyReduction_8 happy_x_1 = case happyOut10 happy_x_1 of { happy_var_1 -> happyIn9 (CFDefExt happy_var_1 )} happyReduce_9 = happySpecReduce_1 2# happyReduction_9 happyReduction_9 happy_x_1 = case happyOut32 happy_x_1 of { happy_var_1 -> happyIn9 (CDeclExt happy_var_1 )} happyReduce_10 = happySpecReduce_2 2# happyReduction_10 happyReduction_10 happy_x_2 happy_x_1 = case happyOut9 happy_x_2 of { happy_var_2 -> happyIn9 (happy_var_2 )} happyReduce_11 = happyMonadReduce 5# 2# happyReduction_11 happyReduction_11 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut123 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CAsmExt happy_var_3)}} ) (\r -> happyReturn (happyIn9 r)) happyReduce_12 = happyMonadReduce 2# 3# happyReduction_12 happyReduction_12 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut11 happy_x_1 of { happy_var_1 -> case happyOut14 happy_x_2 of { happy_var_2 -> ( leaveScope >> (withNodeInfo happy_var_1 $ CFunDef [] happy_var_1 [] happy_var_2))}} ) (\r -> happyReturn (happyIn10 r)) happyReduce_13 = happyMonadReduce 3# 3# happyReduction_13 happyReduction_13 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut127 happy_x_1 of { happy_var_1 -> case happyOut11 happy_x_2 of { happy_var_2 -> case happyOut14 happy_x_3 of { happy_var_3 -> ( leaveScope >> (withNodeInfo happy_var_1 $ CFunDef (liftCAttrs happy_var_1) happy_var_2 [] happy_var_3))}}} ) (\r -> happyReturn (happyIn10 r)) happyReduce_14 = happyMonadReduce 3# 3# happyReduction_14 happyReduction_14 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut37 happy_x_1 of { happy_var_1 -> case happyOut11 happy_x_2 of { happy_var_2 -> case happyOut14 happy_x_3 of { happy_var_3 -> ( leaveScope >> (withNodeInfo happy_var_1 $ CFunDef happy_var_1 happy_var_2 [] happy_var_3))}}} ) (\r -> happyReturn (happyIn10 r)) happyReduce_15 = happyMonadReduce 3# 3# happyReduction_15 happyReduction_15 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut41 happy_x_1 of { happy_var_1 -> case happyOut11 happy_x_2 of { happy_var_2 -> case happyOut14 happy_x_3 of { happy_var_3 -> ( leaveScope >> (withNodeInfo happy_var_1 $ CFunDef happy_var_1 happy_var_2 [] happy_var_3))}}} ) (\r -> happyReturn (happyIn10 r)) happyReduce_16 = happyMonadReduce 3# 3# happyReduction_16 happyReduction_16 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut38 happy_x_1 of { happy_var_1 -> case happyOut11 happy_x_2 of { happy_var_2 -> case happyOut14 happy_x_3 of { happy_var_3 -> ( leaveScope >> (withNodeInfo happy_var_1 $ CFunDef (reverse happy_var_1) happy_var_2 [] happy_var_3))}}} ) (\r -> happyReturn (happyIn10 r)) happyReduce_17 = happyMonadReduce 3# 3# happyReduction_17 happyReduction_17 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut11 happy_x_2 of { happy_var_2 -> case happyOut14 happy_x_3 of { happy_var_3 -> ( leaveScope >> (withNodeInfo happy_var_1 $ CFunDef (liftTypeQuals happy_var_1) happy_var_2 [] happy_var_3))}}} ) (\r -> happyReturn (happyIn10 r)) happyReduce_18 = happyMonadReduce 4# 3# happyReduction_18 happyReduction_18 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut11 happy_x_3 of { happy_var_3 -> case happyOut14 happy_x_4 of { happy_var_4 -> ( leaveScope >> (withNodeInfo happy_var_1 $ CFunDef (liftTypeQuals happy_var_1 ++ liftCAttrs happy_var_2) happy_var_3 [] happy_var_4))}}}} ) (\r -> happyReturn (happyIn10 r)) happyReduce_19 = happyMonadReduce 3# 3# happyReduction_19 happyReduction_19 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut76 happy_x_1 of { happy_var_1 -> case happyOut33 happy_x_2 of { happy_var_2 -> case happyOut14 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CFunDef [] happy_var_1 (reverse happy_var_2) happy_var_3)}}} ) (\r -> happyReturn (happyIn10 r)) happyReduce_20 = happyMonadReduce 4# 3# happyReduction_20 happyReduction_20 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut127 happy_x_1 of { happy_var_1 -> case happyOut76 happy_x_2 of { happy_var_2 -> case happyOut33 happy_x_3 of { happy_var_3 -> case happyOut14 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_2 $ CFunDef (liftCAttrs happy_var_1) happy_var_2 (reverse happy_var_3) happy_var_4)}}}} ) (\r -> happyReturn (happyIn10 r)) happyReduce_21 = happyMonadReduce 4# 3# happyReduction_21 happyReduction_21 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut37 happy_x_1 of { happy_var_1 -> case happyOut76 happy_x_2 of { happy_var_2 -> case happyOut33 happy_x_3 of { happy_var_3 -> case happyOut14 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ CFunDef happy_var_1 happy_var_2 (reverse happy_var_3) happy_var_4)}}}} ) (\r -> happyReturn (happyIn10 r)) happyReduce_22 = happyMonadReduce 4# 3# happyReduction_22 happyReduction_22 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut41 happy_x_1 of { happy_var_1 -> case happyOut76 happy_x_2 of { happy_var_2 -> case happyOut33 happy_x_3 of { happy_var_3 -> case happyOut14 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ CFunDef happy_var_1 happy_var_2 (reverse happy_var_3) happy_var_4)}}}} ) (\r -> happyReturn (happyIn10 r)) happyReduce_23 = happyMonadReduce 4# 3# happyReduction_23 happyReduction_23 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut38 happy_x_1 of { happy_var_1 -> case happyOut76 happy_x_2 of { happy_var_2 -> case happyOut33 happy_x_3 of { happy_var_3 -> case happyOut14 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ CFunDef (reverse happy_var_1) happy_var_2 (reverse happy_var_3) happy_var_4)}}}} ) (\r -> happyReturn (happyIn10 r)) happyReduce_24 = happyMonadReduce 4# 3# happyReduction_24 happyReduction_24 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut76 happy_x_2 of { happy_var_2 -> case happyOut33 happy_x_3 of { happy_var_3 -> case happyOut14 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ CFunDef (liftTypeQuals happy_var_1) happy_var_2 (reverse happy_var_3) happy_var_4)}}}} ) (\r -> happyReturn (happyIn10 r)) happyReduce_25 = happyMonadReduce 5# 3# happyReduction_25 happyReduction_25 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut76 happy_x_3 of { happy_var_3 -> case happyOut33 happy_x_4 of { happy_var_4 -> case happyOut14 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_1 $ CFunDef (liftTypeQuals happy_var_1 ++ liftCAttrs happy_var_2) happy_var_3 (reverse happy_var_4) happy_var_5)}}}}} ) (\r -> happyReturn (happyIn10 r)) happyReduce_26 = happyMonadReduce 1# 4# happyReduction_26 happyReduction_26 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut72 happy_x_1 of { happy_var_1 -> ( let declr = reverseDeclr happy_var_1 in enterScope >> doFuncParamDeclIdent declr >> return declr)} ) (\r -> happyReturn (happyIn11 r)) happyReduce_27 = happySpecReduce_1 5# happyReduction_27 happyReduction_27 happy_x_1 = case happyOut13 happy_x_1 of { happy_var_1 -> happyIn12 (happy_var_1 )} happyReduce_28 = happySpecReduce_1 5# happyReduction_28 happyReduction_28 happy_x_1 = case happyOut14 happy_x_1 of { happy_var_1 -> happyIn12 (happy_var_1 )} happyReduce_29 = happySpecReduce_1 5# happyReduction_29 happyReduction_29 happy_x_1 = case happyOut22 happy_x_1 of { happy_var_1 -> happyIn12 (happy_var_1 )} happyReduce_30 = happySpecReduce_1 5# happyReduction_30 happyReduction_30 happy_x_1 = case happyOut23 happy_x_1 of { happy_var_1 -> happyIn12 (happy_var_1 )} happyReduce_31 = happySpecReduce_1 5# happyReduction_31 happyReduction_31 happy_x_1 = case happyOut24 happy_x_1 of { happy_var_1 -> happyIn12 (happy_var_1 )} happyReduce_32 = happySpecReduce_1 5# happyReduction_32 happyReduction_32 happy_x_1 = case happyOut25 happy_x_1 of { happy_var_1 -> happyIn12 (happy_var_1 )} happyReduce_33 = happyMonadReduce 1# 5# happyReduction_33 happyReduction_33 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut26 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 (CAsm happy_var_1))} ) (\r -> happyReturn (happyIn12 r)) happyReduce_34 = happyMonadReduce 4# 6# happyReduction_34 happyReduction_34 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut125 happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_3 of { happy_var_3 -> case happyOut12 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ CLabel happy_var_1 happy_var_4 happy_var_3)}}} ) (\r -> happyReturn (happyIn13 r)) happyReduce_35 = happyMonadReduce 4# 6# happyReduction_35 happyReduction_35 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut121 happy_x_2 of { happy_var_2 -> case happyOut12 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ CCase happy_var_2 happy_var_4)}}} ) (\r -> happyReturn (happyIn13 r)) happyReduce_36 = happyMonadReduce 3# 6# happyReduction_36 happyReduction_36 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut12 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CDefault happy_var_3)}} ) (\r -> happyReturn (happyIn13 r)) happyReduce_37 = happyMonadReduce 6# 6# happyReduction_37 happyReduction_37 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut121 happy_x_2 of { happy_var_2 -> case happyOut121 happy_x_4 of { happy_var_4 -> case happyOut12 happy_x_6 of { happy_var_6 -> ( withNodeInfo happy_var_1 $ CCases happy_var_2 happy_var_4 happy_var_6)}}}} ) (\r -> happyReturn (happyIn13 r)) happyReduce_38 = happyMonadReduce 5# 7# happyReduction_38 happyReduction_38 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut17 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CCompound [] (reverse happy_var_3))}} ) (\r -> happyReturn (happyIn14 r)) happyReduce_39 = happyMonadReduce 6# 7# happyReduction_39 happyReduction_39 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut21 happy_x_3 of { happy_var_3 -> case happyOut17 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ CCompound (reverse happy_var_3) (reverse happy_var_4))}}} ) (\r -> happyReturn (happyIn14 r)) happyReduce_40 = happyMonadReduce 0# 8# happyReduction_40 happyReduction_40 (happyRest) tk = happyThen (( enterScope) ) (\r -> happyReturn (happyIn15 r)) happyReduce_41 = happyMonadReduce 0# 9# happyReduction_41 happyReduction_41 (happyRest) tk = happyThen (( leaveScope) ) (\r -> happyReturn (happyIn16 r)) happyReduce_42 = happySpecReduce_0 10# happyReduction_42 happyReduction_42 = happyIn17 (empty ) happyReduce_43 = happySpecReduce_2 10# happyReduction_43 happyReduction_43 happy_x_2 happy_x_1 = case happyOut17 happy_x_1 of { happy_var_1 -> case happyOut18 happy_x_2 of { happy_var_2 -> happyIn17 (happy_var_1 `snoc` happy_var_2 )}} happyReduce_44 = happySpecReduce_1 11# happyReduction_44 happyReduction_44 happy_x_1 = case happyOut12 happy_x_1 of { happy_var_1 -> happyIn18 (CBlockStmt happy_var_1 )} happyReduce_45 = happySpecReduce_1 11# happyReduction_45 happyReduction_45 happy_x_1 = case happyOut19 happy_x_1 of { happy_var_1 -> happyIn18 (happy_var_1 )} happyReduce_46 = happySpecReduce_1 12# happyReduction_46 happyReduction_46 happy_x_1 = case happyOut32 happy_x_1 of { happy_var_1 -> happyIn19 (CBlockDecl happy_var_1 )} happyReduce_47 = happySpecReduce_1 12# happyReduction_47 happyReduction_47 happy_x_1 = case happyOut20 happy_x_1 of { happy_var_1 -> happyIn19 (CNestedFunDef happy_var_1 )} happyReduce_48 = happySpecReduce_2 12# happyReduction_48 happyReduction_48 happy_x_2 happy_x_1 = case happyOut19 happy_x_2 of { happy_var_2 -> happyIn19 (happy_var_2 )} happyReduce_49 = happyMonadReduce 3# 13# happyReduction_49 happyReduction_49 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut37 happy_x_1 of { happy_var_1 -> case happyOut11 happy_x_2 of { happy_var_2 -> case happyOut14 happy_x_3 of { happy_var_3 -> ( leaveScope >> (withNodeInfo happy_var_1 $ CFunDef happy_var_1 happy_var_2 [] happy_var_3))}}} ) (\r -> happyReturn (happyIn20 r)) happyReduce_50 = happyMonadReduce 3# 13# happyReduction_50 happyReduction_50 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut41 happy_x_1 of { happy_var_1 -> case happyOut11 happy_x_2 of { happy_var_2 -> case happyOut14 happy_x_3 of { happy_var_3 -> ( leaveScope >> (withNodeInfo happy_var_1 $ CFunDef happy_var_1 happy_var_2 [] happy_var_3))}}} ) (\r -> happyReturn (happyIn20 r)) happyReduce_51 = happyMonadReduce 3# 13# happyReduction_51 happyReduction_51 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut38 happy_x_1 of { happy_var_1 -> case happyOut11 happy_x_2 of { happy_var_2 -> case happyOut14 happy_x_3 of { happy_var_3 -> ( leaveScope >> (withNodeInfo happy_var_1 $ CFunDef (reverse happy_var_1) happy_var_2 [] happy_var_3))}}} ) (\r -> happyReturn (happyIn20 r)) happyReduce_52 = happyMonadReduce 3# 13# happyReduction_52 happyReduction_52 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut11 happy_x_2 of { happy_var_2 -> case happyOut14 happy_x_3 of { happy_var_3 -> ( leaveScope >> (withNodeInfo happy_var_1 $ CFunDef (liftTypeQuals happy_var_1) happy_var_2 [] happy_var_3))}}} ) (\r -> happyReturn (happyIn20 r)) happyReduce_53 = happyMonadReduce 4# 13# happyReduction_53 happyReduction_53 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut11 happy_x_3 of { happy_var_3 -> case happyOut14 happy_x_4 of { happy_var_4 -> ( leaveScope >> (withNodeInfo happy_var_1 $ CFunDef (liftTypeQuals happy_var_1 ++ liftCAttrs happy_var_2) happy_var_3 [] happy_var_4))}}}} ) (\r -> happyReturn (happyIn20 r)) happyReduce_54 = happySpecReduce_3 14# happyReduction_54 happyReduction_54 happy_x_3 happy_x_2 happy_x_1 = case happyOut82 happy_x_2 of { happy_var_2 -> happyIn21 (happy_var_2 )} happyReduce_55 = happyReduce 4# 14# happyReduction_55 happyReduction_55 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut21 happy_x_1 of { happy_var_1 -> case happyOut82 happy_x_3 of { happy_var_3 -> happyIn21 (happy_var_1 `rappendr` happy_var_3 ) `HappyStk` happyRest}} happyReduce_56 = happyMonadReduce 1# 15# happyReduction_56 happyReduction_56 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CExpr Nothing)} ) (\r -> happyReturn (happyIn22 r)) happyReduce_57 = happyMonadReduce 2# 15# happyReduction_57 happyReduction_57 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut117 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CExpr (Just happy_var_1))} ) (\r -> happyReturn (happyIn22 r)) happyReduce_58 = happyMonadReduce 5# 16# happyReduction_58 happyReduction_58 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut117 happy_x_3 of { happy_var_3 -> case happyOut12 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_1 $ CIf happy_var_3 happy_var_5 Nothing)}}} ) (\r -> happyReturn (happyIn23 r)) happyReduce_59 = happyMonadReduce 7# 16# happyReduction_59 happyReduction_59 (happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut117 happy_x_3 of { happy_var_3 -> case happyOut12 happy_x_5 of { happy_var_5 -> case happyOut12 happy_x_7 of { happy_var_7 -> ( withNodeInfo happy_var_1 $ CIf happy_var_3 happy_var_5 (Just happy_var_7))}}}} ) (\r -> happyReturn (happyIn23 r)) happyReduce_60 = happyMonadReduce 5# 16# happyReduction_60 happyReduction_60 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut117 happy_x_3 of { happy_var_3 -> case happyOut12 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_1 $ CSwitch happy_var_3 happy_var_5)}}} ) (\r -> happyReturn (happyIn23 r)) happyReduce_61 = happyMonadReduce 5# 17# happyReduction_61 happyReduction_61 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut117 happy_x_3 of { happy_var_3 -> case happyOut12 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_1 $ CWhile happy_var_3 happy_var_5 False)}}} ) (\r -> happyReturn (happyIn24 r)) happyReduce_62 = happyMonadReduce 7# 17# happyReduction_62 happyReduction_62 (happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut12 happy_x_2 of { happy_var_2 -> case happyOut117 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_1 $ CWhile happy_var_5 happy_var_2 True)}}} ) (\r -> happyReturn (happyIn24 r)) happyReduce_63 = happyMonadReduce 9# 17# happyReduction_63 happyReduction_63 (happy_x_9 `HappyStk` happy_x_8 `HappyStk` happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut119 happy_x_3 of { happy_var_3 -> case happyOut119 happy_x_5 of { happy_var_5 -> case happyOut119 happy_x_7 of { happy_var_7 -> case happyOut12 happy_x_9 of { happy_var_9 -> ( withNodeInfo happy_var_1 $ CFor (Left happy_var_3) happy_var_5 happy_var_7 happy_var_9)}}}}} ) (\r -> happyReturn (happyIn24 r)) happyReduce_64 = happyMonadReduce 10# 17# happyReduction_64 happyReduction_64 (happy_x_10 `HappyStk` happy_x_9 `HappyStk` happy_x_8 `HappyStk` happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut32 happy_x_4 of { happy_var_4 -> case happyOut119 happy_x_5 of { happy_var_5 -> case happyOut119 happy_x_7 of { happy_var_7 -> case happyOut12 happy_x_9 of { happy_var_9 -> ( withNodeInfo happy_var_1 $ CFor (Right happy_var_4) happy_var_5 happy_var_7 happy_var_9)}}}}} ) (\r -> happyReturn (happyIn24 r)) happyReduce_65 = happyMonadReduce 3# 18# happyReduction_65 happyReduction_65 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut125 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CGoto happy_var_2)}} ) (\r -> happyReturn (happyIn25 r)) happyReduce_66 = happyMonadReduce 4# 18# happyReduction_66 happyReduction_66 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut117 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CGotoPtr happy_var_3)}} ) (\r -> happyReturn (happyIn25 r)) happyReduce_67 = happyMonadReduce 2# 18# happyReduction_67 happyReduction_67 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CCont)} ) (\r -> happyReturn (happyIn25 r)) happyReduce_68 = happyMonadReduce 2# 18# happyReduction_68 happyReduction_68 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CBreak)} ) (\r -> happyReturn (happyIn25 r)) happyReduce_69 = happyMonadReduce 3# 18# happyReduction_69 happyReduction_69 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut119 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CReturn happy_var_2)}} ) (\r -> happyReturn (happyIn25 r)) happyReduce_70 = happyMonadReduce 6# 19# happyReduction_70 happyReduction_70 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut27 happy_x_2 of { happy_var_2 -> case happyOut123 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ CAsmStmt happy_var_2 happy_var_4 [] [] [])}}} ) (\r -> happyReturn (happyIn26 r)) happyReduce_71 = happyMonadReduce 8# 19# happyReduction_71 happyReduction_71 (happy_x_8 `HappyStk` happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut27 happy_x_2 of { happy_var_2 -> case happyOut123 happy_x_4 of { happy_var_4 -> case happyOut28 happy_x_6 of { happy_var_6 -> ( withNodeInfo happy_var_1 $ CAsmStmt happy_var_2 happy_var_4 happy_var_6 [] [])}}}} ) (\r -> happyReturn (happyIn26 r)) happyReduce_72 = happyMonadReduce 10# 19# happyReduction_72 happyReduction_72 (happy_x_10 `HappyStk` happy_x_9 `HappyStk` happy_x_8 `HappyStk` happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut27 happy_x_2 of { happy_var_2 -> case happyOut123 happy_x_4 of { happy_var_4 -> case happyOut28 happy_x_6 of { happy_var_6 -> case happyOut28 happy_x_8 of { happy_var_8 -> ( withNodeInfo happy_var_1 $ CAsmStmt happy_var_2 happy_var_4 happy_var_6 happy_var_8 [])}}}}} ) (\r -> happyReturn (happyIn26 r)) happyReduce_73 = happyMonadReduce 12# 19# happyReduction_73 happyReduction_73 (happy_x_12 `HappyStk` happy_x_11 `HappyStk` happy_x_10 `HappyStk` happy_x_9 `HappyStk` happy_x_8 `HappyStk` happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut27 happy_x_2 of { happy_var_2 -> case happyOut123 happy_x_4 of { happy_var_4 -> case happyOut28 happy_x_6 of { happy_var_6 -> case happyOut28 happy_x_8 of { happy_var_8 -> case happyOut31 happy_x_10 of { happy_var_10 -> ( withNodeInfo happy_var_1 $ CAsmStmt happy_var_2 happy_var_4 happy_var_6 happy_var_8 (reverse happy_var_10))}}}}}} ) (\r -> happyReturn (happyIn26 r)) happyReduce_74 = happySpecReduce_0 20# happyReduction_74 happyReduction_74 = happyIn27 (Nothing ) happyReduce_75 = happySpecReduce_1 20# happyReduction_75 happyReduction_75 happy_x_1 = case happyOut61 happy_x_1 of { happy_var_1 -> happyIn27 (Just happy_var_1 )} happyReduce_76 = happySpecReduce_0 21# happyReduction_76 happyReduction_76 = happyIn28 ([] ) happyReduce_77 = happySpecReduce_1 21# happyReduction_77 happyReduction_77 happy_x_1 = case happyOut29 happy_x_1 of { happy_var_1 -> happyIn28 (reverse happy_var_1 )} happyReduce_78 = happySpecReduce_1 22# happyReduction_78 happyReduction_78 happy_x_1 = case happyOut30 happy_x_1 of { happy_var_1 -> happyIn29 (singleton happy_var_1 )} happyReduce_79 = happySpecReduce_3 22# happyReduction_79 happyReduction_79 happy_x_3 happy_x_2 happy_x_1 = case happyOut29 happy_x_1 of { happy_var_1 -> case happyOut30 happy_x_3 of { happy_var_3 -> happyIn29 (happy_var_1 `snoc` happy_var_3 )}} happyReduce_80 = happyMonadReduce 4# 23# happyReduction_80 happyReduction_80 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut123 happy_x_1 of { happy_var_1 -> case happyOut117 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CAsmOperand Nothing happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn30 r)) happyReduce_81 = happyMonadReduce 7# 23# happyReduction_81 happyReduction_81 (happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { (CTokIdent _ happy_var_2) -> case happyOut123 happy_x_4 of { happy_var_4 -> case happyOut117 happy_x_6 of { happy_var_6 -> ( withNodeInfo happy_var_1 $ CAsmOperand (Just happy_var_2) happy_var_4 happy_var_6)}}}} ) (\r -> happyReturn (happyIn30 r)) happyReduce_82 = happyMonadReduce 7# 23# happyReduction_82 happyReduction_82 (happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { (CTokTyIdent _ happy_var_2) -> case happyOut123 happy_x_4 of { happy_var_4 -> case happyOut117 happy_x_6 of { happy_var_6 -> ( withNodeInfo happy_var_1 $ CAsmOperand (Just happy_var_2) happy_var_4 happy_var_6)}}}} ) (\r -> happyReturn (happyIn30 r)) happyReduce_83 = happySpecReduce_1 24# happyReduction_83 happyReduction_83 happy_x_1 = case happyOut123 happy_x_1 of { happy_var_1 -> happyIn31 (singleton happy_var_1 )} happyReduce_84 = happySpecReduce_3 24# happyReduction_84 happyReduction_84 happy_x_3 happy_x_2 happy_x_1 = case happyOut31 happy_x_1 of { happy_var_1 -> case happyOut123 happy_x_3 of { happy_var_3 -> happyIn31 (happy_var_1 `snoc` happy_var_3 )}} happyReduce_85 = happyMonadReduce 2# 25# happyReduction_85 happyReduction_85 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut45 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CDecl (reverse happy_var_1) [])} ) (\r -> happyReturn (happyIn32 r)) happyReduce_86 = happyMonadReduce 2# 25# happyReduction_86 happyReduction_86 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut46 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CDecl (reverse happy_var_1) [])} ) (\r -> happyReturn (happyIn32 r)) happyReduce_87 = happyMonadReduce 2# 25# happyReduction_87 happyReduction_87 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut36 happy_x_1 of { happy_var_1 -> ( case happy_var_1 of CDecl declspecs dies at -> withLength at (CDecl declspecs (List.reverse dies)))} ) (\r -> happyReturn (happyIn32 r)) happyReduce_88 = happyMonadReduce 2# 25# happyReduction_88 happyReduction_88 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut34 happy_x_1 of { happy_var_1 -> ( case happy_var_1 of CDecl declspecs dies at -> withLength at (CDecl declspecs (List.reverse dies)))} ) (\r -> happyReturn (happyIn32 r)) happyReduce_89 = happySpecReduce_0 26# happyReduction_89 happyReduction_89 = happyIn33 (empty ) happyReduce_90 = happySpecReduce_2 26# happyReduction_90 happyReduction_90 happy_x_2 happy_x_1 = case happyOut33 happy_x_1 of { happy_var_1 -> case happyOut32 happy_x_2 of { happy_var_2 -> happyIn33 (happy_var_1 `snoc` happy_var_2 )}} happyReduce_91 = happyMonadReduce 4# 27# happyReduction_91 happyReduction_91 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut38 happy_x_1 of { happy_var_1 -> case happyOut72 happy_x_2 of { happy_var_2 -> case happyOut35 happy_x_3 of { happy_var_3 -> case happyOut91 happy_x_4 of { happy_var_4 -> ( let declspecs = reverse happy_var_1 in do{ declr <- withAsmNameAttrs happy_var_3 happy_var_2 ; doDeclIdent declspecs declr ; withNodeInfo happy_var_1 $ CDecl declspecs [(Just (reverseDeclr declr), happy_var_4, Nothing)] })}}}} ) (\r -> happyReturn (happyIn34 r)) happyReduce_92 = happyMonadReduce 4# 27# happyReduction_92 happyReduction_92 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut72 happy_x_2 of { happy_var_2 -> case happyOut35 happy_x_3 of { happy_var_3 -> case happyOut91 happy_x_4 of { happy_var_4 -> ( let declspecs = liftTypeQuals happy_var_1 in do{ declr <- withAsmNameAttrs happy_var_3 happy_var_2 ; doDeclIdent declspecs declr ; withNodeInfo happy_var_1 $ CDecl declspecs [(Just (reverseDeclr declr), happy_var_4, Nothing)] })}}}} ) (\r -> happyReturn (happyIn34 r)) happyReduce_93 = happyMonadReduce 5# 27# happyReduction_93 happyReduction_93 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut72 happy_x_3 of { happy_var_3 -> case happyOut35 happy_x_4 of { happy_var_4 -> case happyOut91 happy_x_5 of { happy_var_5 -> ( let declspecs = liftTypeQuals happy_var_1 in do{ declr <- withAsmNameAttrs happy_var_4 happy_var_3 ; doDeclIdent declspecs declr ; withNodeInfo happy_var_1 $ CDecl (declspecs ++ liftCAttrs happy_var_2) [(Just (reverseDeclr declr), happy_var_5, Nothing)] })}}}}} ) (\r -> happyReturn (happyIn34 r)) happyReduce_94 = happyMonadReduce 4# 27# happyReduction_94 happyReduction_94 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut127 happy_x_1 of { happy_var_1 -> case happyOut72 happy_x_2 of { happy_var_2 -> case happyOut35 happy_x_3 of { happy_var_3 -> case happyOut91 happy_x_4 of { happy_var_4 -> ( let declspecs = liftCAttrs happy_var_1 in do{ declr <- withAsmNameAttrs happy_var_3 happy_var_2 ; doDeclIdent declspecs declr ; withNodeInfo happy_var_1 $ CDecl declspecs [(Just (reverseDeclr declr), happy_var_4, Nothing)] })}}}} ) (\r -> happyReturn (happyIn34 r)) happyReduce_95 = happyMonadReduce 6# 27# happyReduction_95 happyReduction_95 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut34 happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_3 of { happy_var_3 -> case happyOut72 happy_x_4 of { happy_var_4 -> case happyOut35 happy_x_5 of { happy_var_5 -> case happyOut91 happy_x_6 of { happy_var_6 -> ( case happy_var_1 of CDecl declspecs dies at -> do declr <- withAsmNameAttrs (fst happy_var_5, snd happy_var_5 ++ happy_var_3) happy_var_4 doDeclIdent declspecs declr withLength at $ CDecl declspecs ((Just (reverseDeclr declr), happy_var_6, Nothing) : dies))}}}}} ) (\r -> happyReturn (happyIn34 r)) happyReduce_96 = happySpecReduce_2 28# happyReduction_96 happyReduction_96 happy_x_2 happy_x_1 = case happyOut64 happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_2 of { happy_var_2 -> happyIn35 ((happy_var_1,happy_var_2) )}} happyReduce_97 = happyMonadReduce 4# 29# happyReduction_97 happyReduction_97 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut37 happy_x_1 of { happy_var_1 -> case happyOut63 happy_x_2 of { happy_var_2 -> case happyOut35 happy_x_3 of { happy_var_3 -> case happyOut91 happy_x_4 of { happy_var_4 -> ( do{ declr <- withAsmNameAttrs happy_var_3 happy_var_2; doDeclIdent happy_var_1 declr; withNodeInfo happy_var_1 $ CDecl happy_var_1 [(Just (reverseDeclr declr), happy_var_4, Nothing)] })}}}} ) (\r -> happyReturn (happyIn36 r)) happyReduce_98 = happyMonadReduce 4# 29# happyReduction_98 happyReduction_98 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut41 happy_x_1 of { happy_var_1 -> case happyOut63 happy_x_2 of { happy_var_2 -> case happyOut35 happy_x_3 of { happy_var_3 -> case happyOut91 happy_x_4 of { happy_var_4 -> ( do{ declr <- withAsmNameAttrs happy_var_3 happy_var_2; doDeclIdent happy_var_1 declr; withNodeInfo happy_var_1 $ CDecl happy_var_1 [(Just (reverseDeclr declr), happy_var_4, Nothing)] })}}}} ) (\r -> happyReturn (happyIn36 r)) happyReduce_99 = happyMonadReduce 6# 29# happyReduction_99 happyReduction_99 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut36 happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_3 of { happy_var_3 -> case happyOut63 happy_x_4 of { happy_var_4 -> case happyOut35 happy_x_5 of { happy_var_5 -> case happyOut91 happy_x_6 of { happy_var_6 -> ( case happy_var_1 of CDecl declspecs dies at -> do declr <- withAsmNameAttrs (fst happy_var_5, snd happy_var_5 ++ happy_var_3) happy_var_4 doDeclIdent declspecs declr return (CDecl declspecs ((Just (reverseDeclr declr), happy_var_6, Nothing) : dies) at))}}}}} ) (\r -> happyReturn (happyIn36 r)) happyReduce_100 = happySpecReduce_1 30# happyReduction_100 happyReduction_100 happy_x_1 = case happyOut43 happy_x_1 of { happy_var_1 -> happyIn37 (reverse happy_var_1 )} happyReduce_101 = happySpecReduce_1 30# happyReduction_101 happyReduction_101 happy_x_1 = case happyOut45 happy_x_1 of { happy_var_1 -> happyIn37 (reverse happy_var_1 )} happyReduce_102 = happySpecReduce_1 30# happyReduction_102 happyReduction_102 happy_x_1 = case happyOut47 happy_x_1 of { happy_var_1 -> happyIn37 (reverse happy_var_1 )} happyReduce_103 = happySpecReduce_1 31# happyReduction_103 happyReduction_103 happy_x_1 = case happyOut40 happy_x_1 of { happy_var_1 -> happyIn38 (singleton (CStorageSpec happy_var_1) )} happyReduce_104 = happySpecReduce_2 31# happyReduction_104 happyReduction_104 happy_x_2 happy_x_1 = case happyOut127 happy_x_1 of { happy_var_1 -> case happyOut40 happy_x_2 of { happy_var_2 -> happyIn38 (reverseList (liftCAttrs happy_var_1) `snoc` (CStorageSpec happy_var_2) )}} happyReduce_105 = happySpecReduce_2 31# happyReduction_105 happyReduction_105 happy_x_2 happy_x_1 = case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut40 happy_x_2 of { happy_var_2 -> happyIn38 (rmap CTypeQual happy_var_1 `snoc` CStorageSpec happy_var_2 )}} happyReduce_106 = happySpecReduce_3 31# happyReduction_106 happyReduction_106 happy_x_3 happy_x_2 happy_x_1 = case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut40 happy_x_3 of { happy_var_3 -> happyIn38 ((rmap CTypeQual happy_var_1 `rappend` liftCAttrs happy_var_2) `snoc` CStorageSpec happy_var_3 )}}} happyReduce_107 = happySpecReduce_2 31# happyReduction_107 happyReduction_107 happy_x_2 happy_x_1 = case happyOut38 happy_x_1 of { happy_var_1 -> case happyOut39 happy_x_2 of { happy_var_2 -> happyIn38 (happy_var_1 `snoc` happy_var_2 )}} happyReduce_108 = happySpecReduce_2 31# happyReduction_108 happyReduction_108 happy_x_2 happy_x_1 = case happyOut38 happy_x_1 of { happy_var_1 -> case happyOut128 happy_x_2 of { happy_var_2 -> happyIn38 (addTrailingAttrs happy_var_1 happy_var_2 )}} happyReduce_109 = happySpecReduce_1 32# happyReduction_109 happyReduction_109 happy_x_1 = case happyOut40 happy_x_1 of { happy_var_1 -> happyIn39 (CStorageSpec happy_var_1 )} happyReduce_110 = happySpecReduce_1 32# happyReduction_110 happyReduction_110 happy_x_1 = case happyOut61 happy_x_1 of { happy_var_1 -> happyIn39 (CTypeQual happy_var_1 )} happyReduce_111 = happyMonadReduce 1# 33# happyReduction_111 happyReduction_111 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CTypedef)} ) (\r -> happyReturn (happyIn40 r)) happyReduce_112 = happyMonadReduce 1# 33# happyReduction_112 happyReduction_112 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CExtern)} ) (\r -> happyReturn (happyIn40 r)) happyReduce_113 = happyMonadReduce 1# 33# happyReduction_113 happyReduction_113 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CStatic)} ) (\r -> happyReturn (happyIn40 r)) happyReduce_114 = happyMonadReduce 1# 33# happyReduction_114 happyReduction_114 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CAuto)} ) (\r -> happyReturn (happyIn40 r)) happyReduce_115 = happyMonadReduce 1# 33# happyReduction_115 happyReduction_115 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CRegister)} ) (\r -> happyReturn (happyIn40 r)) happyReduce_116 = happyMonadReduce 1# 33# happyReduction_116 happyReduction_116 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CThread)} ) (\r -> happyReturn (happyIn40 r)) happyReduce_117 = happySpecReduce_1 34# happyReduction_117 happyReduction_117 happy_x_1 = case happyOut44 happy_x_1 of { happy_var_1 -> happyIn41 (reverse happy_var_1 )} happyReduce_118 = happySpecReduce_1 34# happyReduction_118 happyReduction_118 happy_x_1 = case happyOut46 happy_x_1 of { happy_var_1 -> happyIn41 (reverse happy_var_1 )} happyReduce_119 = happySpecReduce_1 34# happyReduction_119 happyReduction_119 happy_x_1 = case happyOut48 happy_x_1 of { happy_var_1 -> happyIn41 (reverse happy_var_1 )} happyReduce_120 = happyMonadReduce 1# 35# happyReduction_120 happyReduction_120 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CVoidType)} ) (\r -> happyReturn (happyIn42 r)) happyReduce_121 = happyMonadReduce 1# 35# happyReduction_121 happyReduction_121 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CCharType)} ) (\r -> happyReturn (happyIn42 r)) happyReduce_122 = happyMonadReduce 1# 35# happyReduction_122 happyReduction_122 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CShortType)} ) (\r -> happyReturn (happyIn42 r)) happyReduce_123 = happyMonadReduce 1# 35# happyReduction_123 happyReduction_123 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CIntType)} ) (\r -> happyReturn (happyIn42 r)) happyReduce_124 = happyMonadReduce 1# 35# happyReduction_124 happyReduction_124 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CLongType)} ) (\r -> happyReturn (happyIn42 r)) happyReduce_125 = happyMonadReduce 1# 35# happyReduction_125 happyReduction_125 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CFloatType)} ) (\r -> happyReturn (happyIn42 r)) happyReduce_126 = happyMonadReduce 1# 35# happyReduction_126 happyReduction_126 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CDoubleType)} ) (\r -> happyReturn (happyIn42 r)) happyReduce_127 = happyMonadReduce 1# 35# happyReduction_127 happyReduction_127 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CSignedType)} ) (\r -> happyReturn (happyIn42 r)) happyReduce_128 = happyMonadReduce 1# 35# happyReduction_128 happyReduction_128 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CUnsigType)} ) (\r -> happyReturn (happyIn42 r)) happyReduce_129 = happyMonadReduce 1# 35# happyReduction_129 happyReduction_129 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CBoolType)} ) (\r -> happyReturn (happyIn42 r)) happyReduce_130 = happyMonadReduce 1# 35# happyReduction_130 happyReduction_130 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CComplexType)} ) (\r -> happyReturn (happyIn42 r)) happyReduce_131 = happySpecReduce_2 36# happyReduction_131 happyReduction_131 happy_x_2 happy_x_1 = case happyOut38 happy_x_1 of { happy_var_1 -> case happyOut42 happy_x_2 of { happy_var_2 -> happyIn43 (happy_var_1 `snoc` CTypeSpec happy_var_2 )}} happyReduce_132 = happySpecReduce_2 36# happyReduction_132 happyReduction_132 happy_x_2 happy_x_1 = case happyOut44 happy_x_1 of { happy_var_1 -> case happyOut40 happy_x_2 of { happy_var_2 -> happyIn43 (happy_var_1 `snoc` CStorageSpec happy_var_2 )}} happyReduce_133 = happySpecReduce_2 36# happyReduction_133 happyReduction_133 happy_x_2 happy_x_1 = case happyOut43 happy_x_1 of { happy_var_1 -> case happyOut39 happy_x_2 of { happy_var_2 -> happyIn43 (happy_var_1 `snoc` happy_var_2 )}} happyReduce_134 = happySpecReduce_2 36# happyReduction_134 happyReduction_134 happy_x_2 happy_x_1 = case happyOut43 happy_x_1 of { happy_var_1 -> case happyOut42 happy_x_2 of { happy_var_2 -> happyIn43 (happy_var_1 `snoc` CTypeSpec happy_var_2 )}} happyReduce_135 = happySpecReduce_2 36# happyReduction_135 happyReduction_135 happy_x_2 happy_x_1 = case happyOut43 happy_x_1 of { happy_var_1 -> case happyOut128 happy_x_2 of { happy_var_2 -> happyIn43 (addTrailingAttrs happy_var_1 happy_var_2 )}} happyReduce_136 = happySpecReduce_1 37# happyReduction_136 happyReduction_136 happy_x_1 = case happyOut42 happy_x_1 of { happy_var_1 -> happyIn44 (singleton (CTypeSpec happy_var_1) )} happyReduce_137 = happySpecReduce_2 37# happyReduction_137 happyReduction_137 happy_x_2 happy_x_1 = case happyOut127 happy_x_1 of { happy_var_1 -> case happyOut42 happy_x_2 of { happy_var_2 -> happyIn44 ((reverseList $ liftCAttrs happy_var_1) `snoc` (CTypeSpec happy_var_2) )}} happyReduce_138 = happySpecReduce_2 37# happyReduction_138 happyReduction_138 happy_x_2 happy_x_1 = case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut42 happy_x_2 of { happy_var_2 -> happyIn44 (rmap CTypeQual happy_var_1 `snoc` CTypeSpec happy_var_2 )}} happyReduce_139 = happySpecReduce_3 37# happyReduction_139 happyReduction_139 happy_x_3 happy_x_2 happy_x_1 = case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut42 happy_x_3 of { happy_var_3 -> happyIn44 (rmap CTypeQual happy_var_1 `rappend` (liftCAttrs happy_var_2) `snoc` CTypeSpec happy_var_3 )}}} happyReduce_140 = happySpecReduce_2 37# happyReduction_140 happyReduction_140 happy_x_2 happy_x_1 = case happyOut44 happy_x_1 of { happy_var_1 -> case happyOut61 happy_x_2 of { happy_var_2 -> happyIn44 (happy_var_1 `snoc` CTypeQual happy_var_2 )}} happyReduce_141 = happySpecReduce_2 37# happyReduction_141 happyReduction_141 happy_x_2 happy_x_1 = case happyOut44 happy_x_1 of { happy_var_1 -> case happyOut42 happy_x_2 of { happy_var_2 -> happyIn44 (happy_var_1 `snoc` CTypeSpec happy_var_2 )}} happyReduce_142 = happySpecReduce_2 37# happyReduction_142 happyReduction_142 happy_x_2 happy_x_1 = case happyOut44 happy_x_1 of { happy_var_1 -> case happyOut128 happy_x_2 of { happy_var_2 -> happyIn44 (addTrailingAttrs happy_var_1 happy_var_2 )}} happyReduce_143 = happySpecReduce_2 38# happyReduction_143 happyReduction_143 happy_x_2 happy_x_1 = case happyOut38 happy_x_1 of { happy_var_1 -> case happyOut49 happy_x_2 of { happy_var_2 -> happyIn45 (happy_var_1 `snoc` CTypeSpec happy_var_2 )}} happyReduce_144 = happySpecReduce_2 38# happyReduction_144 happyReduction_144 happy_x_2 happy_x_1 = case happyOut46 happy_x_1 of { happy_var_1 -> case happyOut40 happy_x_2 of { happy_var_2 -> happyIn45 (happy_var_1 `snoc` CStorageSpec happy_var_2 )}} happyReduce_145 = happySpecReduce_2 38# happyReduction_145 happyReduction_145 happy_x_2 happy_x_1 = case happyOut45 happy_x_1 of { happy_var_1 -> case happyOut39 happy_x_2 of { happy_var_2 -> happyIn45 (happy_var_1 `snoc` happy_var_2 )}} happyReduce_146 = happySpecReduce_2 38# happyReduction_146 happyReduction_146 happy_x_2 happy_x_1 = case happyOut45 happy_x_1 of { happy_var_1 -> case happyOut128 happy_x_2 of { happy_var_2 -> happyIn45 (addTrailingAttrs happy_var_1 happy_var_2 )}} happyReduce_147 = happySpecReduce_1 39# happyReduction_147 happyReduction_147 happy_x_1 = case happyOut49 happy_x_1 of { happy_var_1 -> happyIn46 (singleton (CTypeSpec happy_var_1) )} happyReduce_148 = happySpecReduce_2 39# happyReduction_148 happyReduction_148 happy_x_2 happy_x_1 = case happyOut127 happy_x_1 of { happy_var_1 -> case happyOut49 happy_x_2 of { happy_var_2 -> happyIn46 ((reverseList $ liftCAttrs happy_var_1) `snoc` (CTypeSpec happy_var_2) )}} happyReduce_149 = happySpecReduce_2 39# happyReduction_149 happyReduction_149 happy_x_2 happy_x_1 = case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut49 happy_x_2 of { happy_var_2 -> happyIn46 (rmap CTypeQual happy_var_1 `snoc` CTypeSpec happy_var_2 )}} happyReduce_150 = happySpecReduce_3 39# happyReduction_150 happyReduction_150 happy_x_3 happy_x_2 happy_x_1 = case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut49 happy_x_3 of { happy_var_3 -> happyIn46 (rmap CTypeQual happy_var_1 `rappend` (liftCAttrs happy_var_2) `snoc` CTypeSpec happy_var_3 )}}} happyReduce_151 = happySpecReduce_2 39# happyReduction_151 happyReduction_151 happy_x_2 happy_x_1 = case happyOut46 happy_x_1 of { happy_var_1 -> case happyOut61 happy_x_2 of { happy_var_2 -> happyIn46 (happy_var_1 `snoc` CTypeQual happy_var_2 )}} happyReduce_152 = happySpecReduce_2 39# happyReduction_152 happyReduction_152 happy_x_2 happy_x_1 = case happyOut46 happy_x_1 of { happy_var_1 -> case happyOut128 happy_x_2 of { happy_var_2 -> happyIn46 (addTrailingAttrs happy_var_1 happy_var_2 )}} happyReduce_153 = happySpecReduce_2 40# happyReduction_153 happyReduction_153 happy_x_2 happy_x_1 = case happyOut48 happy_x_1 of { happy_var_1 -> case happyOut40 happy_x_2 of { happy_var_2 -> happyIn47 (happy_var_1 `snoc` CStorageSpec happy_var_2 )}} happyReduce_154 = happyMonadReduce 2# 40# happyReduction_154 happyReduction_154 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut38 happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { (CTokTyIdent _ happy_var_2) -> ( withNodeInfo happy_var_2 $ \at -> happy_var_1 `snoc` CTypeSpec (CTypeDef happy_var_2 at))}} ) (\r -> happyReturn (happyIn47 r)) happyReduce_155 = happyMonadReduce 5# 40# happyReduction_155 happyReduction_155 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut38 happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { happy_var_2 -> case happyOut117 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_2 $ \at -> happy_var_1 `snoc` CTypeSpec (CTypeOfExpr happy_var_4 at))}}} ) (\r -> happyReturn (happyIn47 r)) happyReduce_156 = happyMonadReduce 5# 40# happyReduction_156 happyReduction_156 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut38 happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { happy_var_2 -> case happyOut83 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_2 $ \at -> happy_var_1 `snoc` CTypeSpec (CTypeOfType happy_var_4 at))}}} ) (\r -> happyReturn (happyIn47 r)) happyReduce_157 = happySpecReduce_2 40# happyReduction_157 happyReduction_157 happy_x_2 happy_x_1 = case happyOut47 happy_x_1 of { happy_var_1 -> case happyOut39 happy_x_2 of { happy_var_2 -> happyIn47 (happy_var_1 `snoc` happy_var_2 )}} happyReduce_158 = happySpecReduce_2 40# happyReduction_158 happyReduction_158 happy_x_2 happy_x_1 = case happyOut47 happy_x_1 of { happy_var_1 -> case happyOut128 happy_x_2 of { happy_var_2 -> happyIn47 (addTrailingAttrs happy_var_1 happy_var_2 )}} happyReduce_159 = happyMonadReduce 1# 41# happyReduction_159 happyReduction_159 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { (CTokTyIdent _ happy_var_1) -> ( withNodeInfo happy_var_1 $ \at -> singleton (CTypeSpec (CTypeDef happy_var_1 at)))} ) (\r -> happyReturn (happyIn48 r)) happyReduce_160 = happyMonadReduce 4# 41# happyReduction_160 happyReduction_160 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut117 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ \at -> singleton (CTypeSpec (CTypeOfExpr happy_var_3 at)))}} ) (\r -> happyReturn (happyIn48 r)) happyReduce_161 = happyMonadReduce 4# 41# happyReduction_161 happyReduction_161 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut83 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ \at -> singleton (CTypeSpec (CTypeOfType happy_var_3 at)))}} ) (\r -> happyReturn (happyIn48 r)) happyReduce_162 = happyMonadReduce 2# 41# happyReduction_162 happyReduction_162 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { (CTokTyIdent _ happy_var_2) -> ( withNodeInfo happy_var_2 $ \at -> rmap CTypeQual happy_var_1 `snoc` CTypeSpec (CTypeDef happy_var_2 at))}} ) (\r -> happyReturn (happyIn48 r)) happyReduce_163 = happyMonadReduce 5# 41# happyReduction_163 happyReduction_163 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { happy_var_2 -> case happyOut117 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_2 $ \at -> rmap CTypeQual happy_var_1 `snoc` CTypeSpec (CTypeOfExpr happy_var_4 at))}}} ) (\r -> happyReturn (happyIn48 r)) happyReduce_164 = happyMonadReduce 5# 41# happyReduction_164 happyReduction_164 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { happy_var_2 -> case happyOut83 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_2 $ \at -> rmap CTypeQual happy_var_1 `snoc` CTypeSpec (CTypeOfType happy_var_4 at))}}} ) (\r -> happyReturn (happyIn48 r)) happyReduce_165 = happyMonadReduce 2# 41# happyReduction_165 happyReduction_165 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut127 happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { (CTokTyIdent _ happy_var_2) -> ( withNodeInfo happy_var_2 $ \at -> reverseList (liftCAttrs happy_var_1) `snoc` (CTypeSpec (CTypeDef happy_var_2 at)))}} ) (\r -> happyReturn (happyIn48 r)) happyReduce_166 = happyMonadReduce 5# 41# happyReduction_166 happyReduction_166 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut127 happy_x_1 of { happy_var_1 -> case happyOut117 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ \at -> reverseList (liftCAttrs happy_var_1) `snoc` (CTypeSpec (CTypeOfExpr happy_var_4 at)))}} ) (\r -> happyReturn (happyIn48 r)) happyReduce_167 = happyMonadReduce 5# 41# happyReduction_167 happyReduction_167 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut127 happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { happy_var_2 -> case happyOut83 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_2 $ \at -> reverseList (liftCAttrs happy_var_1) `snoc` (CTypeSpec (CTypeOfType happy_var_4 at)))}}} ) (\r -> happyReturn (happyIn48 r)) happyReduce_168 = happyMonadReduce 3# 41# happyReduction_168 happyReduction_168 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOutTok happy_x_3 of { (CTokTyIdent _ happy_var_3) -> ( withNodeInfo happy_var_3 $ \at -> rmap CTypeQual happy_var_1 `rappend` (liftCAttrs happy_var_2) `snoc` CTypeSpec (CTypeDef happy_var_3 at))}}} ) (\r -> happyReturn (happyIn48 r)) happyReduce_169 = happyMonadReduce 6# 41# happyReduction_169 happyReduction_169 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOutTok happy_x_3 of { happy_var_3 -> case happyOut117 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_3 $ \at -> rmap CTypeQual happy_var_1 `rappend` (liftCAttrs happy_var_2) `snoc` CTypeSpec (CTypeOfExpr happy_var_5 at))}}}} ) (\r -> happyReturn (happyIn48 r)) happyReduce_170 = happyMonadReduce 6# 41# happyReduction_170 happyReduction_170 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOutTok happy_x_3 of { happy_var_3 -> case happyOut83 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_3 $ \at -> rmap CTypeQual happy_var_1 `rappend` (liftCAttrs happy_var_2) `snoc` CTypeSpec (CTypeOfType happy_var_5 at))}}}} ) (\r -> happyReturn (happyIn48 r)) happyReduce_171 = happySpecReduce_2 41# happyReduction_171 happyReduction_171 happy_x_2 happy_x_1 = case happyOut48 happy_x_1 of { happy_var_1 -> case happyOut61 happy_x_2 of { happy_var_2 -> happyIn48 (happy_var_1 `snoc` CTypeQual happy_var_2 )}} happyReduce_172 = happySpecReduce_2 41# happyReduction_172 happyReduction_172 happy_x_2 happy_x_1 = case happyOut48 happy_x_1 of { happy_var_1 -> case happyOut128 happy_x_2 of { happy_var_2 -> happyIn48 (addTrailingAttrs happy_var_1 happy_var_2 )}} happyReduce_173 = happyMonadReduce 1# 42# happyReduction_173 happyReduction_173 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut50 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CSUType happy_var_1)} ) (\r -> happyReturn (happyIn49 r)) happyReduce_174 = happyMonadReduce 1# 42# happyReduction_174 happyReduction_174 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut58 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CEnumType happy_var_1)} ) (\r -> happyReturn (happyIn49 r)) happyReduce_175 = happyMonadReduce 6# 43# happyReduction_175 happyReduction_175 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut51 happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_2 of { happy_var_2 -> case happyOut125 happy_x_3 of { happy_var_3 -> case happyOut52 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_1 $ CStruct (unL happy_var_1) (Just happy_var_3) (Just$ reverse happy_var_5) happy_var_2)}}}} ) (\r -> happyReturn (happyIn50 r)) happyReduce_176 = happyMonadReduce 5# 43# happyReduction_176 happyReduction_176 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut51 happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_2 of { happy_var_2 -> case happyOut52 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ CStruct (unL happy_var_1) Nothing (Just$ reverse happy_var_4) happy_var_2)}}} ) (\r -> happyReturn (happyIn50 r)) happyReduce_177 = happyMonadReduce 3# 43# happyReduction_177 happyReduction_177 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut51 happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_2 of { happy_var_2 -> case happyOut125 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CStruct (unL happy_var_1) (Just happy_var_3) Nothing happy_var_2)}}} ) (\r -> happyReturn (happyIn50 r)) happyReduce_178 = happySpecReduce_1 44# happyReduction_178 happyReduction_178 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn51 (L CStructTag (posOf happy_var_1) )} happyReduce_179 = happySpecReduce_1 44# happyReduction_179 happyReduction_179 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn51 (L CUnionTag (posOf happy_var_1) )} happyReduce_180 = happySpecReduce_0 45# happyReduction_180 happyReduction_180 = happyIn52 (empty ) happyReduce_181 = happySpecReduce_2 45# happyReduction_181 happyReduction_181 happy_x_2 happy_x_1 = case happyOut52 happy_x_1 of { happy_var_1 -> happyIn52 (happy_var_1 )} happyReduce_182 = happySpecReduce_2 45# happyReduction_182 happyReduction_182 happy_x_2 happy_x_1 = case happyOut52 happy_x_1 of { happy_var_1 -> case happyOut53 happy_x_2 of { happy_var_2 -> happyIn52 (happy_var_1 `snoc` happy_var_2 )}} happyReduce_183 = happySpecReduce_2 46# happyReduction_183 happyReduction_183 happy_x_2 happy_x_1 = case happyOut55 happy_x_1 of { happy_var_1 -> happyIn53 (case happy_var_1 of CDecl declspecs dies at -> CDecl declspecs (List.reverse dies) at )} happyReduce_184 = happySpecReduce_2 46# happyReduction_184 happyReduction_184 happy_x_2 happy_x_1 = case happyOut54 happy_x_1 of { happy_var_1 -> happyIn53 (case happy_var_1 of CDecl declspecs dies at -> CDecl declspecs (List.reverse dies) at )} happyReduce_185 = happySpecReduce_2 46# happyReduction_185 happyReduction_185 happy_x_2 happy_x_1 = case happyOut53 happy_x_2 of { happy_var_2 -> happyIn53 (happy_var_2 )} happyReduce_186 = happyMonadReduce 3# 47# happyReduction_186 happyReduction_186 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_2 of { happy_var_2 -> case happyOut57 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ case happy_var_3 of (d,s) -> CDecl (liftTypeQuals happy_var_1 ++ liftCAttrs happy_var_2) [(d,Nothing,s)])}}} ) (\r -> happyReturn (happyIn54 r)) happyReduce_187 = happyMonadReduce 2# 47# happyReduction_187 happyReduction_187 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut127 happy_x_1 of { happy_var_1 -> case happyOut57 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ case happy_var_2 of (d,s) -> CDecl (liftCAttrs happy_var_1) [(d,Nothing,s)])}} ) (\r -> happyReturn (happyIn54 r)) happyReduce_188 = happyReduce 4# 47# happyReduction_188 happyReduction_188 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut54 happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_3 of { happy_var_3 -> case happyOut57 happy_x_4 of { happy_var_4 -> happyIn54 (case happy_var_1 of CDecl declspecs dies at -> case happy_var_4 of (Just d,s) -> CDecl declspecs ((Just $ appendObjAttrs happy_var_3 d,Nothing,s) : dies) at (Nothing,s) -> CDecl declspecs ((Nothing,Nothing,s) : dies) at ) `HappyStk` happyRest}}} happyReduce_189 = happyMonadReduce 3# 48# happyReduction_189 happyReduction_189 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut41 happy_x_1 of { happy_var_1 -> case happyOut56 happy_x_2 of { happy_var_2 -> case happyOut126 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ case happy_var_2 of { (Just d,s) -> CDecl happy_var_1 [(Just $! appendObjAttrs happy_var_3 d,Nothing,s)] ; (Nothing,s) -> CDecl happy_var_1 [(Nothing,Nothing,s)] })}}} ) (\r -> happyReturn (happyIn55 r)) happyReduce_190 = happyReduce 5# 48# happyReduction_190 happyReduction_190 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut55 happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_3 of { happy_var_3 -> case happyOut56 happy_x_4 of { happy_var_4 -> case happyOut126 happy_x_5 of { happy_var_5 -> happyIn55 (case happy_var_1 of CDecl declspecs dies attr -> case happy_var_4 of (Just d,s) -> CDecl declspecs ((Just$ appendObjAttrs (happy_var_3++happy_var_5) d,Nothing,s) : dies) attr (Nothing,s) -> CDecl declspecs ((Nothing,Nothing,s) : dies) attr ) `HappyStk` happyRest}}}} happyReduce_191 = happyMonadReduce 1# 48# happyReduction_191 happyReduction_191 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut41 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CDecl happy_var_1 [])} ) (\r -> happyReturn (happyIn55 r)) happyReduce_192 = happySpecReduce_1 49# happyReduction_192 happyReduction_192 happy_x_1 = case happyOut63 happy_x_1 of { happy_var_1 -> happyIn56 ((Just (reverseDeclr happy_var_1), Nothing) )} happyReduce_193 = happySpecReduce_2 49# happyReduction_193 happyReduction_193 happy_x_2 happy_x_1 = case happyOut121 happy_x_2 of { happy_var_2 -> happyIn56 ((Nothing, Just happy_var_2) )} happyReduce_194 = happySpecReduce_3 49# happyReduction_194 happyReduction_194 happy_x_3 happy_x_2 happy_x_1 = case happyOut63 happy_x_1 of { happy_var_1 -> case happyOut121 happy_x_3 of { happy_var_3 -> happyIn56 ((Just (reverseDeclr happy_var_1), Just happy_var_3) )}} happyReduce_195 = happySpecReduce_1 50# happyReduction_195 happyReduction_195 happy_x_1 = case happyOut72 happy_x_1 of { happy_var_1 -> happyIn57 ((Just (reverseDeclr happy_var_1), Nothing) )} happyReduce_196 = happySpecReduce_2 50# happyReduction_196 happyReduction_196 happy_x_2 happy_x_1 = case happyOut121 happy_x_2 of { happy_var_2 -> happyIn57 ((Nothing, Just happy_var_2) )} happyReduce_197 = happySpecReduce_3 50# happyReduction_197 happyReduction_197 happy_x_3 happy_x_2 happy_x_1 = case happyOut72 happy_x_1 of { happy_var_1 -> case happyOut121 happy_x_3 of { happy_var_3 -> happyIn57 ((Just (reverseDeclr happy_var_1), Just happy_var_3) )}} happyReduce_198 = happySpecReduce_2 50# happyReduction_198 happyReduction_198 happy_x_2 happy_x_1 = case happyOut57 happy_x_1 of { happy_var_1 -> case happyOut128 happy_x_2 of { happy_var_2 -> happyIn57 (case happy_var_1 of { (Nothing,expr) -> (Nothing,expr) {- FIXME -} ; (Just (CDeclr name derived asmname attrs node), bsz) -> (Just (CDeclr name derived asmname (attrs++happy_var_2) node),bsz) } )}} happyReduce_199 = happyMonadReduce 5# 51# happyReduction_199 happyReduction_199 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_2 of { happy_var_2 -> case happyOut59 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ CEnum Nothing (Just$ reverse happy_var_4) happy_var_2)}}} ) (\r -> happyReturn (happyIn58 r)) happyReduce_200 = happyMonadReduce 6# 51# happyReduction_200 happyReduction_200 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_2 of { happy_var_2 -> case happyOut59 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ CEnum Nothing (Just$ reverse happy_var_4) happy_var_2)}}} ) (\r -> happyReturn (happyIn58 r)) happyReduce_201 = happyMonadReduce 6# 51# happyReduction_201 happyReduction_201 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_2 of { happy_var_2 -> case happyOut125 happy_x_3 of { happy_var_3 -> case happyOut59 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_1 $ CEnum (Just happy_var_3) (Just$ reverse happy_var_5) happy_var_2)}}}} ) (\r -> happyReturn (happyIn58 r)) happyReduce_202 = happyMonadReduce 7# 51# happyReduction_202 happyReduction_202 (happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_2 of { happy_var_2 -> case happyOut125 happy_x_3 of { happy_var_3 -> case happyOut59 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_1 $ CEnum (Just happy_var_3) (Just$ reverse happy_var_5) happy_var_2)}}}} ) (\r -> happyReturn (happyIn58 r)) happyReduce_203 = happyMonadReduce 3# 51# happyReduction_203 happyReduction_203 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_2 of { happy_var_2 -> case happyOut125 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CEnum (Just happy_var_3) Nothing happy_var_2)}}} ) (\r -> happyReturn (happyIn58 r)) happyReduce_204 = happySpecReduce_1 52# happyReduction_204 happyReduction_204 happy_x_1 = case happyOut60 happy_x_1 of { happy_var_1 -> happyIn59 (singleton happy_var_1 )} happyReduce_205 = happySpecReduce_3 52# happyReduction_205 happyReduction_205 happy_x_3 happy_x_2 happy_x_1 = case happyOut59 happy_x_1 of { happy_var_1 -> case happyOut60 happy_x_3 of { happy_var_3 -> happyIn59 (happy_var_1 `snoc` happy_var_3 )}} happyReduce_206 = happySpecReduce_1 53# happyReduction_206 happyReduction_206 happy_x_1 = case happyOut125 happy_x_1 of { happy_var_1 -> happyIn60 ((happy_var_1, Nothing) )} happyReduce_207 = happySpecReduce_3 53# happyReduction_207 happyReduction_207 happy_x_3 happy_x_2 happy_x_1 = case happyOut125 happy_x_1 of { happy_var_1 -> case happyOut121 happy_x_3 of { happy_var_3 -> happyIn60 ((happy_var_1, Just happy_var_3) )}} happyReduce_208 = happyMonadReduce 1# 54# happyReduction_208 happyReduction_208 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CConstQual)} ) (\r -> happyReturn (happyIn61 r)) happyReduce_209 = happyMonadReduce 1# 54# happyReduction_209 happyReduction_209 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CVolatQual)} ) (\r -> happyReturn (happyIn61 r)) happyReduce_210 = happyMonadReduce 1# 54# happyReduction_210 happyReduction_210 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CRestrQual)} ) (\r -> happyReturn (happyIn61 r)) happyReduce_211 = happyMonadReduce 1# 54# happyReduction_211 happyReduction_211 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CInlineQual)} ) (\r -> happyReturn (happyIn61 r)) happyReduce_212 = happySpecReduce_2 55# happyReduction_212 happyReduction_212 happy_x_2 happy_x_1 = case happyOut126 happy_x_1 of { happy_var_1 -> case happyOut61 happy_x_2 of { happy_var_2 -> happyIn62 (reverseList (map CAttrQual happy_var_1) `snoc` happy_var_2 )}} happyReduce_213 = happySpecReduce_2 55# happyReduction_213 happyReduction_213 happy_x_2 happy_x_1 = case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut61 happy_x_2 of { happy_var_2 -> happyIn62 (happy_var_1 `snoc` happy_var_2 )}} happyReduce_214 = happySpecReduce_3 55# happyReduction_214 happyReduction_214 happy_x_3 happy_x_2 happy_x_1 = case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut61 happy_x_3 of { happy_var_3 -> happyIn62 ((happy_var_1 `rappend` map CAttrQual happy_var_2) `snoc` happy_var_3 )}}} happyReduce_215 = happySpecReduce_1 56# happyReduction_215 happyReduction_215 happy_x_1 = case happyOut72 happy_x_1 of { happy_var_1 -> happyIn63 (happy_var_1 )} happyReduce_216 = happySpecReduce_1 56# happyReduction_216 happyReduction_216 happy_x_1 = case happyOut65 happy_x_1 of { happy_var_1 -> happyIn63 (happy_var_1 )} happyReduce_217 = happySpecReduce_0 57# happyReduction_217 happyReduction_217 = happyIn64 (Nothing ) happyReduce_218 = happyReduce 4# 57# happyReduction_218 happyReduction_218 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut123 happy_x_3 of { happy_var_3 -> happyIn64 (Just happy_var_3 ) `HappyStk` happyRest} happyReduce_219 = happySpecReduce_1 58# happyReduction_219 happyReduction_219 happy_x_1 = case happyOut69 happy_x_1 of { happy_var_1 -> happyIn65 (happy_var_1 )} happyReduce_220 = happySpecReduce_1 58# happyReduction_220 happyReduction_220 happy_x_1 = case happyOut66 happy_x_1 of { happy_var_1 -> happyIn65 (happy_var_1 )} happyReduce_221 = happyMonadReduce 1# 59# happyReduction_221 happyReduction_221 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { (CTokTyIdent _ happy_var_1) -> ( withNodeInfo happy_var_1 $ mkVarDeclr happy_var_1)} ) (\r -> happyReturn (happyIn66 r)) happyReduce_222 = happyMonadReduce 2# 59# happyReduction_222 happyReduction_222 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { (CTokTyIdent _ happy_var_1) -> case happyOut85 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ \at -> happy_var_2 (mkVarDeclr happy_var_1 at))}} ) (\r -> happyReturn (happyIn66 r)) happyReduce_223 = happySpecReduce_1 59# happyReduction_223 happyReduction_223 happy_x_1 = case happyOut67 happy_x_1 of { happy_var_1 -> happyIn66 (happy_var_1 )} happyReduce_224 = happySpecReduce_1 60# happyReduction_224 happyReduction_224 happy_x_1 = case happyOut68 happy_x_1 of { happy_var_1 -> happyIn67 (happy_var_1 )} happyReduce_225 = happyMonadReduce 2# 60# happyReduction_225 happyReduction_225 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut66 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ ptrDeclr happy_var_2 [])}} ) (\r -> happyReturn (happyIn67 r)) happyReduce_226 = happyMonadReduce 3# 60# happyReduction_226 happyReduction_226 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut66 happy_x_3 of { happy_var_3 -> ( withAttribute happy_var_1 happy_var_2 $ ptrDeclr happy_var_3 [])}}} ) (\r -> happyReturn (happyIn67 r)) happyReduce_227 = happyMonadReduce 3# 60# happyReduction_227 happyReduction_227 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut66 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ ptrDeclr happy_var_3 (reverse happy_var_2))}}} ) (\r -> happyReturn (happyIn67 r)) happyReduce_228 = happyMonadReduce 4# 60# happyReduction_228 happyReduction_228 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut127 happy_x_3 of { happy_var_3 -> case happyOut66 happy_x_4 of { happy_var_4 -> ( withAttribute happy_var_1 happy_var_3 $ ptrDeclr happy_var_4 (reverse happy_var_2))}}}} ) (\r -> happyReturn (happyIn67 r)) happyReduce_229 = happySpecReduce_3 61# happyReduction_229 happyReduction_229 happy_x_3 happy_x_2 happy_x_1 = case happyOut67 happy_x_2 of { happy_var_2 -> happyIn68 (happy_var_2 )} happyReduce_230 = happyReduce 4# 61# happyReduction_230 happyReduction_230 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut67 happy_x_2 of { happy_var_2 -> case happyOut85 happy_x_4 of { happy_var_4 -> happyIn68 (happy_var_4 happy_var_2 ) `HappyStk` happyRest}} happyReduce_231 = happyReduce 4# 61# happyReduction_231 happyReduction_231 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut67 happy_x_3 of { happy_var_3 -> happyIn68 (appendDeclrAttrs happy_var_2 happy_var_3 ) `HappyStk` happyRest}} happyReduce_232 = happyReduce 5# 61# happyReduction_232 happyReduction_232 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut67 happy_x_3 of { happy_var_3 -> case happyOut85 happy_x_5 of { happy_var_5 -> happyIn68 (appendDeclrAttrs happy_var_2 (happy_var_5 happy_var_3) ) `HappyStk` happyRest}}} happyReduce_233 = happySpecReduce_1 62# happyReduction_233 happyReduction_233 happy_x_1 = case happyOut70 happy_x_1 of { happy_var_1 -> happyIn69 (happy_var_1 )} happyReduce_234 = happyMonadReduce 4# 62# happyReduction_234 happyReduction_234 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut71 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ ptrDeclr happy_var_3 [])}} ) (\r -> happyReturn (happyIn69 r)) happyReduce_235 = happyMonadReduce 5# 62# happyReduction_235 happyReduction_235 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut71 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ ptrDeclr happy_var_4 (reverse happy_var_2))}}} ) (\r -> happyReturn (happyIn69 r)) happyReduce_236 = happyMonadReduce 6# 62# happyReduction_236 happyReduction_236 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut127 happy_x_3 of { happy_var_3 -> case happyOut71 happy_x_5 of { happy_var_5 -> ( withAttribute happy_var_1 happy_var_3 $ ptrDeclr happy_var_5 (reverse happy_var_2))}}}} ) (\r -> happyReturn (happyIn69 r)) happyReduce_237 = happyMonadReduce 2# 62# happyReduction_237 happyReduction_237 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut69 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ ptrDeclr happy_var_2 [])}} ) (\r -> happyReturn (happyIn69 r)) happyReduce_238 = happyMonadReduce 3# 62# happyReduction_238 happyReduction_238 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut69 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ ptrDeclr happy_var_3 (reverse happy_var_2))}}} ) (\r -> happyReturn (happyIn69 r)) happyReduce_239 = happyMonadReduce 4# 62# happyReduction_239 happyReduction_239 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut127 happy_x_3 of { happy_var_3 -> case happyOut69 happy_x_4 of { happy_var_4 -> ( withAttribute happy_var_1 happy_var_3 $ ptrDeclr happy_var_4 (reverse happy_var_2))}}}} ) (\r -> happyReturn (happyIn69 r)) happyReduce_240 = happySpecReduce_3 63# happyReduction_240 happyReduction_240 happy_x_3 happy_x_2 happy_x_1 = case happyOut69 happy_x_2 of { happy_var_2 -> happyIn70 (happy_var_2 )} happyReduce_241 = happyReduce 4# 63# happyReduction_241 happyReduction_241 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut71 happy_x_2 of { happy_var_2 -> case happyOut85 happy_x_3 of { happy_var_3 -> happyIn70 (happy_var_3 happy_var_2 ) `HappyStk` happyRest}} happyReduce_242 = happyReduce 4# 63# happyReduction_242 happyReduction_242 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut69 happy_x_2 of { happy_var_2 -> case happyOut85 happy_x_4 of { happy_var_4 -> happyIn70 (happy_var_4 happy_var_2 ) `HappyStk` happyRest}} happyReduce_243 = happyMonadReduce 1# 64# happyReduction_243 happyReduction_243 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { (CTokTyIdent _ happy_var_1) -> ( withNodeInfo happy_var_1 $ mkVarDeclr happy_var_1)} ) (\r -> happyReturn (happyIn71 r)) happyReduce_244 = happySpecReduce_3 64# happyReduction_244 happyReduction_244 happy_x_3 happy_x_2 happy_x_1 = case happyOut71 happy_x_2 of { happy_var_2 -> happyIn71 (happy_var_2 )} happyReduce_245 = happySpecReduce_1 65# happyReduction_245 happyReduction_245 happy_x_1 = case happyOut73 happy_x_1 of { happy_var_1 -> happyIn72 (happy_var_1 )} happyReduce_246 = happySpecReduce_1 65# happyReduction_246 happyReduction_246 happy_x_1 = case happyOut75 happy_x_1 of { happy_var_1 -> happyIn72 (happy_var_1 )} happyReduce_247 = happySpecReduce_1 66# happyReduction_247 happyReduction_247 happy_x_1 = case happyOut74 happy_x_1 of { happy_var_1 -> happyIn73 (happy_var_1 )} happyReduce_248 = happyMonadReduce 2# 66# happyReduction_248 happyReduction_248 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut72 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ ptrDeclr happy_var_2 [])}} ) (\r -> happyReturn (happyIn73 r)) happyReduce_249 = happyMonadReduce 3# 66# happyReduction_249 happyReduction_249 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut72 happy_x_3 of { happy_var_3 -> ( withAttribute happy_var_1 happy_var_2 $ ptrDeclr happy_var_3 [])}}} ) (\r -> happyReturn (happyIn73 r)) happyReduce_250 = happyMonadReduce 3# 66# happyReduction_250 happyReduction_250 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut72 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ ptrDeclr happy_var_3 (reverse happy_var_2))}}} ) (\r -> happyReturn (happyIn73 r)) happyReduce_251 = happyMonadReduce 4# 66# happyReduction_251 happyReduction_251 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut127 happy_x_3 of { happy_var_3 -> case happyOut72 happy_x_4 of { happy_var_4 -> ( withAttribute happy_var_1 happy_var_3 $ ptrDeclr happy_var_4 (reverse happy_var_2))}}}} ) (\r -> happyReturn (happyIn73 r)) happyReduce_252 = happySpecReduce_2 67# happyReduction_252 happyReduction_252 happy_x_2 happy_x_1 = case happyOut75 happy_x_1 of { happy_var_1 -> case happyOut85 happy_x_2 of { happy_var_2 -> happyIn74 (happy_var_2 happy_var_1 )}} happyReduce_253 = happySpecReduce_3 67# happyReduction_253 happyReduction_253 happy_x_3 happy_x_2 happy_x_1 = case happyOut73 happy_x_2 of { happy_var_2 -> happyIn74 (happy_var_2 )} happyReduce_254 = happyReduce 4# 67# happyReduction_254 happyReduction_254 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut73 happy_x_2 of { happy_var_2 -> case happyOut85 happy_x_4 of { happy_var_4 -> happyIn74 (happy_var_4 happy_var_2 ) `HappyStk` happyRest}} happyReduce_255 = happyReduce 4# 67# happyReduction_255 happyReduction_255 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut73 happy_x_3 of { happy_var_3 -> happyIn74 (appendDeclrAttrs happy_var_2 happy_var_3 ) `HappyStk` happyRest}} happyReduce_256 = happyReduce 5# 67# happyReduction_256 happyReduction_256 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut73 happy_x_3 of { happy_var_3 -> case happyOut85 happy_x_5 of { happy_var_5 -> happyIn74 (appendDeclrAttrs happy_var_2 (happy_var_5 happy_var_3) ) `HappyStk` happyRest}}} happyReduce_257 = happyMonadReduce 1# 68# happyReduction_257 happyReduction_257 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { (CTokIdent _ happy_var_1) -> ( withNodeInfo happy_var_1 $ mkVarDeclr happy_var_1)} ) (\r -> happyReturn (happyIn75 r)) happyReduce_258 = happySpecReduce_3 68# happyReduction_258 happyReduction_258 happy_x_3 happy_x_2 happy_x_1 = case happyOut75 happy_x_2 of { happy_var_2 -> happyIn75 (happy_var_2 )} happyReduce_259 = happyReduce 4# 68# happyReduction_259 happyReduction_259 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut75 happy_x_3 of { happy_var_3 -> happyIn75 (appendDeclrAttrs happy_var_2 happy_var_3 ) `HappyStk` happyRest}} happyReduce_260 = happySpecReduce_1 69# happyReduction_260 happyReduction_260 happy_x_1 = case happyOut77 happy_x_1 of { happy_var_1 -> happyIn76 (reverseDeclr happy_var_1 )} happyReduce_261 = happySpecReduce_1 70# happyReduction_261 happyReduction_261 happy_x_1 = case happyOut78 happy_x_1 of { happy_var_1 -> happyIn77 (happy_var_1 )} happyReduce_262 = happyMonadReduce 2# 70# happyReduction_262 happyReduction_262 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut77 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ ptrDeclr happy_var_2 [])}} ) (\r -> happyReturn (happyIn77 r)) happyReduce_263 = happyMonadReduce 3# 70# happyReduction_263 happyReduction_263 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut77 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ ptrDeclr happy_var_3 (reverse happy_var_2))}}} ) (\r -> happyReturn (happyIn77 r)) happyReduce_264 = happyMonadReduce 4# 71# happyReduction_264 happyReduction_264 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut75 happy_x_1 of { happy_var_1 -> case happyOut82 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ funDeclr happy_var_1 (Left $ reverse happy_var_3) [])}} ) (\r -> happyReturn (happyIn78 r)) happyReduce_265 = happySpecReduce_3 71# happyReduction_265 happyReduction_265 happy_x_3 happy_x_2 happy_x_1 = case happyOut77 happy_x_2 of { happy_var_2 -> happyIn78 (happy_var_2 )} happyReduce_266 = happyReduce 4# 71# happyReduction_266 happyReduction_266 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut77 happy_x_2 of { happy_var_2 -> case happyOut85 happy_x_4 of { happy_var_4 -> happyIn78 (happy_var_4 happy_var_2 ) `HappyStk` happyRest}} happyReduce_267 = happySpecReduce_0 72# happyReduction_267 happyReduction_267 = happyIn79 (([], False) ) happyReduce_268 = happySpecReduce_1 72# happyReduction_268 happyReduction_268 happy_x_1 = case happyOut80 happy_x_1 of { happy_var_1 -> happyIn79 ((reverse happy_var_1, False) )} happyReduce_269 = happySpecReduce_3 72# happyReduction_269 happyReduction_269 happy_x_3 happy_x_2 happy_x_1 = case happyOut80 happy_x_1 of { happy_var_1 -> happyIn79 ((reverse happy_var_1, True) )} happyReduce_270 = happySpecReduce_1 73# happyReduction_270 happyReduction_270 happy_x_1 = case happyOut81 happy_x_1 of { happy_var_1 -> happyIn80 (singleton happy_var_1 )} happyReduce_271 = happySpecReduce_3 73# happyReduction_271 happyReduction_271 happy_x_3 happy_x_2 happy_x_1 = case happyOut80 happy_x_1 of { happy_var_1 -> case happyOut81 happy_x_3 of { happy_var_3 -> happyIn80 (happy_var_1 `snoc` happy_var_3 )}} happyReduce_272 = happyMonadReduce 1# 74# happyReduction_272 happyReduction_272 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut37 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CDecl happy_var_1 [])} ) (\r -> happyReturn (happyIn81 r)) happyReduce_273 = happyMonadReduce 2# 74# happyReduction_273 happyReduction_273 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut37 happy_x_1 of { happy_var_1 -> case happyOut84 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CDecl happy_var_1 [(Just (reverseDeclr happy_var_2), Nothing, Nothing)])}} ) (\r -> happyReturn (happyIn81 r)) happyReduce_274 = happyMonadReduce 3# 74# happyReduction_274 happyReduction_274 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut37 happy_x_1 of { happy_var_1 -> case happyOut72 happy_x_2 of { happy_var_2 -> case happyOut126 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CDecl happy_var_1 [(Just (reverseDeclr $! appendDeclrAttrs happy_var_3 happy_var_2), Nothing, Nothing)])}}} ) (\r -> happyReturn (happyIn81 r)) happyReduce_275 = happyMonadReduce 3# 74# happyReduction_275 happyReduction_275 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut37 happy_x_1 of { happy_var_1 -> case happyOut66 happy_x_2 of { happy_var_2 -> case happyOut126 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CDecl happy_var_1 [(Just (reverseDeclr $! appendDeclrAttrs happy_var_3 happy_var_2), Nothing, Nothing)])}}} ) (\r -> happyReturn (happyIn81 r)) happyReduce_276 = happyMonadReduce 1# 74# happyReduction_276 happyReduction_276 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut38 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CDecl (reverse happy_var_1) [])} ) (\r -> happyReturn (happyIn81 r)) happyReduce_277 = happyMonadReduce 2# 74# happyReduction_277 happyReduction_277 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut38 happy_x_1 of { happy_var_1 -> case happyOut84 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CDecl (reverse happy_var_1) [(Just (reverseDeclr happy_var_2), Nothing, Nothing)])}} ) (\r -> happyReturn (happyIn81 r)) happyReduce_278 = happyMonadReduce 3# 74# happyReduction_278 happyReduction_278 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut38 happy_x_1 of { happy_var_1 -> case happyOut72 happy_x_2 of { happy_var_2 -> case happyOut126 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CDecl (reverse happy_var_1) [(Just (reverseDeclr $! appendDeclrAttrs happy_var_3 happy_var_2), Nothing, Nothing)])}}} ) (\r -> happyReturn (happyIn81 r)) happyReduce_279 = happyMonadReduce 1# 74# happyReduction_279 happyReduction_279 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut41 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CDecl happy_var_1 [])} ) (\r -> happyReturn (happyIn81 r)) happyReduce_280 = happyMonadReduce 2# 74# happyReduction_280 happyReduction_280 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut41 happy_x_1 of { happy_var_1 -> case happyOut84 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CDecl happy_var_1 [(Just (reverseDeclr happy_var_2), Nothing, Nothing)])}} ) (\r -> happyReturn (happyIn81 r)) happyReduce_281 = happyMonadReduce 3# 74# happyReduction_281 happyReduction_281 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut41 happy_x_1 of { happy_var_1 -> case happyOut72 happy_x_2 of { happy_var_2 -> case happyOut126 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CDecl happy_var_1 [(Just (reverseDeclr $! appendDeclrAttrs happy_var_3 happy_var_2), Nothing, Nothing)])}}} ) (\r -> happyReturn (happyIn81 r)) happyReduce_282 = happyMonadReduce 3# 74# happyReduction_282 happyReduction_282 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut41 happy_x_1 of { happy_var_1 -> case happyOut66 happy_x_2 of { happy_var_2 -> case happyOut126 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CDecl happy_var_1 [(Just (reverseDeclr $! appendDeclrAttrs happy_var_3 happy_var_2), Nothing, Nothing)])}}} ) (\r -> happyReturn (happyIn81 r)) happyReduce_283 = happyMonadReduce 1# 74# happyReduction_283 happyReduction_283 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CDecl (liftTypeQuals happy_var_1) [])} ) (\r -> happyReturn (happyIn81 r)) happyReduce_284 = happyMonadReduce 2# 74# happyReduction_284 happyReduction_284 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut128 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CDecl (liftTypeQuals happy_var_1 ++ liftCAttrs happy_var_2) [])}} ) (\r -> happyReturn (happyIn81 r)) happyReduce_285 = happyMonadReduce 2# 74# happyReduction_285 happyReduction_285 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut84 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CDecl (liftTypeQuals happy_var_1) [(Just (reverseDeclr happy_var_2), Nothing, Nothing)])}} ) (\r -> happyReturn (happyIn81 r)) happyReduce_286 = happyMonadReduce 3# 74# happyReduction_286 happyReduction_286 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut72 happy_x_2 of { happy_var_2 -> case happyOut126 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CDecl (liftTypeQuals happy_var_1) [(Just (reverseDeclr$ appendDeclrAttrs happy_var_3 happy_var_2), Nothing, Nothing)])}}} ) (\r -> happyReturn (happyIn81 r)) happyReduce_287 = happySpecReduce_1 75# happyReduction_287 happyReduction_287 happy_x_1 = case happyOutTok happy_x_1 of { (CTokIdent _ happy_var_1) -> happyIn82 (singleton happy_var_1 )} happyReduce_288 = happySpecReduce_3 75# happyReduction_288 happyReduction_288 happy_x_3 happy_x_2 happy_x_1 = case happyOut82 happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_3 of { (CTokIdent _ happy_var_3) -> happyIn82 (happy_var_1 `snoc` happy_var_3 )}} happyReduce_289 = happyMonadReduce 1# 76# happyReduction_289 happyReduction_289 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut41 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CDecl happy_var_1 [])} ) (\r -> happyReturn (happyIn83 r)) happyReduce_290 = happyMonadReduce 2# 76# happyReduction_290 happyReduction_290 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut41 happy_x_1 of { happy_var_1 -> case happyOut84 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CDecl happy_var_1 [(Just (reverseDeclr happy_var_2), Nothing, Nothing)])}} ) (\r -> happyReturn (happyIn83 r)) happyReduce_291 = happyMonadReduce 2# 76# happyReduction_291 happyReduction_291 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut128 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CDecl (liftTypeQuals happy_var_1 ++ liftCAttrs happy_var_2) [])}} ) (\r -> happyReturn (happyIn83 r)) happyReduce_292 = happyMonadReduce 2# 76# happyReduction_292 happyReduction_292 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut62 happy_x_1 of { happy_var_1 -> case happyOut84 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CDecl (liftTypeQuals happy_var_1) [(Just (reverseDeclr happy_var_2), Nothing, Nothing)])}} ) (\r -> happyReturn (happyIn83 r)) happyReduce_293 = happySpecReduce_1 77# happyReduction_293 happyReduction_293 happy_x_1 = case happyOut88 happy_x_1 of { happy_var_1 -> happyIn84 (happy_var_1 )} happyReduce_294 = happySpecReduce_1 77# happyReduction_294 happyReduction_294 happy_x_1 = case happyOut89 happy_x_1 of { happy_var_1 -> happyIn84 (happy_var_1 )} happyReduce_295 = happySpecReduce_1 77# happyReduction_295 happyReduction_295 happy_x_1 = case happyOut85 happy_x_1 of { happy_var_1 -> happyIn84 (happy_var_1 emptyDeclr )} happyReduce_296 = happySpecReduce_1 78# happyReduction_296 happyReduction_296 happy_x_1 = case happyOut86 happy_x_1 of { happy_var_1 -> happyIn85 (happy_var_1 )} happyReduce_297 = happyMonadReduce 3# 78# happyReduction_297 happyReduction_297 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut79 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ \at declr -> case happy_var_2 of (params, variadic) -> funDeclr declr (Right (params,variadic)) [] at)}} ) (\r -> happyReturn (happyIn85 r)) happyReduce_298 = happySpecReduce_1 79# happyReduction_298 happyReduction_298 happy_x_1 = case happyOut87 happy_x_1 of { happy_var_1 -> happyIn86 (happy_var_1 )} happyReduce_299 = happySpecReduce_2 79# happyReduction_299 happyReduction_299 happy_x_2 happy_x_1 = case happyOut86 happy_x_1 of { happy_var_1 -> case happyOut87 happy_x_2 of { happy_var_2 -> happyIn86 (\decl -> happy_var_2 (happy_var_1 decl) )}} happyReduce_300 = happyMonadReduce 3# 80# happyReduction_300 happyReduction_300 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut120 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ \at declr -> arrDeclr declr [] False False happy_var_2 at)}} ) (\r -> happyReturn (happyIn87 r)) happyReduce_301 = happyMonadReduce 4# 80# happyReduction_301 happyReduction_301 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut120 happy_x_3 of { happy_var_3 -> ( withAttributePF happy_var_1 happy_var_2 $ \at declr -> arrDeclr declr [] False False happy_var_3 at)}}} ) (\r -> happyReturn (happyIn87 r)) happyReduce_302 = happyMonadReduce 4# 80# happyReduction_302 happyReduction_302 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut120 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ \at declr -> arrDeclr declr (reverse happy_var_2) False False happy_var_3 at)}}} ) (\r -> happyReturn (happyIn87 r)) happyReduce_303 = happyMonadReduce 5# 80# happyReduction_303 happyReduction_303 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut127 happy_x_3 of { happy_var_3 -> case happyOut120 happy_x_4 of { happy_var_4 -> ( withAttributePF happy_var_1 happy_var_3 $ \at declr -> arrDeclr declr (reverse happy_var_2) False False happy_var_4 at)}}}} ) (\r -> happyReturn (happyIn87 r)) happyReduce_304 = happyMonadReduce 5# 80# happyReduction_304 happyReduction_304 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_3 of { happy_var_3 -> case happyOut115 happy_x_4 of { happy_var_4 -> ( withAttributePF happy_var_1 happy_var_3 $ \at declr -> arrDeclr declr [] False True (Just happy_var_4) at)}}} ) (\r -> happyReturn (happyIn87 r)) happyReduce_305 = happyMonadReduce 6# 80# happyReduction_305 happyReduction_305 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_3 of { happy_var_3 -> case happyOut126 happy_x_4 of { happy_var_4 -> case happyOut115 happy_x_5 of { happy_var_5 -> ( withAttributePF happy_var_1 happy_var_4 $ \at declr -> arrDeclr declr (reverse happy_var_3) False True (Just happy_var_5) at)}}}} ) (\r -> happyReturn (happyIn87 r)) happyReduce_306 = happyMonadReduce 7# 80# happyReduction_306 happyReduction_306 (happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut126 happy_x_3 of { happy_var_3 -> case happyOut126 happy_x_5 of { happy_var_5 -> case happyOut115 happy_x_6 of { happy_var_6 -> ( withAttributePF happy_var_1 (happy_var_3 ++ happy_var_5) $ \at declr -> arrDeclr declr (reverse happy_var_2) False True (Just happy_var_6) at)}}}}} ) (\r -> happyReturn (happyIn87 r)) happyReduce_307 = happyMonadReduce 4# 80# happyReduction_307 happyReduction_307 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut126 happy_x_3 of { happy_var_3 -> ( withAttributePF happy_var_1 happy_var_3 $ \at declr -> arrDeclr declr [] True False Nothing at)}} ) (\r -> happyReturn (happyIn87 r)) happyReduce_308 = happyMonadReduce 5# 80# happyReduction_308 happyReduction_308 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut126 happy_x_4 of { happy_var_4 -> ( withAttributePF happy_var_1 (happy_var_2 ++ happy_var_4) $ \at declr -> arrDeclr declr [] True False Nothing at)}}} ) (\r -> happyReturn (happyIn87 r)) happyReduce_309 = happyMonadReduce 5# 80# happyReduction_309 happyReduction_309 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut126 happy_x_4 of { happy_var_4 -> ( withAttributePF happy_var_1 happy_var_4 $ \at declr -> arrDeclr declr (reverse happy_var_2) True False Nothing at)}}} ) (\r -> happyReturn (happyIn87 r)) happyReduce_310 = happyMonadReduce 6# 80# happyReduction_310 happyReduction_310 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut127 happy_x_3 of { happy_var_3 -> case happyOut126 happy_x_5 of { happy_var_5 -> ( withAttributePF happy_var_1 (happy_var_3 ++ happy_var_5) $ \at declr -> arrDeclr declr (reverse happy_var_2) True False Nothing at)}}}} ) (\r -> happyReturn (happyIn87 r)) happyReduce_311 = happyMonadReduce 1# 81# happyReduction_311 happyReduction_311 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ ptrDeclr emptyDeclr [])} ) (\r -> happyReturn (happyIn88 r)) happyReduce_312 = happyMonadReduce 3# 81# happyReduction_312 happyReduction_312 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut126 happy_x_3 of { happy_var_3 -> ( withAttribute happy_var_1 happy_var_3 $ ptrDeclr emptyDeclr (reverse happy_var_2))}}} ) (\r -> happyReturn (happyIn88 r)) happyReduce_313 = happyMonadReduce 2# 81# happyReduction_313 happyReduction_313 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut84 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ ptrDeclr happy_var_2 [])}} ) (\r -> happyReturn (happyIn88 r)) happyReduce_314 = happyMonadReduce 3# 81# happyReduction_314 happyReduction_314 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut62 happy_x_2 of { happy_var_2 -> case happyOut84 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ ptrDeclr happy_var_3 (reverse happy_var_2))}}} ) (\r -> happyReturn (happyIn88 r)) happyReduce_315 = happyMonadReduce 2# 81# happyReduction_315 happyReduction_315 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> ( withAttribute happy_var_1 happy_var_2 $ ptrDeclr emptyDeclr [])}} ) (\r -> happyReturn (happyIn88 r)) happyReduce_316 = happyMonadReduce 3# 81# happyReduction_316 happyReduction_316 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut84 happy_x_3 of { happy_var_3 -> ( withAttribute happy_var_1 happy_var_2 $ ptrDeclr happy_var_3 [])}}} ) (\r -> happyReturn (happyIn88 r)) happyReduce_317 = happySpecReduce_3 82# happyReduction_317 happyReduction_317 happy_x_3 happy_x_2 happy_x_1 = case happyOut88 happy_x_2 of { happy_var_2 -> happyIn89 (happy_var_2 )} happyReduce_318 = happySpecReduce_3 82# happyReduction_318 happyReduction_318 happy_x_3 happy_x_2 happy_x_1 = case happyOut89 happy_x_2 of { happy_var_2 -> happyIn89 (happy_var_2 )} happyReduce_319 = happySpecReduce_3 82# happyReduction_319 happyReduction_319 happy_x_3 happy_x_2 happy_x_1 = case happyOut85 happy_x_2 of { happy_var_2 -> happyIn89 (happy_var_2 emptyDeclr )} happyReduce_320 = happyReduce 4# 82# happyReduction_320 happyReduction_320 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut88 happy_x_2 of { happy_var_2 -> case happyOut85 happy_x_4 of { happy_var_4 -> happyIn89 (happy_var_4 happy_var_2 ) `HappyStk` happyRest}} happyReduce_321 = happyReduce 4# 82# happyReduction_321 happyReduction_321 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut88 happy_x_3 of { happy_var_3 -> happyIn89 (appendDeclrAttrs happy_var_2 happy_var_3 ) `HappyStk` happyRest}} happyReduce_322 = happyReduce 4# 82# happyReduction_322 happyReduction_322 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut89 happy_x_3 of { happy_var_3 -> happyIn89 (appendDeclrAttrs happy_var_2 happy_var_3 ) `HappyStk` happyRest}} happyReduce_323 = happyReduce 4# 82# happyReduction_323 happyReduction_323 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut85 happy_x_3 of { happy_var_3 -> happyIn89 (appendDeclrAttrs happy_var_2 (happy_var_3 emptyDeclr) ) `HappyStk` happyRest}} happyReduce_324 = happyReduce 5# 82# happyReduction_324 happyReduction_324 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut127 happy_x_2 of { happy_var_2 -> case happyOut88 happy_x_3 of { happy_var_3 -> case happyOut85 happy_x_5 of { happy_var_5 -> happyIn89 (appendDeclrAttrs happy_var_2 (happy_var_5 happy_var_3) ) `HappyStk` happyRest}}} happyReduce_325 = happySpecReduce_2 82# happyReduction_325 happyReduction_325 happy_x_2 happy_x_1 = case happyOut89 happy_x_1 of { happy_var_1 -> case happyOut128 happy_x_2 of { happy_var_2 -> happyIn89 (appendDeclrAttrs happy_var_2 happy_var_1 )}} happyReduce_326 = happyMonadReduce 1# 83# happyReduction_326 happyReduction_326 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut115 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CInitExpr happy_var_1)} ) (\r -> happyReturn (happyIn90 r)) happyReduce_327 = happyMonadReduce 3# 83# happyReduction_327 happyReduction_327 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut92 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CInitList (reverse happy_var_2))}} ) (\r -> happyReturn (happyIn90 r)) happyReduce_328 = happyMonadReduce 4# 83# happyReduction_328 happyReduction_328 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut92 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CInitList (reverse happy_var_2))}} ) (\r -> happyReturn (happyIn90 r)) happyReduce_329 = happySpecReduce_0 84# happyReduction_329 happyReduction_329 = happyIn91 (Nothing ) happyReduce_330 = happySpecReduce_2 84# happyReduction_330 happyReduction_330 happy_x_2 happy_x_1 = case happyOut90 happy_x_2 of { happy_var_2 -> happyIn91 (Just happy_var_2 )} happyReduce_331 = happySpecReduce_0 85# happyReduction_331 happyReduction_331 = happyIn92 (empty ) happyReduce_332 = happySpecReduce_1 85# happyReduction_332 happyReduction_332 happy_x_1 = case happyOut90 happy_x_1 of { happy_var_1 -> happyIn92 (singleton ([],happy_var_1) )} happyReduce_333 = happySpecReduce_2 85# happyReduction_333 happyReduction_333 happy_x_2 happy_x_1 = case happyOut93 happy_x_1 of { happy_var_1 -> case happyOut90 happy_x_2 of { happy_var_2 -> happyIn92 (singleton (happy_var_1,happy_var_2) )}} happyReduce_334 = happySpecReduce_3 85# happyReduction_334 happyReduction_334 happy_x_3 happy_x_2 happy_x_1 = case happyOut92 happy_x_1 of { happy_var_1 -> case happyOut90 happy_x_3 of { happy_var_3 -> happyIn92 (happy_var_1 `snoc` ([],happy_var_3) )}} happyReduce_335 = happyReduce 4# 85# happyReduction_335 happyReduction_335 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut92 happy_x_1 of { happy_var_1 -> case happyOut93 happy_x_3 of { happy_var_3 -> case happyOut90 happy_x_4 of { happy_var_4 -> happyIn92 (happy_var_1 `snoc` (happy_var_3,happy_var_4) ) `HappyStk` happyRest}}} happyReduce_336 = happySpecReduce_2 86# happyReduction_336 happyReduction_336 happy_x_2 happy_x_1 = case happyOut94 happy_x_1 of { happy_var_1 -> happyIn93 (reverse happy_var_1 )} happyReduce_337 = happyMonadReduce 2# 86# happyReduction_337 happyReduction_337 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut125 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ \at -> [CMemberDesig happy_var_1 at])} ) (\r -> happyReturn (happyIn93 r)) happyReduce_338 = happySpecReduce_1 86# happyReduction_338 happyReduction_338 happy_x_1 = case happyOut96 happy_x_1 of { happy_var_1 -> happyIn93 ([happy_var_1] )} happyReduce_339 = happySpecReduce_1 87# happyReduction_339 happyReduction_339 happy_x_1 = case happyOut95 happy_x_1 of { happy_var_1 -> happyIn94 (singleton happy_var_1 )} happyReduce_340 = happySpecReduce_2 87# happyReduction_340 happyReduction_340 happy_x_2 happy_x_1 = case happyOut94 happy_x_1 of { happy_var_1 -> case happyOut95 happy_x_2 of { happy_var_2 -> happyIn94 (happy_var_1 `snoc` happy_var_2 )}} happyReduce_341 = happyMonadReduce 3# 88# happyReduction_341 happyReduction_341 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut121 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CArrDesig happy_var_2)}} ) (\r -> happyReturn (happyIn95 r)) happyReduce_342 = happyMonadReduce 2# 88# happyReduction_342 happyReduction_342 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut125 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CMemberDesig happy_var_2)}} ) (\r -> happyReturn (happyIn95 r)) happyReduce_343 = happySpecReduce_1 88# happyReduction_343 happyReduction_343 happy_x_1 = case happyOut96 happy_x_1 of { happy_var_1 -> happyIn95 (happy_var_1 )} happyReduce_344 = happyMonadReduce 5# 89# happyReduction_344 happyReduction_344 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut121 happy_x_2 of { happy_var_2 -> case happyOut121 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ CRangeDesig happy_var_2 happy_var_4)}}} ) (\r -> happyReturn (happyIn96 r)) happyReduce_345 = happyMonadReduce 1# 90# happyReduction_345 happyReduction_345 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { (CTokIdent _ happy_var_1) -> ( withNodeInfo happy_var_1 $ CVar happy_var_1)} ) (\r -> happyReturn (happyIn97 r)) happyReduce_346 = happySpecReduce_1 90# happyReduction_346 happyReduction_346 happy_x_1 = case happyOut122 happy_x_1 of { happy_var_1 -> happyIn97 (CConst happy_var_1 )} happyReduce_347 = happySpecReduce_1 90# happyReduction_347 happyReduction_347 happy_x_1 = case happyOut123 happy_x_1 of { happy_var_1 -> happyIn97 (CConst (liftStrLit happy_var_1) )} happyReduce_348 = happySpecReduce_3 90# happyReduction_348 happyReduction_348 happy_x_3 happy_x_2 happy_x_1 = case happyOut117 happy_x_2 of { happy_var_2 -> happyIn97 (happy_var_2 )} happyReduce_349 = happyMonadReduce 3# 90# happyReduction_349 happyReduction_349 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut14 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CStatExpr happy_var_2)}} ) (\r -> happyReturn (happyIn97 r)) happyReduce_350 = happyMonadReduce 6# 90# happyReduction_350 happyReduction_350 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut115 happy_x_3 of { happy_var_3 -> case happyOut83 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_1 $ CBuiltinExpr . CBuiltinVaArg happy_var_3 happy_var_5)}}} ) (\r -> happyReturn (happyIn97 r)) happyReduce_351 = happyMonadReduce 6# 90# happyReduction_351 happyReduction_351 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut83 happy_x_3 of { happy_var_3 -> case happyOut98 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_1 $ CBuiltinExpr . CBuiltinOffsetOf happy_var_3 (reverse happy_var_5))}}} ) (\r -> happyReturn (happyIn97 r)) happyReduce_352 = happyMonadReduce 6# 90# happyReduction_352 happyReduction_352 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut83 happy_x_3 of { happy_var_3 -> case happyOut83 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_1 $ CBuiltinExpr . CBuiltinTypesCompatible happy_var_3 happy_var_5)}}} ) (\r -> happyReturn (happyIn97 r)) happyReduce_353 = happyMonadReduce 1# 91# happyReduction_353 happyReduction_353 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut125 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ singleton . CMemberDesig happy_var_1)} ) (\r -> happyReturn (happyIn98 r)) happyReduce_354 = happyMonadReduce 3# 91# happyReduction_354 happyReduction_354 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut98 happy_x_1 of { happy_var_1 -> case happyOut125 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_3 $ (happy_var_1 `snoc`) . CMemberDesig happy_var_3)}} ) (\r -> happyReturn (happyIn98 r)) happyReduce_355 = happyMonadReduce 4# 91# happyReduction_355 happyReduction_355 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut98 happy_x_1 of { happy_var_1 -> case happyOut117 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_3 $ (happy_var_1 `snoc`) . CArrDesig happy_var_3)}} ) (\r -> happyReturn (happyIn98 r)) happyReduce_356 = happySpecReduce_1 92# happyReduction_356 happyReduction_356 happy_x_1 = case happyOut97 happy_x_1 of { happy_var_1 -> happyIn99 (happy_var_1 )} happyReduce_357 = happyMonadReduce 4# 92# happyReduction_357 happyReduction_357 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut99 happy_x_1 of { happy_var_1 -> case happyOut117 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CIndex happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn99 r)) happyReduce_358 = happyMonadReduce 3# 92# happyReduction_358 happyReduction_358 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut99 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CCall happy_var_1 [])} ) (\r -> happyReturn (happyIn99 r)) happyReduce_359 = happyMonadReduce 4# 92# happyReduction_359 happyReduction_359 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut99 happy_x_1 of { happy_var_1 -> case happyOut100 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CCall happy_var_1 (reverse happy_var_3))}} ) (\r -> happyReturn (happyIn99 r)) happyReduce_360 = happyMonadReduce 3# 92# happyReduction_360 happyReduction_360 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut99 happy_x_1 of { happy_var_1 -> case happyOut125 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CMember happy_var_1 happy_var_3 False)}} ) (\r -> happyReturn (happyIn99 r)) happyReduce_361 = happyMonadReduce 3# 92# happyReduction_361 happyReduction_361 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut99 happy_x_1 of { happy_var_1 -> case happyOut125 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CMember happy_var_1 happy_var_3 True)}} ) (\r -> happyReturn (happyIn99 r)) happyReduce_362 = happyMonadReduce 2# 92# happyReduction_362 happyReduction_362 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut99 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CUnary CPostIncOp happy_var_1)} ) (\r -> happyReturn (happyIn99 r)) happyReduce_363 = happyMonadReduce 2# 92# happyReduction_363 happyReduction_363 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut99 happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ CUnary CPostDecOp happy_var_1)} ) (\r -> happyReturn (happyIn99 r)) happyReduce_364 = happyMonadReduce 6# 92# happyReduction_364 happyReduction_364 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut83 happy_x_2 of { happy_var_2 -> case happyOut92 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_1 $ CCompoundLit happy_var_2 (reverse happy_var_5))}}} ) (\r -> happyReturn (happyIn99 r)) happyReduce_365 = happyMonadReduce 7# 92# happyReduction_365 happyReduction_365 (happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut83 happy_x_2 of { happy_var_2 -> case happyOut92 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_1 $ CCompoundLit happy_var_2 (reverse happy_var_5))}}} ) (\r -> happyReturn (happyIn99 r)) happyReduce_366 = happySpecReduce_1 93# happyReduction_366 happyReduction_366 happy_x_1 = case happyOut115 happy_x_1 of { happy_var_1 -> happyIn100 (singleton happy_var_1 )} happyReduce_367 = happySpecReduce_3 93# happyReduction_367 happyReduction_367 happy_x_3 happy_x_2 happy_x_1 = case happyOut100 happy_x_1 of { happy_var_1 -> case happyOut115 happy_x_3 of { happy_var_3 -> happyIn100 (happy_var_1 `snoc` happy_var_3 )}} happyReduce_368 = happySpecReduce_1 94# happyReduction_368 happyReduction_368 happy_x_1 = case happyOut99 happy_x_1 of { happy_var_1 -> happyIn101 (happy_var_1 )} happyReduce_369 = happyMonadReduce 2# 94# happyReduction_369 happyReduction_369 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut101 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CUnary CPreIncOp happy_var_2)}} ) (\r -> happyReturn (happyIn101 r)) happyReduce_370 = happyMonadReduce 2# 94# happyReduction_370 happyReduction_370 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut101 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CUnary CPreDecOp happy_var_2)}} ) (\r -> happyReturn (happyIn101 r)) happyReduce_371 = happySpecReduce_2 94# happyReduction_371 happyReduction_371 happy_x_2 happy_x_1 = case happyOut103 happy_x_2 of { happy_var_2 -> happyIn101 (happy_var_2 )} happyReduce_372 = happyMonadReduce 2# 94# happyReduction_372 happyReduction_372 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut102 happy_x_1 of { happy_var_1 -> case happyOut103 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CUnary (unL happy_var_1) happy_var_2)}} ) (\r -> happyReturn (happyIn101 r)) happyReduce_373 = happyMonadReduce 2# 94# happyReduction_373 happyReduction_373 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut101 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CSizeofExpr happy_var_2)}} ) (\r -> happyReturn (happyIn101 r)) happyReduce_374 = happyMonadReduce 4# 94# happyReduction_374 happyReduction_374 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut83 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CSizeofType happy_var_3)}} ) (\r -> happyReturn (happyIn101 r)) happyReduce_375 = happyMonadReduce 2# 94# happyReduction_375 happyReduction_375 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut101 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CAlignofExpr happy_var_2)}} ) (\r -> happyReturn (happyIn101 r)) happyReduce_376 = happyMonadReduce 4# 94# happyReduction_376 happyReduction_376 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut83 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CAlignofType happy_var_3)}} ) (\r -> happyReturn (happyIn101 r)) happyReduce_377 = happyMonadReduce 2# 94# happyReduction_377 happyReduction_377 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut101 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CComplexReal happy_var_2)}} ) (\r -> happyReturn (happyIn101 r)) happyReduce_378 = happyMonadReduce 2# 94# happyReduction_378 happyReduction_378 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut101 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CComplexImag happy_var_2)}} ) (\r -> happyReturn (happyIn101 r)) happyReduce_379 = happyMonadReduce 2# 94# happyReduction_379 happyReduction_379 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut125 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ CLabAddrExpr happy_var_2)}} ) (\r -> happyReturn (happyIn101 r)) happyReduce_380 = happySpecReduce_1 95# happyReduction_380 happyReduction_380 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn102 (L CAdrOp (posOf happy_var_1) )} happyReduce_381 = happySpecReduce_1 95# happyReduction_381 happyReduction_381 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn102 (L CIndOp (posOf happy_var_1) )} happyReduce_382 = happySpecReduce_1 95# happyReduction_382 happyReduction_382 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn102 (L CPlusOp (posOf happy_var_1) )} happyReduce_383 = happySpecReduce_1 95# happyReduction_383 happyReduction_383 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn102 (L CMinOp (posOf happy_var_1) )} happyReduce_384 = happySpecReduce_1 95# happyReduction_384 happyReduction_384 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn102 (L CCompOp (posOf happy_var_1) )} happyReduce_385 = happySpecReduce_1 95# happyReduction_385 happyReduction_385 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn102 (L CNegOp (posOf happy_var_1) )} happyReduce_386 = happySpecReduce_1 96# happyReduction_386 happyReduction_386 happy_x_1 = case happyOut101 happy_x_1 of { happy_var_1 -> happyIn103 (happy_var_1 )} happyReduce_387 = happyMonadReduce 4# 96# happyReduction_387 happyReduction_387 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut83 happy_x_2 of { happy_var_2 -> case happyOut103 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ CCast happy_var_2 happy_var_4)}}} ) (\r -> happyReturn (happyIn103 r)) happyReduce_388 = happySpecReduce_1 97# happyReduction_388 happyReduction_388 happy_x_1 = case happyOut103 happy_x_1 of { happy_var_1 -> happyIn104 (happy_var_1 )} happyReduce_389 = happyMonadReduce 3# 97# happyReduction_389 happyReduction_389 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut104 happy_x_1 of { happy_var_1 -> case happyOut103 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CMulOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn104 r)) happyReduce_390 = happyMonadReduce 3# 97# happyReduction_390 happyReduction_390 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut104 happy_x_1 of { happy_var_1 -> case happyOut103 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CDivOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn104 r)) happyReduce_391 = happyMonadReduce 3# 97# happyReduction_391 happyReduction_391 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut104 happy_x_1 of { happy_var_1 -> case happyOut103 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CRmdOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn104 r)) happyReduce_392 = happySpecReduce_1 98# happyReduction_392 happyReduction_392 happy_x_1 = case happyOut104 happy_x_1 of { happy_var_1 -> happyIn105 (happy_var_1 )} happyReduce_393 = happyMonadReduce 3# 98# happyReduction_393 happyReduction_393 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut105 happy_x_1 of { happy_var_1 -> case happyOut104 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CAddOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn105 r)) happyReduce_394 = happyMonadReduce 3# 98# happyReduction_394 happyReduction_394 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut105 happy_x_1 of { happy_var_1 -> case happyOut104 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CSubOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn105 r)) happyReduce_395 = happySpecReduce_1 99# happyReduction_395 happyReduction_395 happy_x_1 = case happyOut105 happy_x_1 of { happy_var_1 -> happyIn106 (happy_var_1 )} happyReduce_396 = happyMonadReduce 3# 99# happyReduction_396 happyReduction_396 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut106 happy_x_1 of { happy_var_1 -> case happyOut105 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CShlOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn106 r)) happyReduce_397 = happyMonadReduce 3# 99# happyReduction_397 happyReduction_397 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut106 happy_x_1 of { happy_var_1 -> case happyOut105 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CShrOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn106 r)) happyReduce_398 = happySpecReduce_1 100# happyReduction_398 happyReduction_398 happy_x_1 = case happyOut106 happy_x_1 of { happy_var_1 -> happyIn107 (happy_var_1 )} happyReduce_399 = happyMonadReduce 3# 100# happyReduction_399 happyReduction_399 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut107 happy_x_1 of { happy_var_1 -> case happyOut106 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CLeOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn107 r)) happyReduce_400 = happyMonadReduce 3# 100# happyReduction_400 happyReduction_400 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut107 happy_x_1 of { happy_var_1 -> case happyOut106 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CGrOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn107 r)) happyReduce_401 = happyMonadReduce 3# 100# happyReduction_401 happyReduction_401 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut107 happy_x_1 of { happy_var_1 -> case happyOut106 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CLeqOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn107 r)) happyReduce_402 = happyMonadReduce 3# 100# happyReduction_402 happyReduction_402 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut107 happy_x_1 of { happy_var_1 -> case happyOut106 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CGeqOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn107 r)) happyReduce_403 = happySpecReduce_1 101# happyReduction_403 happyReduction_403 happy_x_1 = case happyOut107 happy_x_1 of { happy_var_1 -> happyIn108 (happy_var_1 )} happyReduce_404 = happyMonadReduce 3# 101# happyReduction_404 happyReduction_404 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut108 happy_x_1 of { happy_var_1 -> case happyOut107 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CEqOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn108 r)) happyReduce_405 = happyMonadReduce 3# 101# happyReduction_405 happyReduction_405 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut108 happy_x_1 of { happy_var_1 -> case happyOut107 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CNeqOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn108 r)) happyReduce_406 = happySpecReduce_1 102# happyReduction_406 happyReduction_406 happy_x_1 = case happyOut108 happy_x_1 of { happy_var_1 -> happyIn109 (happy_var_1 )} happyReduce_407 = happyMonadReduce 3# 102# happyReduction_407 happyReduction_407 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut109 happy_x_1 of { happy_var_1 -> case happyOut108 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CAndOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn109 r)) happyReduce_408 = happySpecReduce_1 103# happyReduction_408 happyReduction_408 happy_x_1 = case happyOut109 happy_x_1 of { happy_var_1 -> happyIn110 (happy_var_1 )} happyReduce_409 = happyMonadReduce 3# 103# happyReduction_409 happyReduction_409 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut110 happy_x_1 of { happy_var_1 -> case happyOut109 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CXorOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn110 r)) happyReduce_410 = happySpecReduce_1 104# happyReduction_410 happyReduction_410 happy_x_1 = case happyOut110 happy_x_1 of { happy_var_1 -> happyIn111 (happy_var_1 )} happyReduce_411 = happyMonadReduce 3# 104# happyReduction_411 happyReduction_411 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut111 happy_x_1 of { happy_var_1 -> case happyOut110 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary COrOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn111 r)) happyReduce_412 = happySpecReduce_1 105# happyReduction_412 happyReduction_412 happy_x_1 = case happyOut111 happy_x_1 of { happy_var_1 -> happyIn112 (happy_var_1 )} happyReduce_413 = happyMonadReduce 3# 105# happyReduction_413 happyReduction_413 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut112 happy_x_1 of { happy_var_1 -> case happyOut111 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CLndOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn112 r)) happyReduce_414 = happySpecReduce_1 106# happyReduction_414 happyReduction_414 happy_x_1 = case happyOut112 happy_x_1 of { happy_var_1 -> happyIn113 (happy_var_1 )} happyReduce_415 = happyMonadReduce 3# 106# happyReduction_415 happyReduction_415 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut113 happy_x_1 of { happy_var_1 -> case happyOut112 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CBinary CLorOp happy_var_1 happy_var_3)}} ) (\r -> happyReturn (happyIn113 r)) happyReduce_416 = happySpecReduce_1 107# happyReduction_416 happyReduction_416 happy_x_1 = case happyOut113 happy_x_1 of { happy_var_1 -> happyIn114 (happy_var_1 )} happyReduce_417 = happyMonadReduce 5# 107# happyReduction_417 happyReduction_417 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut113 happy_x_1 of { happy_var_1 -> case happyOut117 happy_x_3 of { happy_var_3 -> case happyOut114 happy_x_5 of { happy_var_5 -> ( withNodeInfo happy_var_1 $ CCond happy_var_1 (Just happy_var_3) happy_var_5)}}} ) (\r -> happyReturn (happyIn114 r)) happyReduce_418 = happyMonadReduce 4# 107# happyReduction_418 happyReduction_418 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut113 happy_x_1 of { happy_var_1 -> case happyOut114 happy_x_4 of { happy_var_4 -> ( withNodeInfo happy_var_1 $ CCond happy_var_1 Nothing happy_var_4)}} ) (\r -> happyReturn (happyIn114 r)) happyReduce_419 = happySpecReduce_1 108# happyReduction_419 happyReduction_419 happy_x_1 = case happyOut114 happy_x_1 of { happy_var_1 -> happyIn115 (happy_var_1 )} happyReduce_420 = happyMonadReduce 3# 108# happyReduction_420 happyReduction_420 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut101 happy_x_1 of { happy_var_1 -> case happyOut116 happy_x_2 of { happy_var_2 -> case happyOut115 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ CAssign (unL happy_var_2) happy_var_1 happy_var_3)}}} ) (\r -> happyReturn (happyIn115 r)) happyReduce_421 = happySpecReduce_1 109# happyReduction_421 happyReduction_421 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn116 (L CAssignOp (posOf happy_var_1) )} happyReduce_422 = happySpecReduce_1 109# happyReduction_422 happyReduction_422 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn116 (L CMulAssOp (posOf happy_var_1) )} happyReduce_423 = happySpecReduce_1 109# happyReduction_423 happyReduction_423 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn116 (L CDivAssOp (posOf happy_var_1) )} happyReduce_424 = happySpecReduce_1 109# happyReduction_424 happyReduction_424 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn116 (L CRmdAssOp (posOf happy_var_1) )} happyReduce_425 = happySpecReduce_1 109# happyReduction_425 happyReduction_425 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn116 (L CAddAssOp (posOf happy_var_1) )} happyReduce_426 = happySpecReduce_1 109# happyReduction_426 happyReduction_426 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn116 (L CSubAssOp (posOf happy_var_1) )} happyReduce_427 = happySpecReduce_1 109# happyReduction_427 happyReduction_427 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn116 (L CShlAssOp (posOf happy_var_1) )} happyReduce_428 = happySpecReduce_1 109# happyReduction_428 happyReduction_428 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn116 (L CShrAssOp (posOf happy_var_1) )} happyReduce_429 = happySpecReduce_1 109# happyReduction_429 happyReduction_429 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn116 (L CAndAssOp (posOf happy_var_1) )} happyReduce_430 = happySpecReduce_1 109# happyReduction_430 happyReduction_430 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn116 (L CXorAssOp (posOf happy_var_1) )} happyReduce_431 = happySpecReduce_1 109# happyReduction_431 happyReduction_431 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn116 (L COrAssOp (posOf happy_var_1) )} happyReduce_432 = happySpecReduce_1 110# happyReduction_432 happyReduction_432 happy_x_1 = case happyOut115 happy_x_1 of { happy_var_1 -> happyIn117 (happy_var_1 )} happyReduce_433 = happyMonadReduce 3# 110# happyReduction_433 happyReduction_433 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOut115 happy_x_1 of { happy_var_1 -> case happyOut118 happy_x_3 of { happy_var_3 -> ( let es = reverse happy_var_3 in withNodeInfo es $ CComma (happy_var_1:es))}} ) (\r -> happyReturn (happyIn117 r)) happyReduce_434 = happySpecReduce_1 111# happyReduction_434 happyReduction_434 happy_x_1 = case happyOut115 happy_x_1 of { happy_var_1 -> happyIn118 (singleton happy_var_1 )} happyReduce_435 = happySpecReduce_3 111# happyReduction_435 happyReduction_435 happy_x_3 happy_x_2 happy_x_1 = case happyOut118 happy_x_1 of { happy_var_1 -> case happyOut115 happy_x_3 of { happy_var_3 -> happyIn118 (happy_var_1 `snoc` happy_var_3 )}} happyReduce_436 = happySpecReduce_0 112# happyReduction_436 happyReduction_436 = happyIn119 (Nothing ) happyReduce_437 = happySpecReduce_1 112# happyReduction_437 happyReduction_437 happy_x_1 = case happyOut117 happy_x_1 of { happy_var_1 -> happyIn119 (Just happy_var_1 )} happyReduce_438 = happySpecReduce_0 113# happyReduction_438 happyReduction_438 = happyIn120 (Nothing ) happyReduce_439 = happySpecReduce_1 113# happyReduction_439 happyReduction_439 happy_x_1 = case happyOut115 happy_x_1 of { happy_var_1 -> happyIn120 (Just happy_var_1 )} happyReduce_440 = happySpecReduce_1 114# happyReduction_440 happyReduction_440 happy_x_1 = case happyOut114 happy_x_1 of { happy_var_1 -> happyIn121 (happy_var_1 )} happyReduce_441 = happyMonadReduce 1# 115# happyReduction_441 happyReduction_441 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ case happy_var_1 of CTokILit _ i -> CIntConst i)} ) (\r -> happyReturn (happyIn122 r)) happyReduce_442 = happyMonadReduce 1# 115# happyReduction_442 happyReduction_442 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ case happy_var_1 of CTokCLit _ c -> CCharConst c)} ) (\r -> happyReturn (happyIn122 r)) happyReduce_443 = happyMonadReduce 1# 115# happyReduction_443 happyReduction_443 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ case happy_var_1 of CTokFLit _ f -> CFloatConst f)} ) (\r -> happyReturn (happyIn122 r)) happyReduce_444 = happyMonadReduce 1# 116# happyReduction_444 happyReduction_444 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ case happy_var_1 of CTokSLit _ s -> CStrLit s)} ) (\r -> happyReturn (happyIn123 r)) happyReduce_445 = happyMonadReduce 2# 116# happyReduction_445 happyReduction_445 (happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> case happyOut124 happy_x_2 of { happy_var_2 -> ( withNodeInfo happy_var_1 $ case happy_var_1 of CTokSLit _ s -> CStrLit (concatCStrings (s : reverse happy_var_2)))}} ) (\r -> happyReturn (happyIn123 r)) happyReduce_446 = happySpecReduce_1 117# happyReduction_446 happyReduction_446 happy_x_1 = case happyOutTok happy_x_1 of { happy_var_1 -> happyIn124 (case happy_var_1 of CTokSLit _ s -> singleton s )} happyReduce_447 = happySpecReduce_2 117# happyReduction_447 happyReduction_447 happy_x_2 happy_x_1 = case happyOut124 happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { happy_var_2 -> happyIn124 (case happy_var_2 of CTokSLit _ s -> happy_var_1 `snoc` s )}} happyReduce_448 = happySpecReduce_1 118# happyReduction_448 happyReduction_448 happy_x_1 = case happyOutTok happy_x_1 of { (CTokIdent _ happy_var_1) -> happyIn125 (happy_var_1 )} happyReduce_449 = happySpecReduce_1 118# happyReduction_449 happyReduction_449 happy_x_1 = case happyOutTok happy_x_1 of { (CTokTyIdent _ happy_var_1) -> happyIn125 (happy_var_1 )} happyReduce_450 = happySpecReduce_0 119# happyReduction_450 happyReduction_450 = happyIn126 ([] ) happyReduce_451 = happySpecReduce_1 119# happyReduction_451 happyReduction_451 happy_x_1 = case happyOut127 happy_x_1 of { happy_var_1 -> happyIn126 (happy_var_1 )} happyReduce_452 = happySpecReduce_1 120# happyReduction_452 happyReduction_452 happy_x_1 = case happyOut128 happy_x_1 of { happy_var_1 -> happyIn127 (happy_var_1 )} happyReduce_453 = happySpecReduce_2 120# happyReduction_453 happyReduction_453 happy_x_2 happy_x_1 = case happyOut127 happy_x_1 of { happy_var_1 -> case happyOut128 happy_x_2 of { happy_var_2 -> happyIn127 (happy_var_1 ++ happy_var_2 )}} happyReduce_454 = happyReduce 6# 121# happyReduction_454 happyReduction_454 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) = case happyOut129 happy_x_4 of { happy_var_4 -> happyIn128 (reverse happy_var_4 ) `HappyStk` happyRest} happyReduce_455 = happySpecReduce_1 122# happyReduction_455 happyReduction_455 happy_x_1 = case happyOut130 happy_x_1 of { happy_var_1 -> happyIn129 (case happy_var_1 of Nothing -> empty; Just attr -> singleton attr )} happyReduce_456 = happySpecReduce_3 122# happyReduction_456 happyReduction_456 happy_x_3 happy_x_2 happy_x_1 = case happyOut129 happy_x_1 of { happy_var_1 -> case happyOut130 happy_x_3 of { happy_var_3 -> happyIn129 ((maybe id (flip snoc) happy_var_3) happy_var_1 )}} happyReduce_457 = happySpecReduce_0 123# happyReduction_457 happyReduction_457 = happyIn130 (Nothing ) happyReduce_458 = happyMonadReduce 1# 123# happyReduction_458 happyReduction_458 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { (CTokIdent _ happy_var_1) -> ( withNodeInfo happy_var_1 $ Just . CAttr happy_var_1 [])} ) (\r -> happyReturn (happyIn130 r)) happyReduce_459 = happyMonadReduce 1# 123# happyReduction_459 happyReduction_459 (happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { happy_var_1 -> ( withNodeInfo happy_var_1 $ Just . CAttr (internalIdent "const") [])} ) (\r -> happyReturn (happyIn130 r)) happyReduce_460 = happyMonadReduce 4# 123# happyReduction_460 happyReduction_460 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { (CTokIdent _ happy_var_1) -> case happyOut131 happy_x_3 of { happy_var_3 -> ( withNodeInfo happy_var_1 $ Just . CAttr happy_var_1 (reverse happy_var_3))}} ) (\r -> happyReturn (happyIn130 r)) happyReduce_461 = happyMonadReduce 3# 123# happyReduction_461 happyReduction_461 (happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk` happyRest) tk = happyThen (case happyOutTok happy_x_1 of { (CTokIdent _ happy_var_1) -> ( withNodeInfo happy_var_1 $ Just . CAttr happy_var_1 [])} ) (\r -> happyReturn (happyIn130 r)) happyReduce_462 = happySpecReduce_1 124# happyReduction_462 happyReduction_462 happy_x_1 = case happyOut121 happy_x_1 of { happy_var_1 -> happyIn131 (singleton happy_var_1 )} happyReduce_463 = happySpecReduce_3 124# happyReduction_463 happyReduction_463 happy_x_3 happy_x_2 happy_x_1 = case happyOut131 happy_x_1 of { happy_var_1 -> case happyOut121 happy_x_3 of { happy_var_3 -> happyIn131 (happy_var_1 `snoc` happy_var_3 )}} happyNewToken action sts stk = lexC(\tk -> let cont i = happyDoAction i tk action sts stk in case tk of { CTokEof -> happyDoAction 101# tk action sts stk; CTokLParen _ -> cont 1#; CTokRParen _ -> cont 2#; CTokLBracket _ -> cont 3#; CTokRBracket _ -> cont 4#; CTokArrow _ -> cont 5#; CTokDot _ -> cont 6#; CTokExclam _ -> cont 7#; CTokTilde _ -> cont 8#; CTokInc _ -> cont 9#; CTokDec _ -> cont 10#; CTokPlus _ -> cont 11#; CTokMinus _ -> cont 12#; CTokStar _ -> cont 13#; CTokSlash _ -> cont 14#; CTokPercent _ -> cont 15#; CTokAmper _ -> cont 16#; CTokShiftL _ -> cont 17#; CTokShiftR _ -> cont 18#; CTokLess _ -> cont 19#; CTokLessEq _ -> cont 20#; CTokHigh _ -> cont 21#; CTokHighEq _ -> cont 22#; CTokEqual _ -> cont 23#; CTokUnequal _ -> cont 24#; CTokHat _ -> cont 25#; CTokBar _ -> cont 26#; CTokAnd _ -> cont 27#; CTokOr _ -> cont 28#; CTokQuest _ -> cont 29#; CTokColon _ -> cont 30#; CTokAssign _ -> cont 31#; CTokPlusAss _ -> cont 32#; CTokMinusAss _ -> cont 33#; CTokStarAss _ -> cont 34#; CTokSlashAss _ -> cont 35#; CTokPercAss _ -> cont 36#; CTokAmpAss _ -> cont 37#; CTokHatAss _ -> cont 38#; CTokBarAss _ -> cont 39#; CTokSLAss _ -> cont 40#; CTokSRAss _ -> cont 41#; CTokComma _ -> cont 42#; CTokSemic _ -> cont 43#; CTokLBrace _ -> cont 44#; CTokRBrace _ -> cont 45#; CTokEllipsis _ -> cont 46#; CTokAlignof _ -> cont 47#; CTokAsm _ -> cont 48#; CTokAuto _ -> cont 49#; CTokBreak _ -> cont 50#; CTokBool _ -> cont 51#; CTokCase _ -> cont 52#; CTokChar _ -> cont 53#; CTokConst _ -> cont 54#; CTokContinue _ -> cont 55#; CTokComplex _ -> cont 56#; CTokDefault _ -> cont 57#; CTokDo _ -> cont 58#; CTokDouble _ -> cont 59#; CTokElse _ -> cont 60#; CTokEnum _ -> cont 61#; CTokExtern _ -> cont 62#; CTokFloat _ -> cont 63#; CTokFor _ -> cont 64#; CTokGoto _ -> cont 65#; CTokIf _ -> cont 66#; CTokInline _ -> cont 67#; CTokInt _ -> cont 68#; CTokLong _ -> cont 69#; CTokLabel _ -> cont 70#; CTokRegister _ -> cont 71#; CTokRestrict _ -> cont 72#; CTokReturn _ -> cont 73#; CTokShort _ -> cont 74#; CTokSigned _ -> cont 75#; CTokSizeof _ -> cont 76#; CTokStatic _ -> cont 77#; CTokStruct _ -> cont 78#; CTokSwitch _ -> cont 79#; CTokTypedef _ -> cont 80#; CTokTypeof _ -> cont 81#; CTokThread _ -> cont 82#; CTokUnion _ -> cont 83#; CTokUnsigned _ -> cont 84#; CTokVoid _ -> cont 85#; CTokVolatile _ -> cont 86#; CTokWhile _ -> cont 87#; CTokCLit _ _ -> cont 88#; CTokILit _ _ -> cont 89#; CTokFLit _ _ -> cont 90#; CTokSLit _ _ -> cont 91#; CTokIdent _ happy_dollar_dollar -> cont 92#; CTokTyIdent _ happy_dollar_dollar -> cont 93#; CTokGnuC GnuCAttrTok _ -> cont 94#; CTokGnuC GnuCExtTok _ -> cont 95#; CTokGnuC GnuCComplexReal _ -> cont 96#; CTokGnuC GnuCComplexImag _ -> cont 97#; CTokGnuC GnuCVaArg _ -> cont 98#; CTokGnuC GnuCOffsetof _ -> cont 99#; CTokGnuC GnuCTyCompat _ -> cont 100#; _ -> happyError' tk }) happyError_ tk = happyError' tk happyThen :: () => P a -> (a -> P b) -> P b happyThen = (>>=) happyReturn :: () => a -> P a happyReturn = (return) happyThen1 = happyThen happyReturn1 :: () => a -> P a happyReturn1 = happyReturn happyError' :: () => CToken -> P a happyError' tk = (\token -> happyError) tk translation_unit = happySomeParser where happySomeParser = happyThen (happyParse 0#) (\x -> happyReturn (happyOut7 x)) external_declaration = happySomeParser where happySomeParser = happyThen (happyParse 1#) (\x -> happyReturn (happyOut9 x)) statement = happySomeParser where happySomeParser = happyThen (happyParse 2#) (\x -> happyReturn (happyOut12 x)) expression = happySomeParser where happySomeParser = happyThen (happyParse 3#) (\x -> happyReturn (happyOut117 x)) happySeq = happyDontSeq -- sometimes it is neccessary to reverse an unreversed list reverseList :: [a] -> Reversed [a] reverseList = Reversed . List.reverse -- We occasionally need things to have a location when they don't naturally -- have one built in as tokens and most AST elements do. -- data Located a = L !a !Position unL :: Located a -> a unL (L a pos) = a instance Pos (Located a) where posOf (L _ pos) = pos -- FIXME: the next 3 inlines here increase the object file size by 70% -- Check whether the speed win is worth it {-# INLINE withNodeInfo #-} withNodeInfo :: Pos node => node -> (NodeInfo -> a) -> P a withNodeInfo node mkAttrNode = do name <- getNewName lastTok <- getSavedToken let firstPos = posOf node let attrs = mkNodeInfo' firstPos (posLenOfTok $! lastTok) name attrs `seq` return (mkAttrNode attrs) {-# INLINE withLength #-} withLength :: NodeInfo -> (NodeInfo -> a) -> P a withLength nodeinfo mkAttrNode = do lastTok <- getSavedToken let firstPos = posOfNode nodeinfo let attrs = mkNodeInfo' firstPos (posLenOfTok $! lastTok) (maybe (error "nameOfNode") id (nameOfNode nodeinfo)) attrs `seq` return (mkAttrNode attrs) data CDeclrR = CDeclrR (Maybe Ident) (Reversed [CDerivedDeclr]) (Maybe CStrLit) [CAttr] NodeInfo reverseDeclr :: CDeclrR -> CDeclr reverseDeclr (CDeclrR ide reversedDDs asmname cattrs at) = CDeclr ide (reverse reversedDDs) asmname cattrs at instance CNode (CDeclrR) where nodeInfo (CDeclrR _ _ _ _ n) = n instance Pos (CDeclrR) where posOf (CDeclrR _ _ _ _ n) = posOf n {-# INLINE withAttribute #-} withAttribute :: Pos node => node -> [CAttr] -> (NodeInfo -> CDeclrR) -> P CDeclrR withAttribute node cattrs mkDeclrNode = do name <- getNewName let attrs = mkNodeInfo (posOf node) name let newDeclr = appendDeclrAttrs cattrs $ mkDeclrNode attrs attrs `seq` newDeclr `seq` return newDeclr -- postfixing variant {-# INLINE withAttributePF #-} withAttributePF :: Pos node => node -> [CAttr] -> (NodeInfo -> CDeclrR -> CDeclrR) -> P (CDeclrR -> CDeclrR) withAttributePF node cattrs mkDeclrCtor = do name <- getNewName let attrs = mkNodeInfo (posOf node) name let newDeclr = appendDeclrAttrs cattrs . mkDeclrCtor attrs attrs `seq` newDeclr `seq` return newDeclr -- add top level attributes for a declarator. -- -- In the following example -- -- > int declr1, __attribute__((a1)) * __attribute__((a2)) y() __asm__("$" "y") __attribute__((a3)); -- -- the attributes `a1' and `a3' are top-level attributes for y. -- The (pseudo)-AST for the second declarator is -- -- > CDeclr "y" -- > [CFunDeclr ..., CPtrDeclr __attribute__((a2)) ... ] -- > (asm "$y") -- > [__attribute__((a1)), __attribute__((a3)) ] -- -- So assembler names and preceeding and trailing attributes are recorded in object declarator. -- appendObjAttrs :: [CAttr] -> CDeclr -> CDeclr appendObjAttrs newAttrs (CDeclr ident indirections asmname cAttrs at) = CDeclr ident indirections asmname (cAttrs ++ newAttrs) at appendObjAttrsR :: [CAttr] -> CDeclrR -> CDeclrR appendObjAttrsR newAttrs (CDeclrR ident indirections asmname cAttrs at) = CDeclrR ident indirections asmname (cAttrs ++ newAttrs) at setAsmName :: Maybe CStrLit -> CDeclrR -> P CDeclrR setAsmName mAsmName (CDeclrR ident indirections oldName cattrs at) = case combineName mAsmName oldName of Left (n1,n2) -> failP (posOf n2) ["Duplicate assembler name: ",showName n1,showName n2] Right newName -> return $ CDeclrR ident indirections newName cattrs at where combineName Nothing Nothing = Right Nothing combineName Nothing oldname@(Just _) = Right oldname combineName newname@(Just _) Nothing = Right newname combineName (Just n1) (Just n2) = Left (n1,n2) showName (CStrLit cstr _) = show cstr withAsmNameAttrs :: (Maybe CStrLit, [CAttr]) -> CDeclrR -> P CDeclrR withAsmNameAttrs (mAsmName, newAttrs) declr = setAsmName mAsmName (appendObjAttrsR newAttrs declr) appendDeclrAttrs :: [CAttr] -> CDeclrR -> CDeclrR appendDeclrAttrs newAttrs (CDeclrR ident (Reversed []) asmname cattrs at) = CDeclrR ident empty asmname (cattrs ++ newAttrs) at appendDeclrAttrs newAttrs (CDeclrR ident (Reversed (x:xs)) asmname cattrs at) = CDeclrR ident (Reversed (appendAttrs x : xs)) asmname cattrs at where appendAttrs (CPtrDeclr typeQuals at) = CPtrDeclr (typeQuals ++ map CAttrQual newAttrs) at appendAttrs (CArrDeclr typeQuals arraySize at) = CArrDeclr (typeQuals ++ map CAttrQual newAttrs) arraySize at appendAttrs (CFunDeclr parameters cattrs at) = CFunDeclr parameters (cattrs ++ newAttrs) at ptrDeclr :: CDeclrR -> [CTypeQual] -> NodeInfo -> CDeclrR ptrDeclr (CDeclrR ident derivedDeclrs asmname cattrs dat) tyquals at = CDeclrR ident (derivedDeclrs `snoc` CPtrDeclr tyquals at) asmname cattrs dat funDeclr :: CDeclrR -> (Either [Ident] ([CDecl],Bool)) -> [CAttr] -> NodeInfo -> CDeclrR funDeclr (CDeclrR ident derivedDeclrs asmname dcattrs dat) params cattrs at = CDeclrR ident (derivedDeclrs `snoc` CFunDeclr params cattrs at) asmname dcattrs dat arrDeclr :: CDeclrR -> [CTypeQual] -> Bool -> Bool -> Maybe CExpr -> NodeInfo -> CDeclrR arrDeclr (CDeclrR ident derivedDeclrs asmname cattrs dat) tyquals var_sized static_size size_expr_opt at = arr_sz `seq` ( CDeclrR ident (derivedDeclrs `snoc` CArrDeclr tyquals arr_sz at) asmname cattrs dat ) where arr_sz = case size_expr_opt of Just e -> CArrSize static_size e Nothing -> CNoArrSize var_sized liftTypeQuals :: Reversed [CTypeQual] -> [CDeclSpec] liftTypeQuals = map CTypeQual . reverse -- lift CAttrs to DeclSpecs -- liftCAttrs :: [CAttr] -> [CDeclSpec] liftCAttrs = map (CTypeQual . CAttrQual) -- when we parsed (decl_spec_1,...,decl_spec_n,attrs), add the __attributes__s to the declspec list -- needs special care when @decl_spec_n@ is a SUE definition addTrailingAttrs :: Reversed [CDeclSpec] -> [CAttr] -> Reversed [CDeclSpec] addTrailingAttrs declspecs new_attrs = case viewr declspecs of (specs_init, CTypeSpec (CSUType (CStruct tag name (Just def) def_attrs su_node) node)) -> (specs_init `snoc` CTypeSpec (CSUType (CStruct tag name (Just def) (def_attrs ++ new_attrs) su_node) node)) (specs_init, CTypeSpec (CEnumType (CEnum name (Just def) def_attrs e_node) node)) -> (specs_init `snoc` CTypeSpec (CEnumType (CEnum name (Just def) (def_attrs ++ new_attrs) e_node) node)) _ -> declspecs `rappend` (liftCAttrs new_attrs) -- convenient instance, the position of a list of things is the position of -- the first thing in the list -- instance Pos a => Pos [a] where posOf (x:_) = posOf x instance Pos a => Pos (Reversed a) where posOf (Reversed x) = posOf x emptyDeclr :: CDeclrR emptyDeclr = CDeclrR Nothing empty Nothing [] undefNode mkVarDeclr :: Ident -> NodeInfo -> CDeclrR mkVarDeclr ident = CDeclrR (Just ident) empty Nothing [] -- Take the identifiers and use them to update the typedef'ed identifier set -- if the decl is defining a typedef then we add it to the set, -- if it's a var decl then that shadows typedefed identifiers -- doDeclIdent :: [CDeclSpec] -> CDeclrR -> P () doDeclIdent declspecs (CDeclrR mIdent _ _ _ _) = case mIdent of Nothing -> return () Just ident | any iypedef declspecs -> addTypedef ident | otherwise -> shadowTypedef ident where iypedef (CStorageSpec (CTypedef _)) = True iypedef _ = False doFuncParamDeclIdent :: CDeclr -> P () doFuncParamDeclIdent (CDeclr _ (CFunDeclr params _ _ : _) _ _ _) = sequence_ [ case getCDeclrIdent declr of Nothing -> return () Just ident -> shadowTypedef ident | CDecl _ dle _ <- either (const []) fst params , (Just declr, _, _) <- dle ] doFuncParamDeclIdent _ = return () -- extract all identifiers getCDeclrIdent :: CDeclr -> Maybe Ident getCDeclrIdent (CDeclr mIdent _ _ _ _) = mIdent happyError :: P a happyError = parseError -- * public interface -- | @parseC input initialPos@ parses the given preprocessed C-source input and returns the AST or a list of parse errors. parseC :: InputStream -> Position -> Either ParseError CTranslUnit parseC input initialPosition = fmap fst $ execParser translUnitP input initialPosition builtinTypeNames (namesStartingFrom 0) -- | @translUnitP@ provides a parser for a complete C translation unit, i.e. a list of external declarations. translUnitP :: P CTranslUnit translUnitP = translation_unit -- | @extDeclP@ provides a parser for an external (file-scope) declaration extDeclP :: P CExtDecl extDeclP = external_declaration -- | @statementP@ provides a parser for C statements statementP :: P CStat statementP = statement -- | @expressionP@ provides a parser for C expressions expressionP :: P CExpr expressionP = expression {-# LINE 1 "GenericTemplate.hs" #-} {-# LINE 1 "" #-} {-# LINE 1 "" #-} {-# LINE 1 "GenericTemplate.hs" #-} -- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp {-# LINE 28 "GenericTemplate.hs" #-} data Happy_IntList = HappyCons Int# Happy_IntList {-# LINE 49 "GenericTemplate.hs" #-} {-# LINE 59 "GenericTemplate.hs" #-} {-# LINE 68 "GenericTemplate.hs" #-} infixr 9 `HappyStk` data HappyStk a = HappyStk a (HappyStk a) ----------------------------------------------------------------------------- -- starting the parse happyParse start_state = happyNewToken start_state notHappyAtAll notHappyAtAll ----------------------------------------------------------------------------- -- Accepting the parse -- If the current token is 0#, it means we've just accepted a partial -- parse (a %partial parser). We must ignore the saved token on the top of -- the stack in this case. happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) = happyReturn1 ans happyAccept j tk st sts (HappyStk ans _) = (happyTcHack j (happyTcHack st)) (happyReturn1 ans) ----------------------------------------------------------------------------- -- Arrays only: do the next action happyDoAction i tk st = {- nothing -} case action of 0# -> {- nothing -} happyFail i tk st -1# -> {- nothing -} happyAccept i tk st n | (n <# (0# :: Int#)) -> {- nothing -} (happyReduceArr ! rule) i tk st where rule = (I# ((negateInt# ((n +# (1# :: Int#)))))) n -> {- nothing -} happyShift new_state i tk st where new_state = (n -# (1# :: Int#)) where off = indexShortOffAddr happyActOffsets st off_i = (off +# i) check = if (off_i >=# (0# :: Int#)) then (indexShortOffAddr happyCheck off_i ==# i) else False action | check = indexShortOffAddr happyTable off_i | otherwise = indexShortOffAddr happyDefActions st {-# LINE 127 "GenericTemplate.hs" #-} indexShortOffAddr (HappyA# arr) off = #if __GLASGOW_HASKELL__ > 500 narrow16Int# i #elif __GLASGOW_HASKELL__ == 500 intToInt16# i #else (i `iShiftL#` 16#) `iShiftRA#` 16# #endif where #if __GLASGOW_HASKELL__ >= 503 i = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low) #else i = word2Int# ((high `shiftL#` 8#) `or#` low) #endif high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#))) low = int2Word# (ord# (indexCharOffAddr# arr off')) off' = off *# 2# data HappyAddr = HappyA# Addr# ----------------------------------------------------------------------------- -- HappyState data type (not arrays) {-# LINE 170 "GenericTemplate.hs" #-} ----------------------------------------------------------------------------- -- Shifting a token happyShift new_state 0# tk st sts stk@(x `HappyStk` _) = let i = (case unsafeCoerce# x of { (I# (i)) -> i }) in -- trace "shifting the error token" $ happyDoAction i tk new_state (HappyCons (st) (sts)) (stk) happyShift new_state i tk st sts stk = happyNewToken new_state (HappyCons (st) (sts)) ((happyInTok (tk))`HappyStk`stk) -- happyReduce is specialised for the common cases. happySpecReduce_0 i fn 0# tk st sts stk = happyFail 0# tk st sts stk happySpecReduce_0 nt fn j tk st@((action)) sts stk = happyGoto nt j tk st (HappyCons (st) (sts)) (fn `HappyStk` stk) happySpecReduce_1 i fn 0# tk st sts stk = happyFail 0# tk st sts stk happySpecReduce_1 nt fn j tk _ sts@((HappyCons (st@(action)) (_))) (v1`HappyStk`stk') = let r = fn v1 in happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk')) happySpecReduce_2 i fn 0# tk st sts stk = happyFail 0# tk st sts stk happySpecReduce_2 nt fn j tk _ (HappyCons (_) (sts@((HappyCons (st@(action)) (_))))) (v1`HappyStk`v2`HappyStk`stk') = let r = fn v1 v2 in happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk')) happySpecReduce_3 i fn 0# tk st sts stk = happyFail 0# tk st sts stk happySpecReduce_3 nt fn j tk _ (HappyCons (_) ((HappyCons (_) (sts@((HappyCons (st@(action)) (_))))))) (v1`HappyStk`v2`HappyStk`v3`HappyStk`stk') = let r = fn v1 v2 v3 in happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk')) happyReduce k i fn 0# tk st sts stk = happyFail 0# tk st sts stk happyReduce k nt fn j tk st sts stk = case happyDrop (k -# (1# :: Int#)) sts of sts1@((HappyCons (st1@(action)) (_))) -> let r = fn stk in -- it doesn't hurt to always seq here... happyDoSeq r (happyGoto nt j tk st1 sts1 r) happyMonadReduce k nt fn 0# tk st sts stk = happyFail 0# tk st sts stk happyMonadReduce k nt fn j tk st sts stk = happyThen1 (fn stk tk) (\r -> happyGoto nt j tk st1 sts1 (r `HappyStk` drop_stk)) where sts1@((HappyCons (st1@(action)) (_))) = happyDrop k (HappyCons (st) (sts)) drop_stk = happyDropStk k stk happyMonad2Reduce k nt fn 0# tk st sts stk = happyFail 0# tk st sts stk happyMonad2Reduce k nt fn j tk st sts stk = happyThen1 (fn stk tk) (\r -> happyNewToken new_state sts1 (r `HappyStk` drop_stk)) where sts1@((HappyCons (st1@(action)) (_))) = happyDrop k (HappyCons (st) (sts)) drop_stk = happyDropStk k stk off = indexShortOffAddr happyGotoOffsets st1 off_i = (off +# nt) new_state = indexShortOffAddr happyTable off_i happyDrop 0# l = l happyDrop n (HappyCons (_) (t)) = happyDrop (n -# (1# :: Int#)) t happyDropStk 0# l = l happyDropStk n (x `HappyStk` xs) = happyDropStk (n -# (1#::Int#)) xs ----------------------------------------------------------------------------- -- Moving to a new state after a reduction happyGoto nt j tk st = {- nothing -} happyDoAction j tk new_state where off = indexShortOffAddr happyGotoOffsets st off_i = (off +# nt) new_state = indexShortOffAddr happyTable off_i ----------------------------------------------------------------------------- -- Error recovery (0# is the error token) -- parse error if we are in recovery and we fail again happyFail 0# tk old_st _ stk = -- trace "failing" $ happyError_ tk {- We don't need state discarding for our restricted implementation of "error". In fact, it can cause some bogus parses, so I've disabled it for now --SDM -- discard a state happyFail 0# tk old_st (HappyCons ((action)) (sts)) (saved_tok `HappyStk` _ `HappyStk` stk) = -- trace ("discarding state, depth " ++ show (length stk)) $ happyDoAction 0# tk action sts ((saved_tok`HappyStk`stk)) -} -- Enter error recovery: generate an error token, -- save the old token and carry on. happyFail i tk (action) sts stk = -- trace "entering error recovery" $ happyDoAction 0# tk action sts ( (unsafeCoerce# (I# (i))) `HappyStk` stk) -- Internal happy errors: notHappyAtAll = error "Internal Happy error\n" ----------------------------------------------------------------------------- -- Hack to get the typechecker to accept our action functions happyTcHack :: Int# -> a -> a happyTcHack x y = y {-# INLINE happyTcHack #-} ----------------------------------------------------------------------------- -- Seq-ing. If the --strict flag is given, then Happy emits -- happySeq = happyDoSeq -- otherwise it emits -- happySeq = happyDontSeq happyDoSeq, happyDontSeq :: a -> b -> b happyDoSeq a b = a `seq` b happyDontSeq a b = b ----------------------------------------------------------------------------- -- Don't inline any functions from the template. GHC has a nasty habit -- of deciding to inline happyGoto everywhere, which increases the size of -- the generated parser quite a bit. {-# NOINLINE happyDoAction #-} {-# NOINLINE happyTable #-} {-# NOINLINE happyCheck #-} {-# NOINLINE happyActOffsets #-} {-# NOINLINE happyGotoOffsets #-} {-# NOINLINE happyDefActions #-} {-# NOINLINE happyShift #-} {-# NOINLINE happySpecReduce_0 #-} {-# NOINLINE happySpecReduce_1 #-} {-# NOINLINE happySpecReduce_2 #-} {-# NOINLINE happySpecReduce_3 #-} {-# NOINLINE happyReduce #-} {-# NOINLINE happyMonadReduce #-} {-# NOINLINE happyGoto #-} {-# NOINLINE happyFail #-} -- end of Happy Template. From deniz.a.m.dogan at gmail.com Fri Jun 19 05:58:26 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Fri Jun 19 05:41:39 2009 Subject: [Haskell-cafe] Re: Running a "sub-process" which dies with the main program In-Reply-To: <7b501d5c0906181256k58c5702ap9e1f80f890e56e79@mail.gmail.com> References: <7b501d5c0906181256k58c5702ap9e1f80f890e56e79@mail.gmail.com> Message-ID: <7b501d5c0906190258j2144940t28e503031b183600@mail.gmail.com> 2009/6/18 Deniz Dogan : > Hi > > I couldn't come up with a better subject than this one, so anyways... > > I have a small program which spawns a subprocess. However, when I hit > C-c, the subprocess won't die, instead it will just keep running until > it's done or until I kill it. I've looked around in System.Process for > something suitable for my needs, but I can't seem to find it. Any > ideas? With a tip from a person outside of the mailing list I found System.Process.system, which essentially does exactly what I was asking for. However, I would really like some more control over what file descriptors the subprocess should use (specifically stdout and stderr). Looking at the source code for System.Process.system, I find that it uses the "syncProcess" function, which would be useful to me, but isn't exported. So why is syncProcess not exported? Is there any good reason not to? -- Deniz Dogan From aycan.irican at core.gen.tr Fri Jun 19 06:31:40 2009 From: aycan.irican at core.gen.tr (Aycan iRiCAN) Date: Fri Jun 19 06:19:07 2009 Subject: [Haskell-cafe] Re: Running a "sub-process" which dies with the main program In-Reply-To: <7b501d5c0906190258j2144940t28e503031b183600@mail.gmail.com> References: <7b501d5c0906181256k58c5702ap9e1f80f890e56e79@mail.gmail.com> <7b501d5c0906190258j2144940t28e503031b183600@mail.gmail.com> Message-ID: <1245407500.22228.27.camel@aycan> Cum, 2009-06-19 tarihinde 11:58 +0200 saatinde, Deniz Dogan yazd?: > 2009/6/18 Deniz Dogan : > > Hi > > > > I couldn't come up with a better subject than this one, so anyways... > > > > I have a small program which spawns a subprocess. However, when I hit > > C-c, the subprocess won't die, instead it will just keep running until > > it's done or until I kill it. I've looked around in System.Process for > > something suitable for my needs, but I can't seem to find it. Any > > ideas? > > With a tip from a person outside of the mailing list I found > System.Process.system, which essentially does exactly what I was > asking for. Hey I'm already subscribed :) You can read from "sout" and "serr" with below example. Hope that it helps. module Main where import System.Process -- using process-1.0.1.1 main = do (_, sout, serr, p) <- createProcess (proc "sleep" ["10"]) { std_out = CreatePipe , std_err = CreatePipe } r <- waitForProcess p return () Regards, -- aycan From deniz.a.m.dogan at gmail.com Fri Jun 19 06:42:51 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Fri Jun 19 06:26:00 2009 Subject: [Haskell-cafe] Re: Running a "sub-process" which dies with the main program In-Reply-To: <1245407500.22228.27.camel@aycan> References: <7b501d5c0906181256k58c5702ap9e1f80f890e56e79@mail.gmail.com> <7b501d5c0906190258j2144940t28e503031b183600@mail.gmail.com> <1245407500.22228.27.camel@aycan> Message-ID: <7b501d5c0906190342l6c942883xb4acc2bbfeb9b67d@mail.gmail.com> 2009/6/19 Aycan iRiCAN : > > Cum, 2009-06-19 tarihinde 11:58 +0200 saatinde, Deniz Dogan yazd?: >> 2009/6/18 Deniz Dogan : >> > Hi >> > >> > I couldn't come up with a better subject than this one, so anyways... >> > >> > I have a small program which spawns a subprocess. However, when I hit >> > C-c, the subprocess won't die, instead it will just keep running until >> > it's done or until I kill it. I've looked around in System.Process for >> > something suitable for my needs, but I can't seem to find it. Any >> > ideas? >> >> With a tip from a person outside of the mailing list I found >> System.Process.system, which essentially does exactly what I was >> asking for. > > Hey I'm already subscribed :) You can read from "sout" and "serr" with > below example. Hope that it helps. > > > module Main where > > import System.Process ?-- using process-1.0.1.1 > > main = do > ?(_, sout, serr, p) <- createProcess (proc "sleep" ["10"]) > ? ? ? ? ? ? ? ? ? ? ? ?{ std_out = CreatePipe > ? ? ? ? ? ? ? ? ? ? ? ?, std_err = CreatePipe } > ?r <- waitForProcess p > ?return () > Thanks! But this was the approach I used before I went to System.Process.system and it did not work on my Linux machine. Looking at the source code for "system", we see that it uses "syncProcess", which has #ifdef mingw32_HOST_OS (IIRC) in which the code you gave me resides. If mingw32_HOST_OS is not defined, one has to go through quite a bit more trouble to get the same effect. This is why it bugs me a bit that syncProcess is not exported. I can't find any reason not to export it, but what do I know? -- Deniz Dogan From aycan.irican at core.gen.tr Fri Jun 19 06:55:20 2009 From: aycan.irican at core.gen.tr (Aycan iRiCAN) Date: Fri Jun 19 06:42:46 2009 Subject: [Haskell-cafe] Re: Running a "sub-process" which dies with the main program In-Reply-To: <7b501d5c0906190342l6c942883xb4acc2bbfeb9b67d@mail.gmail.com> References: <7b501d5c0906181256k58c5702ap9e1f80f890e56e79@mail.gmail.com> <7b501d5c0906190258j2144940t28e503031b183600@mail.gmail.com> <1245407500.22228.27.camel@aycan> <7b501d5c0906190342l6c942883xb4acc2bbfeb9b67d@mail.gmail.com> Message-ID: <1245408920.22228.35.camel@aycan> Cum, 2009-06-19 tarihinde 12:42 +0200 saatinde, Deniz Dogan yazd?: > 2009/6/19 Aycan iRiCAN : > > > > Cum, 2009-06-19 tarihinde 11:58 +0200 saatinde, Deniz Dogan yazd?: > >> 2009/6/18 Deniz Dogan : > >> > Hi > >> > > >> > I couldn't come up with a better subject than this one, so anyways... > >> > > >> > I have a small program which spawns a subprocess. However, when I hit > >> > C-c, the subprocess won't die, instead it will just keep running until > >> > it's done or until I kill it. I've looked around in System.Process for > >> > something suitable for my needs, but I can't seem to find it. Any > >> > ideas? > >> > >> With a tip from a person outside of the mailing list I found > >> System.Process.system, which essentially does exactly what I was > >> asking for. > > > > Hey I'm already subscribed :) You can read from "sout" and "serr" with > > below example. Hope that it helps. > > > > > > module Main where > > > > import System.Process -- using process-1.0.1.1 > > > > main = do > > (_, sout, serr, p) <- createProcess (proc "sleep" ["10"]) > > { std_out = CreatePipe > > , std_err = CreatePipe } > > r <- waitForProcess p > > return () > > > > Thanks! > > But this was the approach I used before I went to > System.Process.system and it did not work on my Linux machine. Give it a try. Try to send CTRL-C and look if "sleep 10" (which is a subprocess) process terminates. aycan@aycan:~/haskell$ time ./deniz2 && ps -ef | grep sleep ^C real 0m0.707s user 0m0.001s sys 0m0.004s aycan 13098 4430 0 13:50:23 pts/7 0:00 grep sleep It terminates with ghc 6.10.3 on OpenSolaris. Best Regards, -- aycan From deniz.a.m.dogan at gmail.com Fri Jun 19 07:09:21 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Fri Jun 19 06:52:31 2009 Subject: [Haskell-cafe] Re: Running a "sub-process" which dies with the main program In-Reply-To: <1245408920.22228.35.camel@aycan> References: <7b501d5c0906181256k58c5702ap9e1f80f890e56e79@mail.gmail.com> <7b501d5c0906190258j2144940t28e503031b183600@mail.gmail.com> <1245407500.22228.27.camel@aycan> <7b501d5c0906190342l6c942883xb4acc2bbfeb9b67d@mail.gmail.com> <1245408920.22228.35.camel@aycan> Message-ID: <7b501d5c0906190409m84b21c2q19e9dd3a7b11db55@mail.gmail.com> 2009/6/19 Aycan iRiCAN : > > Cum, 2009-06-19 tarihinde 12:42 +0200 saatinde, Deniz Dogan yazd?: >> 2009/6/19 Aycan iRiCAN : >> > >> > Cum, 2009-06-19 tarihinde 11:58 +0200 saatinde, Deniz Dogan yazd?: >> >> 2009/6/18 Deniz Dogan : >> >> > Hi >> >> > >> >> > I couldn't come up with a better subject than this one, so anyways... >> >> > >> >> > I have a small program which spawns a subprocess. However, when I hit >> >> > C-c, the subprocess won't die, instead it will just keep running until >> >> > it's done or until I kill it. I've looked around in System.Process for >> >> > something suitable for my needs, but I can't seem to find it. Any >> >> > ideas? >> >> >> >> With a tip from a person outside of the mailing list I found >> >> System.Process.system, which essentially does exactly what I was >> >> asking for. >> > >> > Hey I'm already subscribed :) You can read from "sout" and "serr" with >> > below example. Hope that it helps. >> > >> > >> > module Main where >> > >> > import System.Process ?-- using process-1.0.1.1 >> > >> > main = do >> > ?(_, sout, serr, p) <- createProcess (proc "sleep" ["10"]) >> > ? ? ? ? ? ? ? ? ? ? ? ?{ std_out = CreatePipe >> > ? ? ? ? ? ? ? ? ? ? ? ?, std_err = CreatePipe } >> > ?r <- waitForProcess p >> > ?return () >> > >> >> Thanks! >> >> But this was the approach I used before I went to >> System.Process.system and it did not work on my Linux machine. > > Give it a try. Try to send CTRL-C and look if "sleep 10" (which is a > subprocess) process terminates. > > aycan@aycan:~/haskell$ time ./deniz2 && ps -ef | grep sleep > ^C > real ? ?0m0.707s > user ? ?0m0.001s > sys ? ? 0m0.004s > ? aycan 13098 ?4430 ? 0 13:50:23 pts/7 ? ? ? 0:00 grep sleep > > It terminates with ghc 6.10.3 on OpenSolaris. This is copied verbatim from my terminal. I used the exact some code that you gave me. % time ./test && ps -ef | grep sleep ^C real 0m10.005s user 0m0.003s sys 0m0.003s deniz 14095 14047 0 13:05 pts/1 00:00:00 grep sleep What's strange though is that when I hit C-c *twice*, I get this behavior: time ./test && ps -ef | grep sleep ^C^C real 0m0.915s user 0m0.003s sys 0m0.000s This is with GHC 6.10.3 on Arch Linux i686. -- Deniz Dogan From gue.schmidt at web.de Fri Jun 19 07:33:12 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Fri Jun 19 07:16:36 2009 Subject: [Haskell-cafe] Re: Could someone give me a sample about haskelldb? In-Reply-To: <3bd412d40906190132o569ab851ha139b7e7ab26b8fb@mail.gmail.com> References: <3bd412d40906182224m416f56c4mec1435503eb43548@mail.gmail.com> <3bd412d40906190132o569ab851ha139b7e7ab26b8fb@mail.gmail.com> Message-ID: Hi Magicloud, restrict (t!T.done .<>. constant False) should dot it but your t!T.done confuses me, is the the T.xxx due to an import? also the line 49 does not seem to be right. Would you mind to post your table and column definitions? G?nther Magicloud Magiclouds schrieb: > I changed it, some other problem occured. > 1. How to compare a BoolT column to a True? "t!c .<>. True" could not work. > 2. What shoud I use after "!"? Like table!col, recordset!col, what is col? > Thanks. > > On Fri, Jun 19, 2009 at 1:24 PM, Magicloud > Magiclouds wrote: >> Hi, >> I am learning it following the very few documents on its site. Well, >> I failed, with the import modules, I still cannot compile it. The >> error is on "T.*". >> >> 6 import Database.HaskellDB.HDBC.SQLite3 >> 7 import Database.HaskellDB >> 8 import Database.HaskellDB.DBSpec >> 9 import Database.HaskellDB.DBSpec.PPHelpers >> 10 import Database.HaskellDB.Query >> >> 48 q = do >> 49 t <- table $ Table "notes" [] >> 50 restrict ( t!T.done .<>. False ) >> 51 r <- project ( T.subject << t!T.subject ) >> 52 order [ desc r T.priority >> 53 , desc r T.dt ] >> 54 return r >> -- >> ??????? >> ??????? >> > > > From dvde at gmx.net Fri Jun 19 07:50:16 2009 From: dvde at gmx.net (Daniel van den Eijkel) Date: Fri Jun 19 07:33:29 2009 Subject: [Haskell-cafe] Use MySQL from Haskell In-Reply-To: <29bf512f0906181512i50dec0d9ge04be77ab4e3f668@mail.gmail.com> References: <4A3AB0EA.4090304@googlemail.com> <29bf512f0906181512i50dec0d9ge04be77ab4e3f668@mail.gmail.com> Message-ID: <4A3B7B78.5040207@gmx.net> The same with me - I'm on XP, and HDBC-odbc is the library I got running to access the MySQL database. Regards, Daniel Michael Snoyman schrieb: > Marciej, > > I went the HDBC route and got the same problem. Although it does not > seem to be officially blessed, try installing the time-1.1.3 package. > It's working for me at least, which I know is a dubious recommendation. > > Also, I am currently using the hdbc-odbc package for accessing MySQL. > I couldn't get hdbc-mysql to work properly. I hope that once I get > this project working right, I'll have a chance to dig into the > hdbc-mysql issue itself. > > Good luck! > > Michael > > On Fri, Jun 19, 2009 at 12:26 AM, Maciej Podgurski > > wrote: > > Hello, > > I'm trying to use MySQL from Haskell but it seems impossible for > me to install one of the MySQL packages on my Windows XP machine. > > First I tired to install hsql-mysql-1.7.1 on GHC 6.10.3 but > installing haskelldb-hsql failed with a hidden package error. So I > added the old-time package to the cabal file but there still was a > compile error (something due to the change from Exception to > Exception e => e). > > So I switched to GHC 6.8.3 and tried it again. Now it says: > > Configuring hsql-mysql-1.7.1... > Warning: 'extra-lib-dirs: /usr/lib/mysql' directory does not exist. > Warning: 'include-dirs: /usr/include/mysql' directory does not exist. > Warning: This package indirectly depends on multiple versions of > the same > package. This is highly likely to cause a compile failure. > package process-1.0.0.1 requires filepath-1.1.0.0 > package directory-1.0.0.1 requires filepath-1.1.0.0 > package Cabal-1.6.0.3 requires filepath-1.1.0.2 > Setup: Missing dependency on a foreign library: > * Missing C library: mysqlclient > This problem can usually be solved by installing the system > package that > provides this library (you may need the "-dev" version). If the > library is > already installed but in a non-standard location then you can use > the flags > --extra-include-dirs= and --extra-lib-dirs= to specify where it is. > > There's no Haskell package mysqlclient and I don't know how to > install a C library in Haskell. So I switched to HDBC-2.1.1 and > got the next compile error: > > Building convertible-1.0.5... > > Data/Convertible/Instances/Num.hs:671:0: > warning: no newline at end of file > [...] > [5 of 8] Compiling Data.Convertible.Instances.C ( > Data/Convertible/Instances/C.hs, dist\build/Data/C > onvertible/Instances/C.o ) > [6 of 8] Compiling Data.Convertible.Instances.Time ( > Data/Convertible/Instances/Time.hs, dist\build/ > Data/Convertible/Instances/Time.o ) > > Data/Convertible/Instances/Time.hs:64:0: > Duplicate instance declarations: > instance Typeable NominalDiffTime > -- Defined at Data/Convertible/Instances/Time.hs:(64,0)-(65,42) > instance Typeable NominalDiffTime > -- Defined in time-1.1.3:Data.Time.Clock.UTC > > Data/Convertible/Instances/Time.hs:67:0: > Duplicate instance declarations: > instance Typeable UTCTime > -- Defined at Data/Convertible/Instances/Time.hs:(67,0)-(68,34) > instance Typeable UTCTime > -- Defined in time-1.1.3:Data.Time.Clock.UTC > > So please help me, what GHC/package configuration will I need to > use MySQL from my Haskell programs on Windows? I really like > Haskell but all those "broken" packages are really discouraging. :( > > > Best wishes, > Maciej > _______________________________________________ > 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 quarantedeux42 at yahoo.fr Fri Jun 19 07:51:21 2009 From: quarantedeux42 at yahoo.fr (Fernand) Date: Fri Jun 19 07:34:31 2009 Subject: [Haskell-cafe] Using Parsec with ByteString ? Message-ID: <4A3B7BB9.4040500@yahoo.fr> Hi, May be it's a frequently asked question, but I have been unable to find my way in the parsec-3.0.0 library when trying to write a small parser with Parsec that could work with ByteStrings. I mean, there is the Text.Parsec.ByteString module which allows to parse a file using ByteStrings, but the parser one needs to write must parse ByteStrings instead of Strings (that is, something like having a "Parsec Bytestring ()" type, unless I'm completely misunderstanding the situation). My problem is that I do not manage to write primitive parsing combinators (like string, satisfy, letter, etc.) to define my language's tokens. I'm surely missing some primitive somewhere (may be the Text.Parsec.Prim.token, though I do not really manage to use it). Thanks in advance, F. From aycan.irican at core.gen.tr Fri Jun 19 07:49:58 2009 From: aycan.irican at core.gen.tr (Aycan iRiCAN) Date: Fri Jun 19 07:37:27 2009 Subject: [Haskell-cafe] Re: Running a "sub-process" which dies with the main program In-Reply-To: <7b501d5c0906190409m84b21c2q19e9dd3a7b11db55@mail.gmail.com> References: <7b501d5c0906181256k58c5702ap9e1f80f890e56e79@mail.gmail.com> <7b501d5c0906190258j2144940t28e503031b183600@mail.gmail.com> <1245407500.22228.27.camel@aycan> <7b501d5c0906190342l6c942883xb4acc2bbfeb9b67d@mail.gmail.com> <1245408920.22228.35.camel@aycan> <7b501d5c0906190409m84b21c2q19e9dd3a7b11db55@mail.gmail.com> Message-ID: <1245412198.22228.49.camel@aycan> Cum, 2009-06-19 tarihinde 13:09 +0200 saatinde, Deniz Dogan yazd?: > 2009/6/19 Aycan iRiCAN : > > > > Cum, 2009-06-19 tarihinde 12:42 +0200 saatinde, Deniz Dogan yazd?: > >> 2009/6/19 Aycan iRiCAN : > >> > > >> > Cum, 2009-06-19 tarihinde 11:58 +0200 saatinde, Deniz Dogan yazd?: > >> >> 2009/6/18 Deniz Dogan : > >> >> > Hi > >> >> > > >> >> > I couldn't come up with a better subject than this one, so anyways... > >> >> > > >> >> > I have a small program which spawns a subprocess. However, when I hit > >> >> > C-c, the subprocess won't die, instead it will just keep running until > >> >> > it's done or until I kill it. I've looked around in System.Process for > >> >> > something suitable for my needs, but I can't seem to find it. Any > >> >> > ideas? > >> >> > >> >> With a tip from a person outside of the mailing list I found > >> >> System.Process.system, which essentially does exactly what I was > >> >> asking for. > >> > > >> > Hey I'm already subscribed :) You can read from "sout" and "serr" with > >> > below example. Hope that it helps. > >> > > >> > > >> > module Main where > >> > > >> > import System.Process -- using process-1.0.1.1 > >> > > >> > main = do > >> > (_, sout, serr, p) <- createProcess (proc "sleep" ["10"]) > >> > { std_out = CreatePipe > >> > , std_err = CreatePipe } > >> > r <- waitForProcess p > >> > return () > >> > > >> > >> Thanks! > >> > >> But this was the approach I used before I went to > >> System.Process.system and it did not work on my Linux machine. > > > > Give it a try. Try to send CTRL-C and look if "sleep 10" (which is a > > subprocess) process terminates. > > > > aycan@aycan:~/haskell$ time ./deniz2 && ps -ef | grep sleep > > ^C > > real 0m0.707s > > user 0m0.001s > > sys 0m0.004s > > aycan 13098 4430 0 13:50:23 pts/7 0:00 grep sleep > > > > It terminates with ghc 6.10.3 on OpenSolaris. > > This is copied verbatim from my terminal. I used the exact some code > that you gave me. > > % time ./test && ps -ef | grep sleep > ^C > real 0m10.005s > user 0m0.003s > sys 0m0.003s > deniz 14095 14047 0 13:05 pts/1 00:00:00 grep sleep > > What's strange though is that when I hit C-c *twice*, I get this behavior: Hmm, I think GHC RTS handles SIGINT. I recompiled with thread support and got the same behavour. See: http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Signals When the interrupt signal is received, the default behaviour of the runtime is to attempt to shut down the Haskell program gracefully. It does this by calling interruptStgRts() in rts/Schedule.c (see Commentary/Rts/Scheduler#ShuttingDown). If a second interrupt signal is received, then we terminate the process immediately; this is just in case the normal shutdown procedure failed or hung for some reason, the user is always able to stop the process with two control-C keystrokes. You better install signal handlers using installHandler. Best Regards, -- aycan From deniz.a.m.dogan at gmail.com Fri Jun 19 08:07:01 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Fri Jun 19 07:50:11 2009 Subject: [Haskell-cafe] Re: Running a "sub-process" which dies with the main program In-Reply-To: <1245412198.22228.49.camel@aycan> References: <7b501d5c0906181256k58c5702ap9e1f80f890e56e79@mail.gmail.com> <7b501d5c0906190258j2144940t28e503031b183600@mail.gmail.com> <1245407500.22228.27.camel@aycan> <7b501d5c0906190342l6c942883xb4acc2bbfeb9b67d@mail.gmail.com> <1245408920.22228.35.camel@aycan> <7b501d5c0906190409m84b21c2q19e9dd3a7b11db55@mail.gmail.com> <1245412198.22228.49.camel@aycan> Message-ID: <7b501d5c0906190507i260c849t5f1d4bd9ec7b91c6@mail.gmail.com> 2009/6/19 Aycan iRiCAN : > > Cum, 2009-06-19 tarihinde 13:09 +0200 saatinde, Deniz Dogan yazd?: >> 2009/6/19 Aycan iRiCAN : >> > >> > Cum, 2009-06-19 tarihinde 12:42 +0200 saatinde, Deniz Dogan yazd?: >> >> 2009/6/19 Aycan iRiCAN : >> >> > >> >> > Cum, 2009-06-19 tarihinde 11:58 +0200 saatinde, Deniz Dogan yazd?: >> >> >> 2009/6/18 Deniz Dogan : >> >> >> > Hi >> >> >> > >> >> >> > I couldn't come up with a better subject than this one, so anyways... >> >> >> > >> >> >> > I have a small program which spawns a subprocess. However, when I hit >> >> >> > C-c, the subprocess won't die, instead it will just keep running until >> >> >> > it's done or until I kill it. I've looked around in System.Process for >> >> >> > something suitable for my needs, but I can't seem to find it. Any >> >> >> > ideas? >> >> >> >> >> >> With a tip from a person outside of the mailing list I found >> >> >> System.Process.system, which essentially does exactly what I was >> >> >> asking for. >> >> > >> >> > Hey I'm already subscribed :) You can read from "sout" and "serr" with >> >> > below example. Hope that it helps. >> >> > >> >> > >> >> > module Main where >> >> > >> >> > import System.Process ?-- using process-1.0.1.1 >> >> > >> >> > main = do >> >> > ?(_, sout, serr, p) <- createProcess (proc "sleep" ["10"]) >> >> > ? ? ? ? ? ? ? ? ? ? ? ?{ std_out = CreatePipe >> >> > ? ? ? ? ? ? ? ? ? ? ? ?, std_err = CreatePipe } >> >> > ?r <- waitForProcess p >> >> > ?return () >> >> > >> >> >> >> Thanks! >> >> >> >> But this was the approach I used before I went to >> >> System.Process.system and it did not work on my Linux machine. >> > >> > Give it a try. Try to send CTRL-C and look if "sleep 10" (which is a >> > subprocess) process terminates. >> > >> > aycan@aycan:~/haskell$ time ./deniz2 && ps -ef | grep sleep >> > ^C >> > real ? ?0m0.707s >> > user ? ?0m0.001s >> > sys ? ? 0m0.004s >> > ? aycan 13098 ?4430 ? 0 13:50:23 pts/7 ? ? ? 0:00 grep sleep >> > >> > It terminates with ghc 6.10.3 on OpenSolaris. >> >> This is copied verbatim from my terminal. I used the exact some code >> that you gave me. >> >> % time ./test && ps -ef | grep sleep >> ^C >> real ?0m10.005s >> user ?0m0.003s >> sys ? 0m0.003s >> deniz ? ?14095 14047 ?0 13:05 pts/1 ? ?00:00:00 grep sleep >> >> What's strange though is that when I hit C-c *twice*, I get this behavior: > > Hmm, I think GHC RTS handles SIGINT. I recompiled with thread support and got the same behavour. > > See: http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Signals > > ? ? ? ?When the interrupt signal is received, the default behaviour of > ? ? ? ?the runtime is to attempt to shut down the Haskell program > ? ? ? ?gracefully. It does this by calling interruptStgRts() in > ? ? ? ?rts/Schedule.c (see Commentary/Rts/Scheduler#ShuttingDown). If a > ? ? ? ?second interrupt signal is received, then we terminate the > ? ? ? ?process immediately; this is just in case the normal shutdown > ? ? ? ?procedure failed or hung for some reason, the user is always > ? ? ? ?able to stop the process with two control-C keystrokes. > > You better install signal handlers using installHandler. > > Best Regards, But that's what syncProcess does when mingw32_HOST_OS is not defined. Also, compiling without -threaded doesn't help the problem on my machine, it still acts the same. -- Deniz Dogan From sjoerd at w3future.com Fri Jun 19 09:35:48 2009 From: sjoerd at w3future.com (Sjoerd Visscher) Date: Fri Jun 19 09:19:05 2009 Subject: [Haskell-cafe] ANNOUNCE fmlist In-Reply-To: References: <471C27BA-2DA7-4449-9AF8-4353AA9A4FED@w3future.com> Message-ID: <5F8F0F3E-9A09-4C6A-944D-1CDD21BD98DD@w3future.com> I'm glad you liked it! There's an interesting different way of doing the first half of your derivation, using a helper function: > transform t l = FM $ \f -> unFM l (t f) It transforms the map function passed to foldMap. The transform function has this property: > transform a . transform b = transform (b . a) flatten and fmap can both be written as transformers: > flatten = transform foldMap > fmap g = transform (. g) Now we can derive: (>>= g) = flatten . fmap g = transform foldMap . transform (. g) = transform ((. g) . foldMap) = transform (\f -> foldMap f . g) = FM $ \f -> unFM m (foldMap f . g) Other examples of transform are: filter p = transform (\f e -> if p e then f e else mempty) (<*> xs) = transform (\f g -> unFM xs (f . g)) Unfortunately I couldn't get this code to type-check, so the library doesn't use transform. Sjoerd On Jun 18, 2009, at 11:28 AM, Sebastian Fischer wrote: > On Jun 18, 2009, at 9:57 AM, Sjoerd Visscher wrote: > >> I am pleased to announce the first release of Data.FMList, lists >> represented by their foldMap function: [...] >> http://hackage.haskell.org/package/fmlist-0.1 > > cool! > > Just for fun: a derivation translating between different > formulations of monadic bind. > > m >>= g > = flatten (fmap g m) > = FM $ \f -> unFM (fmap g m) (foldMap f) > = FM $ \f -> unFM (FM $ \f' -> unFM m (f' . g)) (foldMap f) > = FM $ \f -> (\f' -> unFM m (f' . g)) (foldMap f) > = FM $ \f -> unFM m (folfMap f . g) -- your definition > = FM $ \f -> unFM m (flip unFM f . g) > = FM $ \f -> unFM m (\x -> flip unFM f (g x)) > = FM $ \f -> unFM m (\x -> unFM (g x) f) -- like > continuation monad > > Cheers, > Sebastian > > > -- > Underestimating the novelty of the future is a time-honored tradition. > (D.G.) > > > -- Sjoerd Visscher sjoerd@w3future.com From hjgtuyl at chello.nl Fri Jun 19 10:06:50 2009 From: hjgtuyl at chello.nl (Henk-Jan van Tuyl) Date: Fri Jun 19 09:49:43 2009 Subject: [Haskell-cafe] duplicate definition for symbol Message-ID: L.S., I am trying to run a program in GHCi, but I get a meesage that an object file is loaded twice; it appears that two different versions of package "process" are loaded, see the session text below. How can I solve this? GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> :load "Main.lhs" [1 of 1] Compiling Main ( Main.lhs, interpreted ) Ok, modules loaded: Main. *Main> :main Loading package syb ... linking ... done. Loading package base-3.0.3.0 ... linking ... done. Loading package array-0.2.0.0 ... linking ... done. Loading package containers-0.2.0.0 ... linking ... done. Loading package bytestring-0.9.1.4 ... linking ... done. Loading package old-locale-1.0.0.1 ... linking ... done. Loading package old-time-1.0.0.1 ... linking ... done. Loading package filepath-1.1.0.1 ... linking ... done. Loading package Win32-2.2.0.0 ... linking ... done. Loading package directory-1.0.0.2 ... linking ... done. Loading package random-1.0.0.1 ... linking ... done. Loading package time-1.1.2.2 ... linking ... done. Loading package stm-2.1.1.2 ... linking ... done. Loading package split-0.1.1 ... linking ... done. Loading package HUnit-1.2.0.3 ... linking ... done. Loading package QuickCheck-1.2.0.0 ... linking ... done. Loading package process-1.0.1.1 ... linking ... done. Loading package haskell98 ... linking ... done. Loading package mtl-1.1.0.2 ... linking ... done. Loading package parsec-2.1.0.1 ... linking ... done. Loading package network-2.2.0.1 ... linking ... done. Loading package hslogger-1.0.7 ... linking ... done. Loading package process-1.0.1.0 ... GHCi runtime linker: fatal error: I found a duplicate definition for symbol _runInteractiveProcess whilst processing object file C:\Programs\ghc\ghc-6.10.1\process-1.0.1.0\HSprocess-1.0.1.0.o This could be caused by: * Loading two different object files which export the same symbol * Specifying the same object file twice on the GHCi command line * An incorrect `package.conf' entry, causing some object to be loaded twice. GHCi cannot safely continue in this situation. Exiting now. Sorry. -- Met vriendelijke groet, Henk-Jan van Tuyl -- http://functor.bamikanarie.com http://Van.Tuyl.eu/ -- From daniel.is.fischer at web.de Fri Jun 19 10:32:21 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Fri Jun 19 10:16:21 2009 Subject: [Haskell-cafe] duplicate definition for symbol In-Reply-To: References: Message-ID: <200906191632.21404.daniel.is.fischer@web.de> Am Freitag 19 Juni 2009 16:06:50 schrieb Henk-Jan van Tuyl: > L.S., > > I am trying to run a program in GHCi, but I get a meesage that an object ? > file is loaded twice; it appears that two different versions of package ? > "process" are loaded, see the session text below. How can I solve this? http://www.haskell.org/cabal/FAQ.html#dependencies-conflict Wow, that one is really common. From sebf at informatik.uni-kiel.de Fri Jun 19 11:06:20 2009 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Fri Jun 19 10:49:33 2009 Subject: [Haskell-cafe] ANNOUNCE fmlist In-Reply-To: <471C27BA-2DA7-4449-9AF8-4353AA9A4FED@w3future.com> References: <471C27BA-2DA7-4449-9AF8-4353AA9A4FED@w3future.com> Message-ID: <6216D812-85C1-46F7-AEE9-D66562A7186F@informatik.uni-kiel.de> On Jun 18, 2009, at 9:57 AM, Sjoerd Visscher wrote: > This is my first package on Hackage, so any comments are welcome! It is not only pleasingly elegant but also quite useful: Your Monad and MonadPlus instances lead me to an interesting observation. Various strategies for non-deterministic search can be implemented using FMList by expressing failure and choice via a Monoid instance. I have just finished a revision of a paper that explains how to factor two-continuation based backtracking (and other strategies) into a continuation monad transformer and a type class for non-deterministic computations (I'd be glad to receive comments!). http://www-ps.informatik.uni-kiel.de/~sebf/pub/atps09.html Now I recognise that one can also use FMList as the part that provides return and >>= and any Monoid for failure and choice. Especially, one can implement breadth-first search (bfs) using a monoid that collects levels of a search tree and iterative deepening depth-first search (idfs) using a monoid that represents depth-bounded computations. I have updated my package level-monad to use your library and monoids: http://hackage.haskell.org/package/level-monad The employed Monoid instances do not satisfy any monoid law. However, these are the simplest implementations of bfs and idfs that I am aware of, so I don't care very much ;) Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From sjoerd at w3future.com Fri Jun 19 11:41:39 2009 From: sjoerd at w3future.com (Sjoerd Visscher) Date: Fri Jun 19 11:24:55 2009 Subject: [Haskell-cafe] ANNOUNCE fmlist In-Reply-To: <5F8F0F3E-9A09-4C6A-944D-1CDD21BD98DD@w3future.com> References: <471C27BA-2DA7-4449-9AF8-4353AA9A4FED@w3future.com> <5F8F0F3E-9A09-4C6A-944D-1CDD21BD98DD@w3future.com> Message-ID: On Jun 19, 2009, at 3:35 PM, Sjoerd Visscher wrote: > > transform t l = FM $ \f -> unFM l (t f) > > Unfortunately I couldn't get this code to type-check, so the library > doesn't use transform. With some help from Martijn van Steenbergen the type turned out to be: transform :: (forall b. Monoid b => (a -> b) -> (c -> b)) -> FMList c - > FMList a I've updated the library to use the transform function. -- Sjoerd Visscher sjoerd@w3future.com From dons at galois.com Fri Jun 19 11:54:41 2009 From: dons at galois.com (Don Stewart) Date: Fri Jun 19 11:39:40 2009 Subject: [Haskell-cafe] packages on Hackage? In-Reply-To: <5ae4f2ba0906182126w6a094213o4594f7f3b16c505e@mail.gmail.com> References: <5ae4f2ba0906182126w6a094213o4594f7f3b16c505e@mail.gmail.com> Message-ID: <20090619155441.GA24758@whirlpool.galois.com> vigalchin: > Hello, > > Haskell packages on Hackage can be hosted anywhere, yes? > > If a Haskell package is hosted on Hackage, how often is it backed up? Nightly. From dons at galois.com Fri Jun 19 12:00:06 2009 From: dons at galois.com (Don Stewart) Date: Fri Jun 19 11:45:17 2009 Subject: [Haskell-cafe] IORef memory leak In-Reply-To: <4A3AFBF9.5050907@cs.pdx.edu> References: <4A3AFBF9.5050907@cs.pdx.edu> Message-ID: <20090619160006.GC24758@whirlpool.galois.com> jsnow: > > I'm having some trouble with excessive memory use in a program that uses > a lot of IORefs. I was able to write a much simpler program which > exhibits the same sort of behavior. It appears that "modifyIORef" and > "writeIORef" leak memory; perhaps they keep a reference to the old > value. I tried both ghc-6.8.3 and ghc-6.10.1. > > Is this a known limitation, or is this a ghc bug, or am I using IORefs > in the wrong way? > > -jim > > > module Main where > > import Data.IORef > import Control.Monad > > -- Leaks memory > leakcheck1 ior = > do go 1000000000 > where > go 0 = return () > go n = do modifyIORef ior (+1) > go (n-1) It is not possible to write a modifyIORef that *doesn't* leak memory! -- Don From dvde at gmx.net Fri Jun 19 12:07:57 2009 From: dvde at gmx.net (Daniel van den Eijkel) Date: Fri Jun 19 11:51:08 2009 Subject: [Haskell-cafe] IORef memory leak In-Reply-To: <20090619160006.GC24758@whirlpool.galois.com> References: <4A3AFBF9.5050907@cs.pdx.edu> <20090619160006.GC24758@whirlpool.galois.com> Message-ID: <4A3BB7DD.4040705@gmx.net> Don Stewart schrieb: > It is not possible to write a modifyIORef that *doesn't* leak memory! > Why? Or can one read about it somewhere? Best regards, Daniel From dons at galois.com Fri Jun 19 12:09:12 2009 From: dons at galois.com (Don Stewart) Date: Fri Jun 19 11:54:12 2009 Subject: [Haskell-cafe] IORef memory leak In-Reply-To: <4A3BB7DD.4040705@gmx.net> References: <4A3AFBF9.5050907@cs.pdx.edu> <20090619160006.GC24758@whirlpool.galois.com> <4A3BB7DD.4040705@gmx.net> Message-ID: <20090619160912.GD24758@whirlpool.galois.com> dvde: > > Don Stewart schrieb: >> It is not possible to write a modifyIORef that *doesn't* leak memory! >> > Why? Or can one read about it somewhere? Try writing a version of this program, using modifyIORef only, such that it doesn't exhaust the heap: import Data.IORef import Control.Monad import System.IO.Unsafe ref :: IORef Int ref = unsafePerformIO $ newIORef 0 {-# NOINLINE ref #-} main = do modifyIORef ref (\a -> a + 1) main Run it in a constrained environment, so you don't thrash: $ ./A +RTS -M100M Heap exhausted; Current maximum heap size is 99999744 bytes (95 MB); use `+RTS -M' to increase it. The goal is to run in constant space. -- Don From claus.reinke at talk21.com Fri Jun 19 12:29:42 2009 From: claus.reinke at talk21.com (Claus Reinke) Date: Fri Jun 19 12:12:59 2009 Subject: [Haskell-cafe] IORef memory leak References: <4A3AFBF9.5050907@cs.pdx.edu><20090619160006.GC24758@whirlpool.galois.com> <4A3BB7DD.4040705@gmx.net> Message-ID: >> It is not possible to write a modifyIORef that *doesn't* leak memory! >> > Why? Or can one read about it somewhere? Possibly, Don meant that 'modifyIORef' is defined in a way that does not allow to enforce evaluation of the result of the modification function (a typical problem with fmap-style library functions): modifyIORef ref f = readIORef ref >>= writeIORef ref . f No matter whether 'f' is strict or not, the 'writeIORef r' doesn't evaluate its result, just stores the unevaluated application: > r<-newIORef 0 > modifyIORef r (\x->trace "done" $ x+1) > modifyIORef r (\x->trace "done" $ x+1) > readIORef r done done 2 If it had been defined like this instead mRef r ($) f = readIORef r >>= (writeIORef r $) . f it would be possible to transform the strictness of 'writeIORef r' to match that of 'f': > r<-newIORef 0 > mRef r ($) (\x->trace "done" $ x+1) > mRef r ($) (\x->trace "done" $ x+1) > readIORef r done done 2 > r<-newIORef 0 > mRef r ($!) (\x->trace "done" $ x+1) done > mRef r ($!) (\x->trace "done" $ x+1) done > readIORef r 2 Claus From chaddai.fouche at gmail.com Fri Jun 19 12:44:57 2009 From: chaddai.fouche at gmail.com (=?UTF-8?B?Q2hhZGRhw68gRm91Y2jDqQ==?=) Date: Fri Jun 19 12:28:06 2009 Subject: [Haskell-cafe] Using Parsec with ByteString ? In-Reply-To: <4A3B7BB9.4040500@yahoo.fr> References: <4A3B7BB9.4040500@yahoo.fr> Message-ID: On Fri, Jun 19, 2009 at 1:51 PM, Fernand wrote: > but the parser one needs to write must parse ByteStrings instead of Strings > (that is, something like having a "Parsec Bytestring ()" type, unless I'm > completely misunderstanding the situation). My problem is that I do not > manage > to write primitive parsing combinators (like string, satisfy, letter, etc.) > to > define my language's tokens. Why would you want to do that ? After all, those combinators are already available in Text.Parsec.Char : they work on any Stream instance whose token type is Char, which happens to be the case for ByteString. -- Jeda? From dvde at gmx.net Fri Jun 19 12:47:47 2009 From: dvde at gmx.net (Daniel van den Eijkel) Date: Fri Jun 19 12:30:58 2009 Subject: [Haskell-cafe] IORef memory leak In-Reply-To: <20090619160912.GD24758@whirlpool.galois.com> References: <4A3AFBF9.5050907@cs.pdx.edu> <20090619160006.GC24758@whirlpool.galois.com> <4A3BB7DD.4040705@gmx.net> <20090619160912.GD24758@whirlpool.galois.com> Message-ID: <4A3BC133.5010808@gmx.net> Don Stewart schrieb: > dvde: > >> Don Stewart schrieb: >> >>> It is not possible to write a modifyIORef that *doesn't* leak memory! >>> >>> >> Why? Or can one read about it somewhere? >> > > > Try writing a version of this program, using modifyIORef only, > such that it doesn't exhaust the heap: > > import Data.IORef > import Control.Monad > import System.IO.Unsafe > > ref :: IORef Int > ref = unsafePerformIO $ newIORef 0 > {-# NOINLINE ref #-} > > main = do > modifyIORef ref (\a -> a + 1) > main > > Run it in a constrained environment, so you don't thrash: > > $ ./A +RTS -M100M > Heap exhausted; > Current maximum heap size is 99999744 bytes (95 MB); > use `+RTS -M' to increase it. > > The goal is to run in constant space. > > -- Don > > Hm, do you say it is not possible to write a modifyIORef function that does not leak memory, or do you say it is not possible to use the (existing) modifyIORef without having memory leaks? I wrote the following which runs in constant space, but it introduces strictness, which is not always desirable. And yes, using only modifyIORef this could not be done this way, because the strict evaluation happens on the IO-Monad-level. But such examples occured already in this thread. import Data.IORef import Control.Monad import System.IO.Unsafe ref :: IORef Int ref = unsafePerformIO $ newIORef 0 {-# NOINLINE ref #-} main = do myModifyIORef ref (\a -> a + 1) main myModifyIORef :: IORef a -> (a->a) -> IO () myModifyIORef ref f = do a <- readIORef ref let a' = f a seq a' $ writeIORef ref a' So would it make sense to create a strict modifyIORef' function? best regards, daniel From dons at galois.com Fri Jun 19 12:47:24 2009 From: dons at galois.com (Don Stewart) Date: Fri Jun 19 12:32:27 2009 Subject: [Haskell-cafe] IORef memory leak In-Reply-To: <4A3BC133.5010808@gmx.net> References: <4A3AFBF9.5050907@cs.pdx.edu> <20090619160006.GC24758@whirlpool.galois.com> <4A3BB7DD.4040705@gmx.net> <20090619160912.GD24758@whirlpool.galois.com> <4A3BC133.5010808@gmx.net> Message-ID: <20090619164724.GA25233@whirlpool.galois.com> dvde: > Don Stewart schrieb: >> dvde: >> >>> Don Stewart schrieb: >>> >>>> It is not possible to write a modifyIORef that *doesn't* leak memory! >>>> >>> Why? Or can one read about it somewhere? >>> >> >> >> Try writing a version of this program, using modifyIORef only, such >> that it doesn't exhaust the heap: >> >> import Data.IORef >> import Control.Monad >> import System.IO.Unsafe >> >> ref :: IORef Int >> ref = unsafePerformIO $ newIORef 0 >> {-# NOINLINE ref #-} >> >> main = do >> modifyIORef ref (\a -> a + 1) >> main >> >> Run it in a constrained environment, so you don't thrash: >> >> $ ./A +RTS -M100M >> Heap exhausted; >> Current maximum heap size is 99999744 bytes (95 MB); >> use `+RTS -M' to increase it. >> >> The goal is to run in constant space. >> >> -- Don >> >> > Hm, do you say it is not possible to write a modifyIORef function that > does not leak memory, or do you say it is not possible to use the > (existing) modifyIORef without having memory leaks? The latter. atomicModifyIORef is harder though still, since it is a primop with the same properties as modifyIORef :/ > So would it make sense to create a strict modifyIORef' function? Very much so. In fact, I'd argue the vast majority of uses are for the WHNF-strict version. -- Don From dvde at gmx.net Fri Jun 19 12:51:39 2009 From: dvde at gmx.net (Daniel van den Eijkel) Date: Fri Jun 19 12:34:51 2009 Subject: [Haskell-cafe] IORef memory leak In-Reply-To: References: <4A3AFBF9.5050907@cs.pdx.edu><20090619160006.GC24758@whirlpool.galois.com> <4A3BB7DD.4040705@gmx.net> Message-ID: <4A3BC21B.1020603@gmx.net> Yes I guessed that. Thanks, Daniel Claus Reinke schrieb: >>> It is not possible to write a modifyIORef that *doesn't* leak memory! >>> >> Why? Or can one read about it somewhere? > > Possibly, Don meant that 'modifyIORef' is defined in a way that does > not allow to enforce evaluation of the result of the modification > function (a typical problem with fmap-style library functions): > > modifyIORef ref f = readIORef ref >>= writeIORef ref . f > > No matter whether 'f' is strict or not, the 'writeIORef r' doesn't > evaluate its result, just stores the unevaluated application: > > > r<-newIORef 0 > > modifyIORef r (\x->trace "done" $ x+1) > > modifyIORef r (\x->trace "done" $ x+1) > > readIORef r > done > done > 2 > > If it had been defined like this instead > > mRef r ($) f = readIORef r >>= (writeIORef r $) . f > > it would be possible to transform the strictness of 'writeIORef r' > to match that of 'f': > > > r<-newIORef 0 > > mRef r ($) (\x->trace "done" $ x+1) > > mRef r ($) (\x->trace "done" $ x+1) > > readIORef r > done > done > 2 > > r<-newIORef 0 > > mRef r ($!) (\x->trace "done" $ x+1) > done > > mRef r ($!) (\x->trace "done" $ x+1) > done > > readIORef r > 2 > > Claus > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From jgoerzen at complete.org Fri Jun 19 13:02:47 2009 From: jgoerzen at complete.org (John Goerzen) Date: Fri Jun 19 12:45:57 2009 Subject: [Haskell-cafe] Use MySQL from Haskell In-Reply-To: <4A3AB0EA.4090304@googlemail.com> References: <4A3AB0EA.4090304@googlemail.com> Message-ID: <4A3BC4B7.8000508@complete.org> Maciej Podgurski wrote: > Building convertible-1.0.5... There was unfortunately an API change in GHC 6.10.3 that could not be worked around. Either upgrade to 6.10.3 or use an older version of convertible. -- John From sjoerd at w3future.com Fri Jun 19 13:12:24 2009 From: sjoerd at w3future.com (Sjoerd Visscher) Date: Fri Jun 19 12:55:37 2009 Subject: [Haskell-cafe] ANNOUNCE fmlist In-Reply-To: <6216D812-85C1-46F7-AEE9-D66562A7186F@informatik.uni-kiel.de> References: <471C27BA-2DA7-4449-9AF8-4353AA9A4FED@w3future.com> <6216D812-85C1-46F7-AEE9-D66562A7186F@informatik.uni-kiel.de> Message-ID: <8E22DA38-D732-4F9D-99F8-7579DDADAC4C@w3future.com> On Jun 19, 2009, at 5:06 PM, Sebastian Fischer wrote: > Your Monad and MonadPlus instances lead me to an interesting > observation. Various strategies for non-deterministic search can be > implemented using FMList by expressing failure and choice via a > Monoid instance. > > I have just finished a revision of a paper that explains how to > factor two-continuation based backtracking (and other strategies) > into a continuation monad transformer and a type class for non- > deterministic computations (I'd be glad to receive comments!). > > http://www-ps.informatik.uni-kiel.de/~sebf/pub/atps09.html > > Now I recognise that one can also use FMList as the part that > provides return and >>= and any Monoid for failure and choice. > > Especially, one can implement breadth-first search (bfs) using a > monoid that collects levels of a search tree and iterative deepening > depth-first search (idfs) using a monoid that represents depth- > bounded computations. > > I have updated my package level-monad to use your library and monoids: > > http://hackage.haskell.org/package/level-monad > > The employed Monoid instances do not satisfy any monoid law. > However, these are the simplest implementations of bfs and idfs that > I am aware of, so I don't care very much ;) Very nice. It is cool to see someone using this already! I see you did performance tests. How does your current version compare to f.e. one based on DiffLists? I wonder though, aren't you worried that updated versions of FMList might use the monoid laws to rewrite certains bits, and your code would break? Essentially you are using FMLists as a tree structure, which isn't possible when you abide by the monoid laws. I think you should be able to do the same thing in as many lines, using f.e. the ChoiceT type from MonadLib, where bfs and idfsBy are variations on runChoiceT. The ChoiceEff part might complicate things a bit though. But I might be missing some essential detail. greetings, -- Sjoerd Visscher sjoerd@w3future.com From as at nijoruj.org Fri Jun 19 13:20:19 2009 From: as at nijoruj.org (austin s) Date: Fri Jun 19 13:03:31 2009 Subject: [Haskell-cafe] duplicate definition for symbol In-Reply-To: References: Message-ID: <1245431903-sup-525@existential.local> Excerpts from Henk-Jan van Tuyl's message of Fri Jun 19 09:06:50 -0500 2009: > > L.S., > > I am trying to run a program in GHCi, but I get a meesage that an object > file is loaded twice; it appears that two different versions of package > "process" are loaded, see the session text below. How can I solve this? > > > GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help > Loading package ghc-prim ... linking ... done. > Loading package integer ... linking ... done. > Loading package base ... linking ... done. > Prelude> :load "Main.lhs" > [1 of 1] Compiling Main ( Main.lhs, interpreted ) > Ok, modules loaded: Main. > *Main> :main > Loading package syb ... linking ... done. > Loading package base-3.0.3.0 ... linking ... done. > Loading package array-0.2.0.0 ... linking ... done. > Loading package containers-0.2.0.0 ... linking ... done. > Loading package bytestring-0.9.1.4 ... linking ... done. > Loading package old-locale-1.0.0.1 ... linking ... done. > Loading package old-time-1.0.0.1 ... linking ... done. > Loading package filepath-1.1.0.1 ... linking ... done. > Loading package Win32-2.2.0.0 ... linking ... done. > Loading package directory-1.0.0.2 ... linking ... done. > Loading package random-1.0.0.1 ... linking ... done. > Loading package time-1.1.2.2 ... linking ... done. > Loading package stm-2.1.1.2 ... linking ... done. > Loading package split-0.1.1 ... linking ... done. > Loading package HUnit-1.2.0.3 ... linking ... done. > Loading package QuickCheck-1.2.0.0 ... linking ... done. > Loading package process-1.0.1.1 ... linking ... done. > Loading package haskell98 ... linking ... done. > Loading package mtl-1.1.0.2 ... linking ... done. > Loading package parsec-2.1.0.1 ... linking ... done. > Loading package network-2.2.0.1 ... linking ... done. > Loading package hslogger-1.0.7 ... linking ... done. > Loading package process-1.0.1.0 ... > > GHCi runtime linker: fatal error: I found a duplicate definition for symbol > _runInteractiveProcess > whilst processing object file > C:\Programs\ghc\ghc-6.10.1\process-1.0.1.0\HSprocess-1.0.1.0.o > This could be caused by: > * Loading two different object files which export the same symbol > * Specifying the same object file twice on the GHCi command line > * An incorrect `package.conf' entry, causing some object to be > loaded twice. > GHCi cannot safely continue in this situation. Exiting now. Sorry. > > The easiest solution would simply be to 'ghc-pkg unregister process-1.0.1.1', and then rebuild all the packages that depend on it against process-1.0.1.0. The reason this is happening is simply because you have two libraries you depend on, each of which depends on a different version of process. It's a fairly annoying error, that is prone to happen when you have upgraded versions of GHC's bootlibs (i.e. necessary libraries for GHC installation.) Austin From maciej.podgurski at googlemail.com Fri Jun 19 14:11:41 2009 From: maciej.podgurski at googlemail.com (Maciej Podgurski) Date: Fri Jun 19 13:56:28 2009 Subject: [Haskell-cafe] Use MySQL from Haskell In-Reply-To: <4A3B7B78.5040207@gmx.net> References: <4A3AB0EA.4090304@googlemail.com> <29bf512f0906181512i50dec0d9ge04be77ab4e3f668@mail.gmail.com> <4A3B7B78.5040207@gmx.net> Message-ID: <4A3BD4DD.1040901@googlemail.com> Does Database.HDBC.getTables work for you? I successfully created a new table and selected data from a database but getTables always returns an empty list (what is not a big problem since a query "show tables" works fine). Besh wishes, Maciej W dniu 19.06.2009 13:50 Daniel van den Eijkel pisze: > The same with me - I'm on XP, and HDBC-odbc is the library I got > running to access the MySQL database. > Regards, > Daniel > > > Michael Snoyman schrieb: >> Marciej, >> >> I went the HDBC route and got the same problem. Although it does not >> seem to be officially blessed, try installing the time-1.1.3 package. >> It's working for me at least, which I know is a dubious recommendation. >> >> Also, I am currently using the hdbc-odbc package for accessing MySQL. >> I couldn't get hdbc-mysql to work properly. I hope that once I get >> this project working right, I'll have a chance to dig into the >> hdbc-mysql issue itself. >> >> Good luck! >> >> Michael From jsnow at cs.pdx.edu Fri Jun 19 14:13:59 2009 From: jsnow at cs.pdx.edu (Jim Snow) Date: Fri Jun 19 14:50:58 2009 Subject: [Haskell-cafe] IORef memory leak In-Reply-To: <20090619160912.GD24758@whirlpool.galois.com> References: <4A3AFBF9.5050907@cs.pdx.edu> <20090619160006.GC24758@whirlpool.galois.com> <4A3BB7DD.4040705@gmx.net> <20090619160912.GD24758@whirlpool.galois.com> Message-ID: <4A3BD567.6090509@cs.pdx.edu> Don Stewart wrote: > dvde: > >> Don Stewart schrieb: >> >>> It is not possible to write a modifyIORef that *doesn't* leak memory! >>> >>> >> Why? Or can one read about it somewhere? >> > > > Try writing a version of this program, using modifyIORef only, > such that it doesn't exhaust the heap: > > import Data.IORef > import Control.Monad > import System.IO.Unsafe > > ref :: IORef Int > ref = unsafePerformIO $ newIORef 0 > {-# NOINLINE ref #-} > > main = do > modifyIORef ref (\a -> a + 1) > main > > Run it in a constrained environment, so you don't thrash: > > $ ./A +RTS -M100M > Heap exhausted; > Current maximum heap size is 99999744 bytes (95 MB); > use `+RTS -M' to increase it. > > The goal is to run in constant space. > > -- Don > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > Thanks, that's good to know. do x <- readIORef ior writeIORef ior $! (x+1) Works for me. The laziness of modifyIORef and workarounds would be a good thing to have documented in the modifyIORef docs [1], since it's probably a common source of memory leaks. I'd also be in favor of a strict version of modifyIORef. [1] http://www.haskell.org/ghc/dist/current/docs/libraries/base/Data-IORef.html#v%3AmodifyIORef -jim From maciej.podgurski at googlemail.com Fri Jun 19 15:21:25 2009 From: maciej.podgurski at googlemail.com (Maciej Podgurski) Date: Fri Jun 19 15:04:37 2009 Subject: [Haskell-cafe] Use MySQL from Haskell In-Reply-To: <4A3B3ECA.2010607@gmx.de> References: <4A3AB0EA.4090304@googlemail.com> <4A3B3ECA.2010607@gmx.de> Message-ID: <4A3BE535.20302@googlemail.com> Hi Bj?rn, thanks for your hint, I finally made HDBC-odbc and even hsql-mysql run. Below is a step-by-step manual how to install both packages on windows for people having the same troubles I had. I used GHC 6.8.3. MySQL from HDBC-odbc ******************** 1.) Install package time-1.1.2.4. 2.) Download package convertible-1.0.5. In convertible.cabal find the line Build-Depends: ..., time>=1.1.2.4, ... and replace it by Build-Depends: ..., time>=1.1.2.4 && <1.1.3, ... Now the installation shouldn't fail with a compilation error. 3.) Download package HDBC-2.1.1, modfiy HDBC.cabal in the same way as in 2.) and install the package. 4.) Install package HDBC-odbc-2.1.0.0. 5.) There still was one thing I didn't know that made my example fail with an exception. You need to install a MySQL ODBC connector for Windows (available from dev.mysql.com). 6) Now the following example should return a list of all table names in the database: import Database.HDBC import Database.HDBC.ODBC main :: IO () main = do conn <- connectODBC "DRIVER={MySQL ODBC 5.1 Driver}; SERVER=my_server; DATABASE=my_database; UID=my_username; PASSWORD=my_password" qs <- quickQuery' conn "show tables" [] mapM_ (\[SqlByteString table] -> print table) qs disconnect conn (There's also a getTables function but it always returns an empty list on my system, I don't know why). MySQL from hsql-mysql ********************* 1.) Install package hsql-1.7.1. 2.) Download package hsql-mysql-1.7.1. In hsql-mysql.cabal find the line include-dirs: Database/HSQL, /usr/include/mysql and replace it by include-dirs: Database/HSQL Also find the line extra-lib-dirs: /usr/lib/mysql and remove it. 3.) Do a runghc Setup configure --extra-include-dirs=/include/ --extra-lib-dirs=/lib/opt/ runghc Setup build runghc Setup install where is the path to your MySQL server installation. I'm using MySQL Server 5.1, so maybe you have to adjust the include or lib path. 4.) Now you should be able to compile: import Database.HSQL import Database.HSQL.MySQL main :: IO () main = do conn <- connect "my_server" "my_database" "my_username" "my_password" ts <- tables conn mapM_ print ts disconnect conn 5.) Execute the main function. If you get an error like Loading package hsql-mysql-1.7.1 ... can't load .so/.DLL for: mysqlclient (addDLL: unknown error) go to /bin where a file "libmySQL.dll" should reside. Copy this file to "mysqlclient.dll" and try executing the main function again. Now you should get a list of all tables in the database. Installing HDBC-mysql still failed due to a missing file "mysql_config" which seems to be available only for linux systems. Best wishes, Maciej W dniu 19.06.2009 09:31 Bj?rn Peem?ller pisze: > Maciej Podgurski schrieb: >> So I switched to HDBC-2.1.1 and got the next compile error: >> >> Building convertible-1.0.5... >> >> Data/Convertible/Instances/Num.hs:671:0: >> warning: no newline at end of file >> [...] >> [5 of 8] Compiling Data.Convertible.Instances.C ( >> Data/Convertible/Instances/C.hs, dist\build/Data/C >> onvertible/Instances/C.o ) >> [6 of 8] Compiling Data.Convertible.Instances.Time ( >> Data/Convertible/Instances/Time.hs, dist\build/ >> Data/Convertible/Instances/Time.o ) >> >> Data/Convertible/Instances/Time.hs:64:0: >> Duplicate instance declarations: >> instance Typeable NominalDiffTime >> -- Defined at Data/Convertible/Instances/Time.hs:(64,0)-(65,42) >> instance Typeable NominalDiffTime >> -- Defined in time-1.1.3:Data.Time.Clock.UTC >> >> Data/Convertible/Instances/Time.hs:67:0: >> Duplicate instance declarations: >> instance Typeable UTCTime >> -- Defined at Data/Convertible/Instances/Time.hs:(67,0)-(68,34) >> instance Typeable UTCTime >> -- Defined in time-1.1.3:Data.Time.Clock.UTC > > Hi Maciej, > > this is quite easy to fix (although a little bit dirty). The problem is > that time-1.1.3 now defines some Typeable instances which time-1.1.2.4 > did not and which are therefore defined in convertible, too. I don't > know a general fix to the problem, but you can either > > - download the convertible package and comment out the two instance > declarations as shown in the error message and then cabal install it > - install from Hackage with additional constraint: cabal install > convertible --constraint=time<1.1.3 > > I hope this will help you get HDBC running. > > Cheers, > Bj?rn > > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From greg at gregorycollins.net Fri Jun 19 16:04:46 2009 From: greg at gregorycollins.net (Gregory Collins) Date: Fri Jun 19 15:47:55 2009 Subject: [Haskell-cafe] IORef memory leak In-Reply-To: <4A3BD567.6090509@cs.pdx.edu> (Jim Snow's message of "Fri, 19 Jun 2009 11:13:59 -0700") References: <4A3AFBF9.5050907@cs.pdx.edu> <20090619160006.GC24758@whirlpool.galois.com> <4A3BB7DD.4040705@gmx.net> <20090619160912.GD24758@whirlpool.galois.com> <4A3BD567.6090509@cs.pdx.edu> Message-ID: <87ab44rnvl.fsf@gregorycollins.net> Jim Snow writes: > Works for me. The laziness of modifyIORef and workarounds would be a > good thing to have documented in the modifyIORef docs, since it's > probably a common source of memory leaks. I'd also be in favor of a > strict version of modifyIORef. http://hackage.haskell.org/packages/archive/strict-io/0.1/doc/html/Data-IORef-Strict.html ? G. -- Gregory Collins From pocmatos at gmail.com Fri Jun 19 16:23:22 2009 From: pocmatos at gmail.com (Paulo J. Matos) Date: Fri Jun 19 16:06:38 2009 Subject: [Haskell-cafe] Installing agda through cabal Message-ID: <1245443002.15603.1.camel@drserver> Hi all, I am trying to install agda through cabal but I get this: $ cabal install alex Resolving dependencies... [1 of 1] Compiling Main ( /tmp/alex-2.3.116333/alex-2.3.1/Setup.lhs, /tmp/alex-2.3.116333/alex-2.3.1/dist/setup/Main.o ) /tmp/alex-2.3.116333/alex-2.3.1/Setup.lhs:6:51: Warning: In the use of `buildVerbose' (imported from Distribution.Simple.Setup): Deprecated: "Use buildVerbosity instead" /tmp/alex-2.3.116333/alex-2.3.1/Setup.lhs:7:51: Warning: In the use of `defaultUserHooks' (imported from Distribution.Simple): Deprecated: "Use simpleUserHooks or autoconfUserHooks, unless you need Cabal-1.2 compatibility in which case you must stick with defaultUserHooks" Linking /tmp/alex-2.3.116333/alex-2.3.1/dist/setup/setup ... Warning: defaultUserHooks in Setup script is deprecated. Configuring alex-2.3.1... Preprocessing executables for alex-2.3.1... Building alex-2.3.1... [ 1 of 16] Compiling Set ( src/Set.hs, dist/build/alex/alex-tmp/Set.o ) [ 2 of 16] Compiling DFS ( src/DFS.hs, dist/build/alex/alex-tmp/DFS.o ) [ 3 of 16] Compiling Sort ( src/Sort.hs, dist/build/alex/alex-tmp/Sort.o ) [ 4 of 16] Compiling CharSet ( src/CharSet.hs, dist/build/alex/alex-tmp/CharSet.o ) [ 5 of 16] Compiling Map ( src/Map.hs, dist/build/alex/alex-tmp/Map.o ) [ 6 of 16] Compiling Paths_alex ( dist/build/autogen/Paths_alex.hs, dist/build/alex/alex-tmp/Paths_alex.o ) [ 7 of 16] Compiling Util ( src/Util.hs, dist/build/alex/alex-tmp/Util.o ) [ 8 of 16] Compiling AbsSyn ( src/AbsSyn.hs, dist/build/alex/alex-tmp/AbsSyn.o ) [ 9 of 16] Compiling ParseMonad ( src/ParseMonad.hs, dist/build/alex/alex-tmp/ParseMonad.o ) [10 of 16] Compiling Scan ( dist/build/alex/alex-tmp/Scan.hs, dist/build/alex/alex-tmp/Scan.o ) [11 of 16] Compiling Output ( src/Output.hs, dist/build/alex/alex-tmp/Output.o ) [12 of 16] Compiling Info ( src/Info.hs, dist/build/alex/alex-tmp/Info.o ) [13 of 16] Compiling NFA ( src/NFA.hs, dist/build/alex/alex-tmp/NFA.o ) [14 of 16] Compiling DFA ( src/DFA.hs, dist/build/alex/alex-tmp/DFA.o ) [15 of 16] Compiling Parser ( dist/build/alex/alex-tmp/Parser.hs, dist/build/alex/alex-tmp/Parser.o ) [16 of 16] Compiling Main ( src/Main.hs, dist/build/alex/alex-tmp/Main.o ) Linking dist/build/alex/alex ... Installing executable(s) in /home/pmatos/.cabal/bin pmatos@drserver ~ $ cabal install agda Resolving dependencies... Configuring Agda-2.2.2... cabal: alex version >=2.0.1 && <3 is required but it could not be found. cabal: Error: some packages failed to install: Agda-2.2.2 failed during the configure step. The exception was: exit: ExitFailure 1 As you can see, I had just finished installing alex 2.3.1, so why does cabal still request alex >=2.0.1 && <3? Cheers, Paulo Matos From jake.mcarthur at gmail.com Fri Jun 19 16:35:12 2009 From: jake.mcarthur at gmail.com (Jake McArthur) Date: Fri Jun 19 16:19:26 2009 Subject: [Haskell-cafe] Installing agda through cabal In-Reply-To: <1245443002.15603.1.camel@drserver> References: <1245443002.15603.1.camel@drserver> Message-ID: <4A3BF680.4000100@gmail.com> Paulo J. Matos wrote: > As you can see, I had just finished installing alex 2.3.1, so why does > cabal still request alex >=2.0.1 && <3? Probably you don't have alex in your PATH. - Jake From pocmatos at gmail.com Fri Jun 19 17:20:39 2009 From: pocmatos at gmail.com (Paulo J. Matos) Date: Fri Jun 19 17:03:49 2009 Subject: [Haskell-cafe] Installing agda through cabal In-Reply-To: <4A3BF680.4000100@gmail.com> References: <1245443002.15603.1.camel@drserver> <4A3BF680.4000100@gmail.com> Message-ID: <1245446439.15603.2.camel@drserver> On Fri, 2009-06-19 at 15:35 -0500, Jake McArthur wrote: > Paulo J. Matos wrote: > > As you can see, I had just finished installing alex 2.3.1, so why does > > cabal still request alex >=2.0.1 && <3? > > Probably you don't have alex in your PATH. > > - Jake Shouldn't cabal make sure the library it installs are in PATH? or at least, they are in the PATH of the apps built by cabal itself? Cheers, Paulo Matos From max.rabkin at gmail.com Fri Jun 19 17:35:39 2009 From: max.rabkin at gmail.com (Max Rabkin) Date: Fri Jun 19 17:19:07 2009 Subject: [Haskell-cafe] Installing agda through cabal In-Reply-To: <1245446439.15603.2.camel@drserver> References: <1245443002.15603.1.camel@drserver> <4A3BF680.4000100@gmail.com> <1245446439.15603.2.camel@drserver> Message-ID: On Fri, Jun 19, 2009 at 11:20 PM, Paulo J. Matos wrote: > Shouldn't cabal make sure the library it installs are in PATH? This would require modifying the path (since there may be no writable location on the existing path). But the PATH is set by a combination of several programs written in Turing-complete languages (shell script), and those programs themselves are in unknown locations (depending on the shell in use). > or at > least, they are in the PATH of the apps built by cabal itself? This is a possibility. But surely you're one day going to want to run your cabal-installed programs yourself (there are some pretty handy ones), so the easiest thing is to extend your path. It might be a good idea for cabal-install to warn that its bin directory is not in your path when you install an executable. --Max From pocmatos at gmail.com Fri Jun 19 17:41:05 2009 From: pocmatos at gmail.com (Paulo J. Matos) Date: Fri Jun 19 17:24:16 2009 Subject: [Haskell-cafe] Installing agda through cabal In-Reply-To: References: <1245443002.15603.1.camel@drserver> <4A3BF680.4000100@gmail.com> <1245446439.15603.2.camel@drserver> Message-ID: <1245447665.15603.3.camel@drserver> On Fri, 2009-06-19 at 23:35 +0200, Max Rabkin wrote: > On Fri, Jun 19, 2009 at 11:20 PM, Paulo J. Matos wrote: > > Shouldn't cabal make sure the library it installs are in PATH? > > This would require modifying the path (since there may be no writable > location on the existing path). But the PATH is set by a combination > of several programs written in Turing-complete languages (shell > script), and those programs themselves are in unknown locations > (depending on the shell in use). > > > or at > > least, they are in the PATH of the apps built by cabal itself? > > This is a possibility. But surely you're one day going to want to run > your cabal-installed programs yourself (there are some pretty handy > ones), so the easiest thing is to extend your path. > You're right. Added .cabal/bin to path and everything is ok. > It might be a good idea for cabal-install to warn that its bin > directory is not in your path when you install an executable. > Yep, might be an interesting idea for warning. :) > --Max From daniel.is.fischer at web.de Fri Jun 19 17:59:11 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Fri Jun 19 17:43:10 2009 Subject: [Haskell-cafe] Installing agda through cabal In-Reply-To: <1245447665.15603.3.camel@drserver> References: <1245443002.15603.1.camel@drserver> <1245447665.15603.3.camel@drserver> Message-ID: <200906192359.12319.daniel.is.fischer@web.de> Am Freitag 19 Juni 2009 23:41:05 schrieb Paulo J. Matos: > > It might be a good idea for cabal-install to warn that its bin > > directory is not in your path when you install an executable. > > Yep, might be an interesting idea for warning. :) This has been discussed in connection to the question where cabal should by default install things. IIRC, the plan is to have cabal display a message on first startup asking the user for the default install location [of binaries] and telling them to make sure it's in the path. From dvde at gmx.net Fri Jun 19 19:16:35 2009 From: dvde at gmx.net (Daniel van den Eijkel) Date: Fri Jun 19 18:59:45 2009 Subject: [Haskell-cafe] Use MySQL from Haskell In-Reply-To: <4A3BD4DD.1040901@googlemail.com> References: <4A3AB0EA.4090304@googlemail.com> <29bf512f0906181512i50dec0d9ge04be77ab4e3f668@mail.gmail.com> <4A3B7B78.5040207@gmx.net> <4A3BD4DD.1040901@googlemail.com> Message-ID: <4A3C1C53.8020508@gmx.net> Hi Maciej, Database.HDBC.getTables works fine here (XP, ghc 6.10.2, HDBC-2.1.0, HDBC-ODBC-2.1.0.0) - it gives me the list of all tablenames, as intended. Which HDBC version do you use? best regards, daniel Maciej Podgurski schrieb: > Does Database.HDBC.getTables work for you? I successfully created a > new table and selected data from a database but getTables always > returns an empty list (what is not a big problem since a query "show > tables" works fine). > > Besh wishes, > Maciej > > > W dniu 19.06.2009 13:50 Daniel van den Eijkel pisze: >> The same with me - I'm on XP, and HDBC-odbc is the library I got >> running to access the MySQL database. >> Regards, >> Daniel >> >> >> Michael Snoyman schrieb: >>> Marciej, >>> >>> I went the HDBC route and got the same problem. Although it does not >>> seem to be officially blessed, try installing the time-1.1.3 >>> package. It's working for me at least, which I know is a dubious >>> recommendation. >>> >>> Also, I am currently using the hdbc-odbc package for accessing >>> MySQL. I couldn't get hdbc-mysql to work properly. I hope that once >>> I get this project working right, I'll have a chance to dig into the >>> hdbc-mysql issue itself. >>> >>> Good luck! >>> >>> Michael > From niklas.broberg at gmail.com Fri Jun 19 19:31:21 2009 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Fri Jun 19 19:14:29 2009 Subject: [Haskell-cafe] Re: ANN: haskell-src-exts 1.0.0 rc1 (aka 0.5.2) In-Reply-To: References: Message-ID: Hi all, > Another day, another release candidate. Please see > haskell-src-exts-0.5.5, 1.0.0 rc3. Thanks a lot to all reports, and > please keep up the good work! Here we go again. Please have a look at haskell-src-exts-0.5.6, or 1.0.0 rc4. Thanks again for the reports, they're all truly invaluable. Changes in 0.5.6: =================== One major addition: * Support for relaxed layout in do-blocks! Yes, I caved in, after I got enough reports about it. Two stupid bugs fixed: * MagicHash ConId lexemes can now be followed by things other than space characters (like closing brackets: foo :: (Int#)). * ctypes (i.e. types with contexts and forall-quantifiers) can now appear inside tuples and lists if the proper extensions are on. Cheers, /Niklas From maciej.podgurski at googlemail.com Fri Jun 19 20:27:02 2009 From: maciej.podgurski at googlemail.com (Maciej Podgurski) Date: Fri Jun 19 20:10:17 2009 Subject: [Haskell-cafe] Use MySQL from Haskell In-Reply-To: <4A3C1C53.8020508@gmx.net> References: <4A3AB0EA.4090304@googlemail.com> <29bf512f0906181512i50dec0d9ge04be77ab4e3f668@mail.gmail.com> <4A3B7B78.5040207@gmx.net> <4A3BD4DD.1040901@googlemail.com> <4A3C1C53.8020508@gmx.net> Message-ID: <4A3C2CD6.4040004@googlemail.com> Hi Daniel, I use HDBC-2.1.1 + HDBC-odbc-2.1.0.0 with GHC 6.8.3 and MySQL Server 5.1 on XP. The hsql equivalent Database.HSQL.tables works as expected. Best wishes, Maciej W dniu 20.06.2009 01:16 Daniel van den Eijkel pisze: > Hi Maciej, > > Database.HDBC.getTables works fine here (XP, ghc 6.10.2, HDBC-2.1.0, > HDBC-ODBC-2.1.0.0) - it gives me the list of all tablenames, as > intended. Which HDBC version do you use? > > best regards, > daniel > > > Maciej Podgurski schrieb: >> Does Database.HDBC.getTables work for you? I successfully created a >> new table and selected data from a database but getTables always >> returns an empty list (what is not a big problem since a query "show >> tables" works fine). >> >> Besh wishes, >> Maciej From gue.schmidt at web.de Fri Jun 19 20:29:37 2009 From: gue.schmidt at web.de (=?UTF-8?B?R8O8wp9udGhlciBTY2htaWR0?=) Date: Fri Jun 19 20:12:58 2009 Subject: [Haskell-cafe] hs-dotnet users? Message-ID: Hi all, I'm just touching base with Sigbjorns hs-dotnet package. Are there other users of this package out there who would like to share their experience? G?nther From scooter.phd at gmail.com Fri Jun 19 21:43:29 2009 From: scooter.phd at gmail.com (Scott Michel) Date: Fri Jun 19 21:26:36 2009 Subject: [Haskell-cafe] Getting my mind around UArray -> STUArray conversion Message-ID: <258cd3200906191843m44d96543mc8140fa9a787b843@mail.gmail.com> I'm trying to get my mind around how to thaw and then freeze a UArray. Theoretically, what I've written below should be a no-op, but I keep getting typing errors that I can't figure out. GHCI 6.10.3 says: Couldn't match expected type `UArray ix a' against inferred type `ST s (STUArray s ix1 e)' In the first argument of `(>>=)', namely `(unsafeThaw mem :: ST s (STUArray s ix e))' In the expression: (unsafeThaw mem :: ST s (STUArray s ix e)) >>= (\ mmem -> unsafeFreeze mmem) In the definition of `wombat': wombat val idx mem = (unsafeThaw mem :: ST s (STUArray s ix e)) >>= (\ mmem -> unsafeFreeze mmem) I'm figuring that usafeThaw with the type annotation should have given GHIC enough clue. Any suggestions? -scooter (WOMBAT = Waste Of Money Brains And Time) import Control.Monad; import Control.Monad.ST; import Data.Array.ST; import Data.Array.Unboxed; import Data.Array.MArray; import Data.Word; wombat :: (IArray UArray e, Ix ix, MArray (STUArray s) e (ST s)) => e -> ix -> UArray ix e -> UArray ix e wombat val idx mem = (unsafeThaw mem :: ST s (STUArray s ix e)) >>= (\mmem -> unsafeFreeze mmem) From dan.doel at gmail.com Fri Jun 19 21:51:08 2009 From: dan.doel at gmail.com (Dan Doel) Date: Fri Jun 19 21:34:19 2009 Subject: [Haskell-cafe] Getting my mind around UArray -> STUArray conversion In-Reply-To: <258cd3200906191843m44d96543mc8140fa9a787b843@mail.gmail.com> References: <258cd3200906191843m44d96543mc8140fa9a787b843@mail.gmail.com> Message-ID: <200906192151.09436.dan.doel@gmail.com> On Friday 19 June 2009 9:43:29 pm Scott Michel wrote: > wombat :: (IArray UArray e, Ix ix, MArray (STUArray s) e (ST s)) => e > -> ix -> UArray ix e -> UArray ix e > wombat val idx mem = (unsafeThaw mem :: ST s (STUArray s ix e)) >>= > (\mmem -> unsafeFreeze mmem) Based on the error message and dealing with this sort of thing before, your problem is that when you say: ":: ST s (STUArray s ix e)" the s, ix and e there aren't the same as they are in the signature of wombat. To make them the same, you need the ScopedTypeVariables extension, and to make wombat's signature: wombat :: forall e ix s. ... where the dots are your current signature. It's possible you'll still have errors, but that will solve the one in your mail. -- Dan From daniel.is.fischer at web.de Fri Jun 19 22:03:42 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Fri Jun 19 21:47:40 2009 Subject: [Haskell-cafe] Getting my mind around UArray -> STUArray conversion In-Reply-To: <200906192151.09436.dan.doel@gmail.com> References: <258cd3200906191843m44d96543mc8140fa9a787b843@mail.gmail.com> <200906192151.09436.dan.doel@gmail.com> Message-ID: <200906200403.42947.daniel.is.fischer@web.de> Am Samstag 20 Juni 2009 03:51:08 schrieb Dan Doel: > On Friday 19 June 2009 9:43:29 pm Scott Michel wrote: > > wombat :: (IArray UArray e, Ix ix, MArray (STUArray s) e (ST s)) => e > > -> ix -> UArray ix e -> UArray ix e > > wombat val idx mem = (unsafeThaw mem :: ST s (STUArray s ix e)) >>= > > (\mmem -> unsafeFreeze mmem) > > Based on the error message and dealing with this sort of thing before, your > problem is that when you say: > > ":: ST s (STUArray s ix e)" > > the s, ix and e there aren't the same as they are in the signature of > wombat. To make them the same, you need the ScopedTypeVariables extension, > and to make wombat's signature: > > wombat :: forall e ix s. ... > > where the dots are your current signature. > > It's possible you'll still have errors, but that will solve the one in your > mail. > > -- Dan No, only part of it. Another part is unsafeFreeze :: (Ix i, MArray a e m, IArray b e) => a i e -> m (b i e) so unsafeThaw arr >>= unsafeFreeze lives in a monad, here (ST s) and to get the type he wants, he has to wrap it in runST. From dan.doel at gmail.com Fri Jun 19 22:08:29 2009 From: dan.doel at gmail.com (Dan Doel) Date: Fri Jun 19 21:51:40 2009 Subject: [Haskell-cafe] Getting my mind around UArray -> STUArray conversion In-Reply-To: <258cd3200906191843m44d96543mc8140fa9a787b843@mail.gmail.com> References: <258cd3200906191843m44d96543mc8140fa9a787b843@mail.gmail.com> Message-ID: <200906192208.30175.dan.doel@gmail.com> Oops, I replied too hastily. What I wrote in my first mail is a problem, as witnessed by the "ix" and "ix1" in the error message. However, it isn't the main error. The main error is that you have a monadic expression, with type something like: ST s (UArray ix e) but the return type of your function is: UArray ix e To make a no-op you need to add a runST, something like: runST (unsafeThaw mem >>= unsafeFreeze) If you need to annotate 'unsafeThaw mem', that's where the ScopedTypeVariables will come in. However, there's also an issue that mentioning 's' in the type of wombat won't work with the runST, which may be a problem with the MArray constraint (and I'm not sure what to do about that off the top of my head; I've not worked with STUArray in a while, so you may be constructing an unresolvable ambiguity). Sorry for the confusion. -- Dan From wren at freegeek.org Sat Jun 20 00:03:35 2009 From: wren at freegeek.org (wren ng thornton) Date: Fri Jun 19 23:46:49 2009 Subject: [Haskell-cafe] Confusion on the third monad law when using lambda abstractions In-Reply-To: <1245324183.4762.6.camel@dhcppc0> References: <4A39938D.7020400@moonloop.net> <4A39A5C6.2060102@gmail.com> <1245324183.4762.6.camel@dhcppc0> Message-ID: <4A3C5F97.1070801@freegeek.org> Hans van Thiel wrote: > On Wed, 2009-06-17 at 21:26 -0500, Jake McArthur wrote: >> Jon Strait wrote: >>> I'm reading the third (bind associativity) law for monads in this form: >>> >>> m >>= (\x -> k x >>= h) = (m >>= k) >>= h >> Arguably, that law would be better stated as: >> >> (h <=< k) <=< m = h <=< (k <=< m) >> >> This wouldn't be so unintuitive. > Hi, > The only place I've ever seen Kleisli composition, or its flip, used is > in demonstrating the monad laws. Yet it is so elegant and, even having > its own name, it must have some practical use. Do you, or anybody else, > have some pointers? import Prelude hiding (mapM) import Data.Traversable (mapM) import Control.Monad ((<=<)) newtype Fix f = Fix { unFix :: f (Fix f) } cata phi = phi . fmap (cata phi) . unFix cataM phiM = phiM <=< (mapM (cataM phiM) . unFix) ana psi = Fix . fmap (ana psi) . psi anaM psiM = (liftM Fix . mapM (anaM psiM)) <=< psiM etc. It's great for anyone who enjoys point-free style but wants to work with monads. -- Live well, ~wren From andrewcoppin at btinternet.com Sat Jun 20 11:29:31 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sat Jun 20 11:12:35 2009 Subject: [Haskell-cafe] Obscure weirdness Message-ID: <4A3D005B.1010307@btinternet.com> OK, so here's an interesting problem... I've been coding away all day, but now my program is doing something slightly weird. For a specific input, it summarily terminates. The registered exception handler does not fire. There is no output to stdout or stderr indicating what the problem is. It just *stops* half way through the printout. Weirder: If I run it in GHCi, then GHCi itself terminates. (I didn't think you could *do* that!) It's not as if my program is anything unusual. There are no unsafe functions. No FFI. Nothing. Just regular high-level Haskell. Is this a known bug in GHC 6.10.1? Will upgrading fix it? (Obviously, it's quite a lot of work to change GHC.) Suffice it to say that my program is quite big and complicated; it worked fine when it was still small and simple. ;-) From alexander.dunlap at gmail.com Sat Jun 20 13:14:55 2009 From: alexander.dunlap at gmail.com (Alexander Dunlap) Date: Sat Jun 20 12:58:20 2009 Subject: [Haskell-cafe] Obscure weirdness In-Reply-To: <4A3D005B.1010307@btinternet.com> References: <4A3D005B.1010307@btinternet.com> Message-ID: <57526e770906201014s6d3b0c1g7e48f7f6c9985aed@mail.gmail.com> On Sat, Jun 20, 2009 at 8:29 AM, Andrew Coppin wrote: > > OK, so here's an interesting problem... > > I've been coding away all day, but now my program is doing something slightly weird. For a specific input, it summarily terminates. The registered exception handler does not fire. There is no output to stdout or stderr indicating what the problem is. It just *stops* half way through the printout. > > Weirder: If I run it in GHCi, then GHCi itself terminates. (I didn't think you could *do* that!) > > It's not as if my program is anything unusual. There are no unsafe functions. No FFI. Nothing. Just regular high-level Haskell. > > Is this a known bug in GHC 6.10.1? Will upgrading fix it? (Obviously, it's quite a lot of work to change GHC.) Suffice it to say that my program is quite big and complicated; it worked fine when it was still small and simple. ;-) > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe I think you'll need to provide a bit more detail about what you're doing in order for anyone to have anything to go off of. If you can link to the source, that would help, or even give a summary of what you're trying to do. Alex From andrewcoppin at btinternet.com Sat Jun 20 13:34:12 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sat Jun 20 13:17:16 2009 Subject: [Haskell-cafe] Obscure weirdness In-Reply-To: <57526e770906201014s6d3b0c1g7e48f7f6c9985aed@mail.gmail.com> References: <4A3D005B.1010307@btinternet.com> <57526e770906201014s6d3b0c1g7e48f7f6c9985aed@mail.gmail.com> Message-ID: <4A3D1D94.2010602@btinternet.com> Alexander Dunlap wrote: > On Sat, Jun 20, 2009 at 8:29 AM, Andrew Coppin > wrote: > >> OK, so here's an interesting problem... >> >> I've been coding away all day, but now my program is doing something slightly weird. For a specific input, it summarily terminates. The registered exception handler does not fire. There is no output to stdout or stderr indicating what the problem is. It just *stops* half way through the printout. >> >> Weirder: If I run it in GHCi, then GHCi itself terminates. (I didn't think you could *do* that!) >> > > I think you'll need to provide a bit more detail about what you're > doing in order for anyone to have anything to go off of. If you can > link to the source, that would help, or even give a summary of what > you're trying to do. > The program takes some text, parses it as a lambda calculus expression, and prints it out again. Except, somewhere during the variable uniqueness pass, the program just halts. For no defined reason. As you can see, nothing remotely unusual for a Haskell program to be doing. And yet, the result is very unusual. (I.e., halting part-way through some pure code without throwing an exception.) Given that it doesn't appear to be a known bug (presumably somebody would have said something by now if it was...), I think I'm going to try upgrading GHC anyway, just for arguments' sake, and see if that fixes it. From rmm-haskell at z.odi.ac Sat Jun 20 13:54:41 2009 From: rmm-haskell at z.odi.ac (Ross Mellgren) Date: Sat Jun 20 13:37:50 2009 Subject: [Haskell-cafe] Obscure weirdness In-Reply-To: <4A3D1D94.2010602@btinternet.com> References: <4A3D005B.1010307@btinternet.com> <57526e770906201014s6d3b0c1g7e48f7f6c9985aed@mail.gmail.com> <4A3D1D94.2010602@btinternet.com> Message-ID: <9A88F751-35D6-43E8-9973-68D980B3F05F@z.odi.ac> Really, without code or more than "it just disappears", it's just conjecture what's happening. Can you post the code, or even better yet a minimized case that reproduces it? -Ross On Jun 20, 2009, at 1:34 PM, Andrew Coppin wrote: > Alexander Dunlap wrote: >> On Sat, Jun 20, 2009 at 8:29 AM, Andrew Coppin >> wrote: >> >>> OK, so here's an interesting problem... >>> >>> I've been coding away all day, but now my program is doing >>> something slightly weird. For a specific input, it summarily >>> terminates. The registered exception handler does not fire. There >>> is no output to stdout or stderr indicating what the problem is. >>> It just *stops* half way through the printout. >>> >>> Weirder: If I run it in GHCi, then GHCi itself terminates. (I >>> didn't think you could *do* that!) >>> >> >> I think you'll need to provide a bit more detail about what you're >> doing in order for anyone to have anything to go off of. If you can >> link to the source, that would help, or even give a summary of what >> you're trying to do. >> > > The program takes some text, parses it as a lambda calculus > expression, and prints it out again. Except, somewhere during the > variable uniqueness pass, the program just halts. For no defined > reason. > > As you can see, nothing remotely unusual for a Haskell program to be > doing. And yet, the result is very unusual. (I.e., halting part-way > through some pure code without throwing an exception.) > > Given that it doesn't appear to be a known bug (presumably somebody > would have said something by now if it was...), I think I'm going to > try upgrading GHC anyway, just for arguments' sake, and see if that > fixes it. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From irving at naml.us Sat Jun 20 13:57:11 2009 From: irving at naml.us (Geoffrey Irving) Date: Sat Jun 20 13:40:35 2009 Subject: [Haskell-cafe] unique identity and name shadowing during type inference Message-ID: <7f9d599f0906201057i41907cefmb0cc84d7f30cdf8d@mail.gmail.com> Hello, I am designing a type inference algorithm for a language with arbitrary function overloading. For various reasons (beyond the scope of this email), it's impossible to know the full type of an overloaded function, so each function is assigned a unique primitive type and the inference algorithm gradually learns more information about the primitive. For example, if we declare an identity function f x = x the algorithm will create a primitive type F, and record f :: F. If we use the function a few times, f 1 f "blah" the algorithm will infer F Int = Int F String = String My question is: what's the best way to represent these unique primitive types in Haskell? A new type primitive needs to be created whenever we process a function declaration. Nested function declarations produce a different primitive each time the parent is invoked with different argument types. These separate primitives can escape if local functions are returned, so the inference algorithm must be able to keep them separate and learn more about them after their parent function is forgotten. Here are a few ways I know of: 1. Thread a uniqueness generator monad through the whole algorithm. I'd prefer to avoid this extra plumbing if possible. 2. Label primitives with the full context of how they were created. If function f declares a nested function g, and f is called with Int and Char, the primitives for g would be labeled with "f Int" and "f Char" to keep them separate. This is similar to lambda lifting. 3. Scary hacks involving makeStableName and unsafePerformIO. Some sort of context would have to be thrown around here to make sure GHC doesn't merge the different makeStableName calls. Unfortunately, method (2) is complicated by the fact that variable names are not unique even in the internal representation (I'm using the trick from [1]), so I'm not sure what the minimal unique "context" would be. Does anyone know other methods outside of (1), (2), or (3), or clean ways of structuring (2) or (3)? Thanks! Geoffrey [1]: http://www.haskell.org/~simonmar/bib/ghcinliner02_abstract.html From conal at conal.net Sat Jun 20 14:04:37 2009 From: conal at conal.net (Conal Elliott) Date: Sat Jun 20 13:48:03 2009 Subject: [Haskell-cafe] Tree Semantics and efficiency In-Reply-To: <4A39013E.1060004@gmail.com> References: <296381.66639.qm@web23701.mail.ird.yahoo.com> <4A39013E.1060004@gmail.com> Message-ID: Moreover, copying is not even meaningful in a functional setting. A data structure is indistinguishable from a copy of the data structure. In languages that allow mutation of data, one has to carefully copy data to avoid accidental mutation by other computations. Disallow data mutation, and the problem disappears. - Conal On Wed, Jun 17, 2009 at 7:44 AM, Jake McArthur wrote: > Rouan van Dalen wrote: > >> It is important to store only a reference to the parent and not a copy of >> the entire parent for efficiency. >> > > Others have already recommended the rosezipper package, which gives you > what you want, but I want to address one thing. > > foo = > bar = foo > > In most implementations (including GHC, which I assume you are using), > `bar` will *not* be an actual copy of `foo`. In fact, GHC will not make a > deep copy of a structure unless you pattern match all the way down and > reconstruct it all the way back up yourself. > > If you use a zipper, like Data.Tree.Zipper mentioned already, moving around > will not create and destroy tons of data. It will only create and destroy > the spine of the tree local to the current "pointer" into the tree, which is > not a lot of data. If you are holding on to older versions of the zipper, of > course, they won't even be destroyed. > > - Jake > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090620/b1b8485c/attachment.html From deniz.a.m.dogan at gmail.com Sat Jun 20 14:05:11 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Sat Jun 20 13:48:19 2009 Subject: [Haskell-cafe] Code walking off the right edge of the screen Message-ID: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> I (too) often find myself writing code such as this: if something then putStrLn "howdy there!" else if somethingElse then putStrLn "howdy ho!" else ... I recall reading some tutorial about how you can use the Maybe monad if your code starts looking like this, but as you can see, that doesn't really apply here. "something" and "somethingElse" are simply booleans and each of them have different actions to take if either of them is True. So how do I make code like this prettier? Thanks, Deniz Dogan From tphyahoo at gmail.com Sat Jun 20 14:16:34 2009 From: tphyahoo at gmail.com (Thomas Hartman) Date: Sat Jun 20 13:59:39 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list In-Reply-To: References: <1245363427.8395.21.camel@localhost> Message-ID: <910ddf450906201116h73c3c07y3ababe974615c27c@mail.gmail.com> could someone explain sharing? In the code below, allstrings2 is 6X as fast as allstrings. I assume because of sharing, but I don't intuitively see a reason why. can someone give me some pointers, perhaps using debug.trace or other tools (profiling?) to show where the first version is being inefficient? *********** letters = ['a'..'z'] strings 0 = [""] strings n = [ c : s | c <- letters, s <- strings (n-1) x ] allstrings = concat $ map strings [1..] allstrings2 = let sss = [""] : [ [ c:s | c <- letters, s <- ss ] | ss <- sss ] in concat $ tail sss t = allstrings !! wanted t2 = allstrings2 !! wanted wanted = (10^2) 2009/6/18 Lee Duhem : > On Fri, Jun 19, 2009 at 6:17 AM, Matthew Brecknell wrote: >> On Thu, 2009-06-18 at 23:57 +0800, Lee Duhem wrote: >>> [...] I have prepared a blog post for how >>> I worked out some of these answers, here is the draft of it, I hope it >>> can help you too. >> >> Nice post! Certainly, pen-and-paper reasoning like this is a very good >> way to develop deeper intuitions. >> >>> ? ? ? Answer 1 (by Matthew Brecknell): >>> >>> ? ? ? concat $ tail $ iterate (map (:) ['a' .. 'z'] <*>) [[]] >> >> I actually said "tail $ concat $ iterate ...", because I think the >> initial empty string is logically part of the sequence. Tacking "tail" >> on the front then produces the subsequence requested by the OP. > > Yes, I changed your solution from "tail $ concat $ iterate ..." to > "concat $ tail $ iterate ...", because I think cut useless part out early > is good idea, forgot to mention that, sorry. > >> >> I should have given more credit to Reid for this solution. I'm always >> delighted to see people using monadic combinators (like replicateM) in >> the list monad, because I so rarely think to use them this way. Sadly, >> my understanding of these combinators is still somewhat stuck in IO, >> where I first learned them. I never would have thought to use <*> this >> way if I had not seen Reid's solution first. > > Actually, I first figure out how Reid's solution works, then figure out yours. > After that, I found, for me, your solution's logic is easier to understand, > so I take it as my first example. As I said at the end, or as I'll > said at the end, > Reid' solution and yours are the same (except effective) > > lee > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From miguelimo38 at yandex.ru Sat Jun 20 14:43:11 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Sat Jun 20 14:26:18 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list In-Reply-To: <910ddf450906201116h73c3c07y3ababe974615c27c@mail.gmail.com> References: <1245363427.8395.21.camel@localhost> <910ddf450906201116h73c3c07y3ababe974615c27c@mail.gmail.com> Message-ID: <25AB9A7C-EDF4-4E3C-8ECC-53AB7D0C4CA8@yandex.ru> Well, I'm hardly the one knowing GHC internals, but... In allstrings you continue calling "strings" with same arguments again and again. Don't fool yourself, it's not going to automagically memorize what you were doing before. In fact, I'd expect much more speed loss. If you increase your "wanted" constant, you'll probably notice it. Anyway, you allstrings2 is much nicer - the problem you're solving has nothing to do with numbers, so "map whatever [1..]" seems out of place. On 20 Jun 2009, at 22:16, Thomas Hartman wrote: > could someone explain sharing? > > In the code below, allstrings2 is 6X as fast as allstrings. I assume > because of sharing, but I don't intuitively see a reason why. > > can someone give me some pointers, perhaps using debug.trace or other > tools (profiling?) to show where the first version is being > inefficient? > > > *********** > > letters = ['a'..'z'] > > strings 0 = [""] > strings n = [ c : s | c <- letters, s <- strings (n-1) x ] > > allstrings = concat $ map strings [1..] > > allstrings2 = let sss = [""] : [ [ c:s | c <- letters, s <- ss ] | > ss <- sss ] > in concat $ tail sss > > t = allstrings !! wanted > t2 = allstrings2 !! wanted > > wanted = (10^2) > > > 2009/6/18 Lee Duhem : >> On Fri, Jun 19, 2009 at 6:17 AM, Matthew Brecknell> > wrote: >>> On Thu, 2009-06-18 at 23:57 +0800, Lee Duhem wrote: >>>> [...] I have prepared a blog post for how >>>> I worked out some of these answers, here is the draft of it, I >>>> hope it >>>> can help you too. >>> >>> Nice post! Certainly, pen-and-paper reasoning like this is a very >>> good >>> way to develop deeper intuitions. >>> >>>> Answer 1 (by Matthew Brecknell): >>>> >>>> concat $ tail $ iterate (map (:) ['a' .. 'z'] <*>) [[]] >>> >>> I actually said "tail $ concat $ iterate ...", because I think the >>> initial empty string is logically part of the sequence. Tacking >>> "tail" >>> on the front then produces the subsequence requested by the OP. >> >> Yes, I changed your solution from "tail $ concat $ iterate ..." to >> "concat $ tail $ iterate ...", because I think cut useless part out >> early >> is good idea, forgot to mention that, sorry. >> >>> >>> I should have given more credit to Reid for this solution. I'm >>> always >>> delighted to see people using monadic combinators (like >>> replicateM) in >>> the list monad, because I so rarely think to use them this way. >>> Sadly, >>> my understanding of these combinators is still somewhat stuck in IO, >>> where I first learned them. I never would have thought to use <*> >>> this >>> way if I had not seen Reid's solution first. >> >> Actually, I first figure out how Reid's solution works, then figure >> out yours. >> After that, I found, for me, your solution's logic is easier to >> understand, >> so I take it as my first example. As I said at the end, or as I'll >> said at the end, >> Reid' solution and yours are the same (except effective) >> >> lee >> _______________________________________________ >> 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 deduktionstheorem at web.de Sat Jun 20 14:45:16 2009 From: deduktionstheorem at web.de (Stephan Friedrichs) Date: Sat Jun 20 14:28:28 2009 Subject: [Haskell-cafe] Code walking off the right edge of the screen In-Reply-To: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> References: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> Message-ID: <4A3D2E3C.5040809@web.de> Deniz Dogan wrote: > I (too) often find myself writing code such as this: > > if something > then putStrLn "howdy there!" > else if somethingElse > then putStrLn "howdy ho!" > else ... > > [...] > > So how do I make code like this prettier? If it's a function, you can use guards: foo :: ... foo something somethingElse | something -> putStrLn "howdy there!" | somethingElse -> putStrLn "howdy ho!" | otherwise -> ... -- Fr?her hie? es ja: Ich denke, also bin ich. Heute wei? man: Es geht auch so. - Dieter Nuhr From deniz.a.m.dogan at gmail.com Sat Jun 20 14:51:00 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Sat Jun 20 14:34:05 2009 Subject: [Haskell-cafe] Code walking off the right edge of the screen In-Reply-To: <4A3D2E3C.5040809@web.de> References: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> <4A3D2E3C.5040809@web.de> Message-ID: <7b501d5c0906201151m767de77cs5f3cbe647d57a282@mail.gmail.com> 2009/6/20 Stephan Friedrichs : > Deniz Dogan wrote: >> I (too) often find myself writing code such as this: >> >> if something >> ? then putStrLn "howdy there!" >> ? else if somethingElse >> ? ? ? ? ? then putStrLn "howdy ho!" >> ? ? ? ? ? else ... >> >> [...] >> >> So how do I make code like this prettier? > > If it's a function, you can use guards: > > foo :: ... > foo something somethingElse > ? ?| something ? ? -> putStrLn "howdy there!" > ? ?| somethingElse -> putStrLn "howdy ho!" > ? ?| otherwise ? ? -> ... Good idea, I hadn't thought of that... Currently this is all in the main function, checking the command line arguments. I suppose I could put it in a separate function. Thanks! -- Deniz Dogan From jeremy at n-heptane.com Sat Jun 20 15:00:11 2009 From: jeremy at n-heptane.com (Jeremy Shaw) Date: Sat Jun 20 14:43:17 2009 Subject: [Haskell-cafe] Code walking off the right edge of the screen In-Reply-To: <4A3D2E3C.5040809@web.de> References: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> <4A3D2E3C.5040809@web.de> Message-ID: <87hbyaenno.wl%jeremy@n-heptane.com> At Sat, 20 Jun 2009 20:45:16 +0200, Stephan Friedrichs wrote: > If it's a function, you can use guards: > > foo :: ... > foo something somethingElse > | something -> putStrLn "howdy there!" > | somethingElse -> putStrLn "howdy ho!" > | otherwise -> ... You can also artificially introduce places to use gaurds inside a function: foo = let x | 1 > 1 = "uh-oh" | otherwise = "all is well" in x bar = case () of _ | 1 > 1 -> "uh-oh" | otherwise -> "all is well" - jeremy From aslatter at gmail.com Sat Jun 20 15:12:56 2009 From: aslatter at gmail.com (Antoine Latter) Date: Sat Jun 20 14:56:01 2009 Subject: [Haskell-cafe] Code walking off the right edge of the screen In-Reply-To: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> References: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> Message-ID: <694519c50906201212p10c77a83m5977ea5dce103cd6@mail.gmail.com> On Sat, Jun 20, 2009 at 1:05 PM, Deniz Dogan wrote: > I (too) often find myself writing code such as this: > > if something > ?then putStrLn "howdy there!" > ?else if somethingElse > ? ? ? ? ?then putStrLn "howdy ho!" > ? ? ? ? ?else ... > > I recall reading some tutorial about how you can use the Maybe monad > if your code starts looking like this, but as you can see, that > doesn't really apply here. "something" and "somethingElse" are simply > booleans and each of them have different actions to take if either of > them is True. > > So how do I make code like this prettier? I'm not entirely sure if this is haskell'98, but GHC seems to support this sort of layout: >>>>> main = do if something then someOtherComputation else do <<<<< Antoine From marcin.kosiba at gmail.com Sat Jun 20 15:19:36 2009 From: marcin.kosiba at gmail.com (Marcin Kosiba) Date: Sat Jun 20 15:02:54 2009 Subject: [Haskell-cafe] Obscure weirdness In-Reply-To: <4A3D005B.1010307@btinternet.com> References: <4A3D005B.1010307@btinternet.com> Message-ID: <200906202119.36738.marcin.kosiba@gmail.com> On Saturday 20 June 2009, Andrew Coppin wrote: > OK, so here's an interesting problem... > > I've been coding away all day, but now my program is doing something > slightly weird. For a specific input, it summarily terminates. The > registered exception handler does not fire. There is no output to stdout > or stderr indicating what the problem is. It just *stops* half way > through the printout. > > Weirder: If I run it in GHCi, then GHCi itself terminates. (I didn't > think you could *do* that!) > > It's not as if my program is anything unusual. There are no unsafe > functions. No FFI. Nothing. Just regular high-level Haskell. > > Is this a known bug in GHC 6.10.1? Will upgrading fix it? (Obviously, > it's quite a lot of work to change GHC.) Suffice it to say that my > program is quite big and complicated; it worked fine when it was still > small and simple. ;-) Hi, With the information you've provided it's hard to even guess. At least take a look at your app's RAM usage -- it just may be that its allocating too much memory and the OOM killer is killing it (if you're running linux, that is). You may also want to try the GHCi debugger [1] to find out where the program crashes. The last thing I'd do is blame it on ghc/ghci, but as always -- such a possibility exists. Thanks! Marcin Kosiba [1] http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-debugger.html From pumpkingod at gmail.com Sat Jun 20 15:21:59 2009 From: pumpkingod at gmail.com (Daniel Peebles) Date: Sat Jun 20 15:05:04 2009 Subject: [Haskell-cafe] Code walking off the right edge of the screen In-Reply-To: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> References: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> Message-ID: The when and unless functions might come in handy too (both have type forall (m :: * -> *). (Monad m) => Bool -> m () -> m ()) On Sat, Jun 20, 2009 at 2:05 PM, Deniz Dogan wrote: > I (too) often find myself writing code such as this: > > if something > ?then putStrLn "howdy there!" > ?else if somethingElse > ? ? ? ? ?then putStrLn "howdy ho!" > ? ? ? ? ?else ... > > I recall reading some tutorial about how you can use the Maybe monad > if your code starts looking like this, but as you can see, that > doesn't really apply here. "something" and "somethingElse" are simply > booleans and each of them have different actions to take if either of > them is True. > > So how do I make code like this prettier? > > Thanks, > Deniz Dogan > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From gwern0 at gmail.com Sat Jun 20 15:58:19 2009 From: gwern0 at gmail.com (Gwern Branwen) Date: Sat Jun 20 15:41:26 2009 Subject: [Haskell-cafe] Re: Wiki user accounts In-Reply-To: <4A39FA2D.4040604@semantic.org> References: <1244822326.28941.29.camel@flippa-eee> <1245086323.3817.2.camel@glastonbury> <1245089315.5131.5.camel@flippa-eee> <4A369677.2010500@therning.org> <4A36A31A.10504@semantic.org> <4A3827CC.50806@semantic.org> <4A3864B3.5020000@semantic.org> <4A39FA2D.4040604@semantic.org> Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Ok, we now have 3 people with createaccount: http://haskell.org/haskellwiki/?title=Special%3AListusers&group=createaccount&username= myself byorgey & Magnus (Neil Mitchell and Don Stewart having not accepted/declined in this thread.) Does anyone feel a need for these people to also be admins, or will just createaccount status handle the wiki's problems for the foreseeable future? - -- gwern -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEAREKAAYFAko9P1sACgkQvpDo5Pfl1oIOUgCgnYFfMGSY4ppDjY+ZW9da0rjC L3IAn0+k1G8ya9o3oTZ/NXs8mx7Xa1gN =A82l -----END PGP SIGNATURE----- From jochem at functor.nl Sat Jun 20 16:25:29 2009 From: jochem at functor.nl (Jochem Berndsen) Date: Sat Jun 20 16:08:35 2009 Subject: [Haskell-cafe] Code walking off the right edge of the screen In-Reply-To: <694519c50906201212p10c77a83m5977ea5dce103cd6@mail.gmail.com> References: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> <694519c50906201212p10c77a83m5977ea5dce103cd6@mail.gmail.com> Message-ID: <4A3D45B9.70608@functor.nl> Antoine Latter wrote: > On Sat, Jun 20, 2009 at 1:05 PM, Deniz Dogan wrote: >> I (too) often find myself writing code such as this: >> >> if something >> then putStrLn "howdy there!" >> else if somethingElse >> then putStrLn "howdy ho!" >> else ... >> >> I recall reading some tutorial about how you can use the Maybe monad >> if your code starts looking like this, but as you can see, that >> doesn't really apply here. "something" and "somethingElse" are simply >> booleans and each of them have different actions to take if either of >> them is True. >> >> So how do I make code like this prettier? > > I'm not entirely sure if this is haskell'98, but GHC seems to support > this sort of layout: > > main = do > > > if something then someOtherComputation else do > > > <<<<< IMHO, this is ugly and counterintuitive; I like having a single "point of exit" (to use an imperative programming term) of a function. Your suggestion is equivalent to someComputation; if something then begin someOtherComputation; exit; end; more; in, say, Pascal. This obscures the fact that "more;" is sometimes/often not executed. (You could argue the same about exceptions, but they are a necessary evil ;-). Regards, -- Jochem Berndsen | jochem@functor.nl GPG: 0xE6FABFAB From andrewcoppin at btinternet.com Sat Jun 20 16:36:58 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sat Jun 20 16:20:00 2009 Subject: [Haskell-cafe] Obscure weirdness In-Reply-To: <200906202119.36738.marcin.kosiba@gmail.com> References: <4A3D005B.1010307@btinternet.com> <200906202119.36738.marcin.kosiba@gmail.com> Message-ID: <4A3D486A.5040600@btinternet.com> Marcin Kosiba wrote: > On Saturday 20 June 2009, Andrew Coppin wrote: > >> OK, so here's an interesting problem... >> >> I've been coding away all day, but now my program is doing something >> slightly weird. For a specific input, it summarily terminates. The >> registered exception handler does not fire. There is no output to stdout >> or stderr indicating what the problem is. It just *stops* half way >> through the printout. >> >> Weirder: If I run it in GHCi, then GHCi itself terminates. (I didn't >> think you could *do* that!) >> > Hi, > With the information you've provided it's hard to even guess. At least take a > look at your app's RAM usage -- it just may be that its allocating too much > memory and the OOM killer is killing it (if you're running linux, that is). > You may also want to try the GHCi debugger [1] to find out where the program > crashes. The last thing I'd do is blame it on ghc/ghci, but as always -- such > a possibility exists. > It's Windows. And while it's possible (indeed even probable) that my code has an infinite loop in it somewhere, usually that makes the program slow to a crawl and start thrashing the HD as it hits virtual memory. But this program just dies. Instantly. And I already tried the GHCi debugger. When I run the program, GHCi just quits. I suppose if I can track down exactly *where* in the program it's dying, I could try single-stepping through it... If I was doing something tricky like FFI or unsafe coersions, I'd assume I'd got it wrong somewhere. But I'm just doing plain ordinary Haskell stuff - traversing trees, pattern matching, etc. I'm a bit perplexed that it can fail this way. From lennart at augustsson.net Sat Jun 20 16:40:10 2009 From: lennart at augustsson.net (Lennart Augustsson) Date: Sat Jun 20 16:23:16 2009 Subject: [Haskell-cafe] unique identity and name shadowing during type inference In-Reply-To: <7f9d599f0906201057i41907cefmb0cc84d7f30cdf8d@mail.gmail.com> References: <7f9d599f0906201057i41907cefmb0cc84d7f30cdf8d@mail.gmail.com> Message-ID: Use 1. You'll probably need a monad in the type checker soon or later anyway, e.g., for handling errors. On Sat, Jun 20, 2009 at 7:57 PM, Geoffrey Irving wrote: > Hello, > > I am designing a type inference algorithm for a language with > arbitrary function overloading. ?For various reasons (beyond the scope > of this email), it's impossible to know the full type of an overloaded > function, so each function is assigned a unique primitive type and the > inference algorithm gradually learns more information about the > primitive. ?For example, if we declare an identity function > > ? ?f x = x > > the algorithm will create a primitive type F, and record f :: F. ?If > we use the function a few times, > > ? ?f 1 > ? ?f "blah" > > the algorithm will infer > > ? ?F Int = Int > ? ?F String = String > > My question is: what's the best way to represent these unique > primitive types in Haskell? ?A new type primitive needs to be created > whenever we process a function declaration. ?Nested function > declarations produce a different primitive each time the parent is > invoked with different argument types. ?These separate primitives can > escape if local functions are returned, so the inference algorithm > must be able to keep them separate and learn more about them after > their parent function is forgotten. > > Here are a few ways I know of: > > 1. Thread a uniqueness generator monad through the whole algorithm. > I'd prefer to avoid this extra plumbing if possible. > 2. Label primitives with the full context of how they were created. > If function f declares a nested function g, and f is called with Int > and Char, the primitives for g would be labeled with "f Int" and "f > Char" to keep them separate. ?This is similar to lambda lifting. > 3. Scary hacks involving makeStableName and unsafePerformIO. ?Some > sort of context would have to be thrown around here to make sure GHC > doesn't merge the different makeStableName calls. > > Unfortunately, method (2) is complicated by the fact that variable > names are not unique even in the internal representation (I'm using > the trick from [1]), so I'm not sure what the minimal unique "context" > would be. > > Does anyone know other methods outside of (1), (2), or (3), or clean > ways of structuring (2) or (3)? > > Thanks! > Geoffrey > > [1]: http://www.haskell.org/~simonmar/bib/ghcinliner02_abstract.html > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From lennart at augustsson.net Sat Jun 20 16:42:30 2009 From: lennart at augustsson.net (Lennart Augustsson) Date: Sat Jun 20 16:25:36 2009 Subject: [Haskell-cafe] Obscure weirdness In-Reply-To: <4A3D486A.5040600@btinternet.com> References: <4A3D005B.1010307@btinternet.com> <200906202119.36738.marcin.kosiba@gmail.com> <4A3D486A.5040600@btinternet.com> Message-ID: Did you try running it in some debugger, like windbg or VS? 2009/6/20 Andrew Coppin : > Marcin Kosiba wrote: >> >> On Saturday 20 June 2009, Andrew Coppin wrote: >> >>> >>> OK, so here's an interesting problem... >>> >>> I've been coding away all day, but now my program is doing something >>> slightly weird. For a specific input, it summarily terminates. The >>> registered exception handler does not fire. There is no output to stdout >>> or stderr indicating what the problem is. It just *stops* half way >>> through the printout. >>> >>> Weirder: If I run it in GHCi, then GHCi itself terminates. (I didn't >>> think you could *do* that!) >>> >> >> Hi, >> ? ? ? ?With the information you've provided it's hard to even guess. At >> least take a look at your app's RAM usage -- it just may be that its >> allocating too much memory and the OOM killer is killing it (if you're >> running linux, that is). >> ? ? ? ?You may also want to try the GHCi debugger [1] to find out where >> the program crashes. The last thing I'd do is blame it on ghc/ghci, but as >> always -- such a possibility exists. >> > > It's Windows. And while it's possible (indeed even probable) that my code > has an infinite loop in it somewhere, usually that makes the program slow to > a crawl and start thrashing the HD as it hits virtual memory. But this > program just dies. Instantly. > > And I already tried the GHCi debugger. When I run the program, GHCi just > quits. I suppose if I can track down exactly *where* in the program it's > dying, I could try single-stepping through it... > > If I was doing something tricky like FFI or unsafe coersions, I'd assume I'd > got it wrong somewhere. But I'm just doing plain ordinary Haskell stuff - > traversing trees, pattern matching, etc. I'm a bit perplexed that it can > fail this way. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From allbery at ece.cmu.edu Sat Jun 20 17:35:12 2009 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Sat Jun 20 17:18:50 2009 Subject: [Haskell-cafe] Code walking off the right edge of the screen In-Reply-To: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> References: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> Message-ID: On Jun 20, 2009, at 14:05 , Deniz Dogan wrote: > if something > then putStrLn "howdy there!" > else if somethingElse > then putStrLn "howdy ho!" > else ... FWIW, when I see this I generally start looking for a higher order way to express it. The monoid instance for lists can be a good start. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 195 bytes Desc: This is a digitally signed message part Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090620/9fd8f6ca/PGP.bin From aslatter at gmail.com Sat Jun 20 18:20:16 2009 From: aslatter at gmail.com (Antoine Latter) Date: Sat Jun 20 18:03:22 2009 Subject: [Haskell-cafe] ANN: haskeline-class Message-ID: <694519c50906201520j2c6e88e1l273defafd7f1639@mail.gmail.com> I'd like to announce a small library newly on hackage: haskeline-class http://hackage.haskell.org/package/haskeline-class Haskeline is an easy to use library, with a reasonable interface. The one quirk that got in my way was that its 'InputT' monad transformer defined its own instance of MonadState which allowed the user of the library to peer into the guts of Haskeline. What I really wanted at the time was an instance of MonadState which lifted the class operations to an inner monad. So I wrote a small newtype wrapper and a support class to work around this. If anyone else has the same issue, the code is now on Hackage. I've heard that this won't even be needed in the next major release of Haskeline, but I'll likely keep this package up-to-date if anyone finds the MonadHaskeline class useful. Antoine From wren at freegeek.org Sat Jun 20 22:26:54 2009 From: wren at freegeek.org (wren ng thornton) Date: Sat Jun 20 22:10:08 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list In-Reply-To: <910ddf450906201116h73c3c07y3ababe974615c27c@mail.gmail.com> References: <1245363427.8395.21.camel@localhost> <910ddf450906201116h73c3c07y3ababe974615c27c@mail.gmail.com> Message-ID: <4A3D9A6E.4070608@freegeek.org> Thomas Hartman wrote: > could someone explain sharing? > > In the code below, allstrings2 is 6X as fast as allstrings. I assume > because of sharing, but I don't intuitively see a reason why. > > can someone give me some pointers, perhaps using debug.trace or other > tools (profiling?) to show where the first version is being > inefficient? > > > *********** > > letters = ['a'..'z'] > > strings 0 = [""] > strings n = [ c : s | c <- letters, s <- strings (n-1) x ] > > allstrings = concat $ map strings [1..] > > allstrings2 = let sss = [""] : [ [ c:s | c <- letters, s <- ss ] | ss <- sss ] > in concat $ tail sss It's a dynamic-programming problem. Let's reword this in terms of fibonnaci: fibs = map fib [0..] where fib 0 = 0 fib 1 = 1 fib n = fib (n-1) + fib (n-2) This is essentially what allstrings is doing. We have a basic function fib/strings and we use it to "count down" from our seed input to the value we want. But, because fib/strings is a pure function, it will always give equivalent output for the same input, and so once we hit some query we've answered before we'd like to just stop. But this version won't stop, it'll count all the way down to the bottom. Haskell doesn't automatically memoize functions, so it's a key point that the values are only "equivalent". With allstrings2 we do memoization and take it a step further to return the "identical" answer, since we keep a copy of the answers we've given out before. The fibs variation is: fibs = 0 : 1 : zipWith (+) fibs (tail fibs) Because we're defining fibs recursively in terms of itself, to get the next element of the stream we only need to keep track of the previous two answers we've given out. Similarly for allstrings2 because sss is defined in terms of itself it's always producing elements one step before it needs them. More particularly, because the recursion has "already been done" producing the next element is just a matter of applying (+) or applying [ c:s | c <- letters, s <- ss ] and we don't need to repeat the recursion. -- Live well, ~wren From haskell at brecknell.org Sat Jun 20 23:46:31 2009 From: haskell at brecknell.org (Matthew Brecknell) Date: Sat Jun 20 23:29:41 2009 Subject: [Haskell-cafe] Re: Need some help with an infinite list In-Reply-To: <910ddf450906201116h73c3c07y3ababe974615c27c@mail.gmail.com> References: <1245363427.8395.21.camel@localhost> <910ddf450906201116h73c3c07y3ababe974615c27c@mail.gmail.com> Message-ID: <1245555991.8403.65.camel@localhost> Thomas Hartman wrote: > could someone explain sharing? A good tool for visualising the difference between shared and non-shared results would be vacuum, using one of its front ends, vacuum-cairo or vacuum-ubigraph. http://hackage.haskell.org/package/vacuum http://hackage.haskell.org/package/vacuum-cairo http://hackage.haskell.org/package/vacuum-ubigraph To see sharing, you will need to view a set of outputs (not just one string). To keep the graph to a manageable size, use a smaller alphabet: digits = "01" -- All words of length n, with shared substrings shared :: Int -> [String] shared n = sss !! n where sss = [""] : [ [ c:s | c <- digits, s <- ss ] | ss <- sss ] -- All words of length n, with unshared substrings unshared :: Int -> [String] unshared 0 = [""] unshared n = [ c:s | c <- digits, s <- unshared (n-1) ] And then in GHCi: Vacuum.Cairo> shared 3 == unshared 3 True Vacuum.Cairo> view $ shared 3 Vacuum.Cairo> view $ unshared 3 I'd send some PNGs, except my vacuum installation is currently broken. Perhaps someone else can? Regards, Matthew From shinnonoir at gmail.com Sun Jun 21 02:37:25 2009 From: shinnonoir at gmail.com (Raynor Vliegendhart) Date: Sun Jun 21 02:20:30 2009 Subject: [Haskell-cafe] Obscure weirdness In-Reply-To: <6d961e560906202336mcf3afb3j93ac520a1f4870c3@mail.gmail.com> References: <4A3D005B.1010307@btinternet.com> <6d961e560906202336mcf3afb3j93ac520a1f4870c3@mail.gmail.com> Message-ID: <6d961e560906202337o3e2ba556ie27432135d11fa78@mail.gmail.com> On 6/20/09, Andrew Coppin wrote: > > Is this a known bug in GHC 6.10.1? Will upgrading fix it? (Obviously, it's > quite a lot of work to change GHC.) Suffice it to say that my program is > quite big and complicated; it worked fine when it was still small and > simple. ;-) There is a bug in ghci 6.10.1 that seems to be fixed in 6.10.3 (not sure whether it's fixed in 6.10.3). Certain non-terminating expressions causes ghci to crash immediately and go back to the prompt: ---------------------------------------- C:\>ghci GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> let loop = loop in loop C:\> ---------------------------------------- Compiling a module with a non-terminating expression first with ghc and then loading it in ghci does not seem to result in a crash. From dougal at dougalstanton.net Sun Jun 21 03:08:58 2009 From: dougal at dougalstanton.net (Dougal Stanton) Date: Sun Jun 21 02:52:02 2009 Subject: [Haskell-cafe] Edinburgh Haskell users meeting this afternoon Message-ID: <2d3641330906210008x470d74d1l6b6f2baf875933df@mail.gmail.com> Hello Haskell users If you're in the Edinburgh (Scotland!) area and interested in Haskell we may have just the thing for you. I will be meeting one other Haskell Cafe list member at Doctor's pub at 4pm this afternoon (Sunday 21 June). This could be the start of something bigger, so if you're interested in Haskell please drop in and swell the numbers. The conversation will probably be about some of the basics - what is currying? what are typeclasses? what does the "deriving" keyword do? - so don't feel nervous about being out of your depth! If I can get a table, I will try to display a copy of Hudak's _Haskell School of Expression_ prominently. Please come up and say hello, or fire me back a note if you can't make it but are still interested in making this a regular meeting. Don't be shy about joining us if you're available though! Thanks everyone! Dougal -- Dougal Stanton dougal@dougalstanton.net // http://www.dougalstanton.net From andrewcoppin at btinternet.com Sun Jun 21 04:36:16 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jun 21 04:19:18 2009 Subject: [Haskell-cafe] Obscure weirdness In-Reply-To: <6d961e560906202337o3e2ba556ie27432135d11fa78@mail.gmail.com> References: <4A3D005B.1010307@btinternet.com> <6d961e560906202336mcf3afb3j93ac520a1f4870c3@mail.gmail.com> <6d961e560906202337o3e2ba556ie27432135d11fa78@mail.gmail.com> Message-ID: <4A3DF100.2070706@btinternet.com> Raynor Vliegendhart wrote: > There is a bug in ghci 6.10.1 that seems to be fixed in 6.10.3 (not > sure whether it's fixed in 6.10.3). Certain non-terminating > expressions causes ghci to crash immediately and go back to the > prompt: > > ---------------------------------------- > C:\>ghci > GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help > Loading package ghc-prim ... linking ... done. > Loading package integer ... linking ... done. > Loading package base ... linking ... done. > Prelude> let loop = loop in loop > > C:\> > ---------------------------------------- > > Compiling a module with a non-terminating expression first with ghc > and then loading it in ghci does not seem to result in a crash. > That certainly sounds very much like the behaviour I'm seeing, except... it happens whether or not the code is compiled. If I run GHCi with nothing compiled, it crashes. If I compile all the modules and run GHCi, it crashes. If I make a stand-alone executable and run it, it crashes. Anyway, I shall try 6.10.3 and see what happens. PS. Is there a ticket for this? I mean, it seems to be fixed, but we should probably still record it somehow? From andrewcoppin at btinternet.com Sun Jun 21 05:09:55 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jun 21 04:52:57 2009 Subject: [Haskell-cafe] Obscure weirdness In-Reply-To: <4A3DF100.2070706@btinternet.com> References: <4A3D005B.1010307@btinternet.com> <6d961e560906202336mcf3afb3j93ac520a1f4870c3@mail.gmail.com> <6d961e560906202337o3e2ba556ie27432135d11fa78@mail.gmail.com> <4A3DF100.2070706@btinternet.com> Message-ID: <4A3DF8E3.1020307@btinternet.com> Andrew Coppin wrote: > Anyway, I shall try 6.10.3 and see what happens. Recompiled my program. It now throws a "loop" exception (which the exception handler catches) instead of just dying. (Curiosly, the exception handler itself then throws an exception saying ": hGetLine: illegal operation (handle is finalized)". It worked fine before... anybody know about this?) From andrewcoppin at btinternet.com Sun Jun 21 05:52:22 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jun 21 05:35:24 2009 Subject: [Haskell-cafe] Nested tests [Code walking off the right edge of the screen] In-Reply-To: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> References: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> Message-ID: <4A3E02D6.9040709@btinternet.com> Deniz Dogan wrote: > I (too) often find myself writing code such as this: > > if something > then putStrLn "howdy there!" > else if somethingElse > then putStrLn "howdy ho!" > else ... > > I recall reading some tutorial about how you can use the Maybe monad > if your code starts looking like this, but as you can see, that > doesn't really apply here. "something" and "somethingElse" are simply > booleans and each of them have different actions to take if either of > them is True. > > So how do I make code like this prettier? > In a similar vein: d1x <- doesDirectoryExist d1 if d1x then do f1x <- doesFileExist (d1 f1) if f1x then do d2x <- doesDirectoryExist d2 if d2x then do f2x <- doesFileExist (d2 f2) if f2x then do_stuff d1 d2 f1 f2 else hPutStrLn stderr $ "File " ++ f2 ++ " not found." else hPutStrLn stderr $ "Directory " ++ d2 ++ " not found." else hPutStrLn stderr $ "File " ++ f1 ++ " not found." else hPutStrLn stderr $ "Directory " ++ d1 ++ " not found." Obviously, this is nausiating. Surely we can do better somehow? The above is a simple example. I might need to check file permissions, invoke external programs, parse files, all sorts of things. And it might matter which order the tests happen in. Later tests might use information gained during earlier tests. But the recurring pattern is "check this thing; if it passes, continue; if it fails, stop here and emit an error message". Can we abstract this somehow? From bulat.ziganshin at gmail.com Sun Jun 21 06:04:31 2009 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sun Jun 21 05:47:44 2009 Subject: [Haskell-cafe] Nested tests [Code walking off the right edge of the screen] In-Reply-To: <4A3E02D6.9040709@btinternet.com> References: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> <4A3E02D6.9040709@btinternet.com> Message-ID: <1586117088.20090621140431@gmail.com> Hello Andrew, Sunday, June 21, 2009, 1:52:22 PM, you wrote: > d1x <- doesDirectoryExist d1 > if d1x > then do > f1x <- doesFileExist (d1 f1) > if f1x > then do > d2x <- doesDirectoryExist d2 > if d2x > then do > f2x <- doesFileExist (d2 f2) > if f2x > then do_stuff d1 d2 f1 f2 > else hPutStrLn stderr $ "File " ++ f2 ++ " not found." > else hPutStrLn stderr $ "Directory " ++ d2 ++ " not found." > else hPutStrLn stderr $ "File " ++ f1 ++ " not found." > else hPutStrLn stderr $ "Directory " ++ d1 ++ " not found." d1x <- doesDirectoryExist d1 if not d1x then hPutStrLn stderr $ "Directory " ++ d1 ++ " not found." else do f1x <- doesFileExist (d1 f1) if not f1x then hPutStrLn stderr $ "File " ++ f1 ++ " not found." else do d2x <- doesDirectoryExist d2 if not d2x then hPutStrLn stderr $ "Directory " ++ d2 ++ " not found." else do f2x <- doesFileExist (d2 f2) if not f2x then hPutStrLn stderr $ "File " ++ f2 ++ " not found." else do do_stuff d1 d2 f1 f2 or, with a little additional combinators: ifM (not ==<< doesDirectoryExist d1) (hPutStrLn stderr $ "Directory " ++ d1 ++ " not found.") $ do ifM (not ==<< doesFileExist (d1 f1)) (hPutStrLn stderr $ "File " ++ f1 ++ " not found.") $ do ifM (not ==<< doesDirectoryExist d2) (hPutStrLn stderr $ "Directory " ++ d2 ++ " not found.") $ do ifM (not ==<< doesFileExist (d2 f2)) (hPutStrLn stderr $ "File " ++ f2 ++ " not found.") $ do do_stuff d1 d2 f1 f2 -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From claus.reinke at talk21.com Sun Jun 21 07:03:15 2009 From: claus.reinke at talk21.com (Claus Reinke) Date: Sun Jun 21 06:46:38 2009 Subject: [Haskell-cafe] Code walking off the right edge of the screen References: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> Message-ID: >I (too) often find myself writing code such as this: > > if something > then putStrLn "howdy there!" > else if somethingElse > then putStrLn "howdy ho!" > else ... 1. recognize something odd. done. 2. look for improvements. good. 3. define suitable abstractions for your special case 4. look for general abstractions covering the special case > I recall reading some tutorial about how you can use the Maybe monad > if your code starts looking like this, but as you can see, that > doesn't really apply here. "something" and "somethingElse" are simply > booleans and each of them have different actions to take if either of > them is True. Maybe, or MaybeT (a monad transformer adding Maybe-style functionality to your base monad, in this case IO) can be used here as well, but may not be the first choice. As has been pointed out, guards would seem to cover your use case: e something somethingElse | something = putStrLn "howdy there!" | somethingElse = putStrLn "howdy ho!" | otherwise = putStrLn "hmm.. hi?" If you need something more, you can define your own abstractions to cover the repeated patterns in your code. Perhaps a function to select one of a list of (condition,action) pairs: g something somethingElse = oneOf [(something, putStrLn "howdy there!") ,(somethingElse, putStrLn "howdy ho!") ,(otherwise, putStrLn "hmm.. hi?") ] where oneOf = foldr (\(c,a) r->if c then a else r) (error "no match in oneOf") or some combinators for alternatives of guarded actions instead h something somethingElse = (something -:> putStrLn "howdy there!") `orElse` (somethingElse -:> putStrLn "howdy ho!") `orElse` (otherwise -:> putStrLn "hmm.. hi?") where c -:> a = when c a >> return c a `orElse` b = a >>= \ar-> if ar then return True else b Now, the former can be quite sufficient for many situations, but it doesn't quite feel like a general solution, and the latter clearly shows the dangers of defining your own abstractions: if you overdo it, anyone reading your code will need a translator!-) Which is where the search for general abstractions comes in - we're looking for something that will not only cover this special use case, but will be more generally useful, in a form that only needs to be understand once (not once per project). And that brings us to things like MonadPlus: you don't have to use the Monad combinator for sequencing, but if you do (as in IO), then it is natural to ask for a second combinator, for alternatives. Now, IO itself doesn't have a MonadPlus instance, but we can use a monad transformer to add such functionality. Using MaybeT, that will be similar to version 'h' above: i something somethingElse = runMaybeT $ (guard something >> lift (putStrLn "howdy there!")) `mplus` (guard somethingElse >> lift (putStrLn "howdy ho!")) `mplus` ( lift (putStrLn "hmm.. hi?")) and it can also be used for related patterns, such as running a sequence of actions until the first failure: j something somethingElse = runMaybeT $ do (guard something >> lift (putStrLn "howdy there!")) (guard somethingElse >> lift (putStrLn "howdy ho!")) ( lift (putStrLn "hmm.. hi?")) or other combinations of these two patterns. MaybeT is not the only possibility, and not always the best, but Maybe is perhaps the best known instance of MonadPlus (and the only thing that needs to change to use other MonadPlus instances is the 'runMaybeT'). Hth, Claus PS. for a more extensive example of MaybeT vs indentation creep, see http://www.haskell.org/haskellwiki/Equational_reasoning_examples#Coding_style:_indentation_creep_with_nested_Maybe --------------------------- data MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) } instance Monad m => Monad (MaybeT m) where return = MaybeT . return . Just a >>= b = MaybeT $ runMaybeT a >>= maybe (return Nothing) (runMaybeT . b) fail msg= mzero instance Monad m => MonadPlus (MaybeT m) where mzero = MaybeT $ return Nothing a `mplus` b = MaybeT $ runMaybeT a >>= maybe (runMaybeT b) (return . Just) instance MonadTrans MaybeT where lift m = MaybeT $ m >>= return . Just main = do putStrLn "e:" >> mapM_ (uncurry e) args putStrLn "f:" >> mapM_ (uncurry f) args putStrLn "g:" >> mapM_ (uncurry g) args putStrLn "h:" >> mapM_ (uncurry h) args putStrLn "i:" >> mapM_ (uncurry i) args putStrLn "j:" >> mapM_ (uncurry j) args where args = [(x,y)|x<-[True,False],y<-[True,False]] From sebf at informatik.uni-kiel.de Sun Jun 21 08:36:38 2009 From: sebf at informatik.uni-kiel.de (Sebastian Fischer) Date: Sun Jun 21 08:19:45 2009 Subject: [Haskell-cafe] Nested tests [Code walking off the right edge of the screen] In-Reply-To: <4A3E02D6.9040709@btinternet.com> References: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> <4A3E02D6.9040709@btinternet.com> Message-ID: <11DAD609-5513-4D90-9ADA-ADD25169488C@informatik.uni-kiel.de> On Jun 21, 2009, at 11:52 AM, Andrew Coppin wrote: > In a similar vein: > > d1x <- doesDirectoryExist d1 > if d1x > then do > f1x <- doesFileExist (d1 f1) > if f1x > then do > d2x <- doesDirectoryExist d2 > if d2x > then do > f2x <- doesFileExist (d2 f2) > if f2x > then do_stuff d1 d2 f1 f2 > else hPutStrLn stderr $ "File " ++ f2 ++ " not found." > else hPutStrLn stderr $ "Directory " ++ d2 ++ " not found." > else hPutStrLn stderr $ "File " ++ f1 ++ " not found." > else hPutStrLn stderr $ "Directory " ++ d1 ++ " not found." using Control.Monad.Error: either (hPutStrLn stderr) return =<< runErrorT $ do d1x <- lift $ doesDirectoryExist d1 unless d1x $ fail "Directory " ++ d1 ++ " not found." f1x <- lift $ doesFileExist (d1 f1) unless f1x $ fail "File " ++ f1 ++ " not found." d2x <- lift $ doesDirectoryExist d2 unless d2x $ fail "Directory " ++ d2 ++ " not found." f2x <- lift $ doesFileExist (d2 f2) unless f2x $ fail "File " ++ f2 ++ " not found." lift $ doStuff d1 d2 f1 f2 When using failUnless boolAction message = lift boolAction >>= (`unless`fail message) the code becomes either (hPutStrLn stderr) return =<< runErrorT $ do failUnless (doesDirectoryExist d1) $ "Directory " ++ d1 ++ " not found." failUnless (doesFileExist (d1 f1)) $ "File " ++ f1 ++ " not found." failUnless (doesDirectoryExist d2) $ "Directory " ++ d2 ++ " not found." failUnless (doesFileExist (d2 f2)) $ "File " ++ f2 ++ " not found." lift $ doStuff d1 d2 f1 f2 It's similar to Claus's proposal to use MaybeT with additional support for error messages. Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) From andrewcoppin at btinternet.com Sun Jun 21 08:47:26 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jun 21 08:30:26 2009 Subject: [Haskell-cafe] Nested tests [Code walking off the right edge of the screen] In-Reply-To: <11DAD609-5513-4D90-9ADA-ADD25169488C@informatik.uni-kiel.de> References: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> <4A3E02D6.9040709@btinternet.com> <11DAD609-5513-4D90-9ADA-ADD25169488C@informatik.uni-kiel.de> Message-ID: <4A3E2BDE.10607@btinternet.com> Sebastian Fischer wrote: > using Control.Monad.Error: > > either (hPutStrLn stderr) return =<< runErrorT $ > do d1x <- lift $ doesDirectoryExist d1 > unless d1x $ fail "Directory " ++ d1 ++ " not found." > f1x <- lift $ doesFileExist (d1 f1) > unless f1x $ fail "File " ++ f1 ++ " not found." > d2x <- lift $ doesDirectoryExist d2 > unless d2x $ fail "Directory " ++ d2 ++ " not found." > f2x <- lift $ doesFileExist (d2 f2) > unless f2x $ fail "File " ++ f2 ++ " not found." > lift $ doStuff d1 d2 f1 f2 So... essentially, run the ErrorT transformer on top of IO to do the error handling? That seems like a much nicer solution - if I can get it to work. (In general, any code involving monad transformers tends to fail with elaborate type checker failures. Typically it takes me hours to figure out why... Maybe somebody has written a tutorial on this stuff?) From sfvisser at cs.uu.nl Sun Jun 21 08:54:23 2009 From: sfvisser at cs.uu.nl (Sebastiaan Visser) Date: Sun Jun 21 08:37:31 2009 Subject: [Haskell-cafe] Nested tests [Code walking off the right edge of the screen] In-Reply-To: <11DAD609-5513-4D90-9ADA-ADD25169488C@informatik.uni-kiel.de> References: <7b501d5c0906201105r112b0f13rbd78e63634c10457@mail.gmail.com> <4A3E02D6.9040709@btinternet.com> <11DAD609-5513-4D90-9ADA-ADD25169488C@informatik.uni-kiel.de> Message-ID: On Jun 21, 2009, at 2:36 PM, Sebastian Fischer wrote: > On Jun 21, 2009, at 11:52 AM, Andrew Coppin wrote: > ... > > When using > > failUnless boolAction message = lift boolAction >>= (`unless`fail > message) > > the code becomes > > either (hPutStrLn stderr) return =<< runErrorT $ > do failUnless (doesDirectoryExist d1) $ "Directory " ++ d1 ++ " > not found." > failUnless (doesFileExist (d1 f1)) $ "File " ++ f1 ++ " not > found." > failUnless (doesDirectoryExist d2) $ "Directory " ++ d2 ++ " > not found." > failUnless (doesFileExist (d2 f2)) $ "File " ++ f2 ++ " not > found." > lift $ doStuff d1 d2 f1 f2 Or make is somewhat prettier (imho) using infix: orError boolAction message = lift boolAction >>= (`unless`fail message) either (hPutStrLn stderr) return =<< runErrorT $ do doesDirectoryExist d1 `orError` ("Directory " ++ d1 ++ " not found.") doesFileExist (d1 f1) `orError` ("File " ++ f1 ++ " not found.") doesDirectoryExist d2 `orError` ("Directory " ++ d2 ++ " not found.") doesFileExist (d2 f2) `orError` ("File " ++ f2 ++ " not found.") lift $ doStuff d1 d2 f1 f2 > It's similar to Claus's proposal to use MaybeT with additional > support for error messages. > > Sebastian > > > -- > Underestimating the novelty of the future is a time-honored tradition. > (D.G.) -- Sebastiaan Visser From andrewcoppin at btinternet.com Sun Jun 21 12:53:04 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jun 21 12:36:06 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus Message-ID: <4A3E6570.90504@btinternet.com> OK, so I'm guessing there might be one or two (!) people around here who know something about the Lambda calculus. I've written a simple interpretter that takes any valid Lambda expression and performs as many beta reductions as possible. When the input is first received, all the variables are renamed to be unique. Question: Does this guarantee that the reduction sequence will never contain name collisions? I have a sinking feeling that it does not. However, I can find no counter-example as yet. If somebody here can provide either a proof or a counter-example, that would be helpful. From deniz.a.m.dogan at gmail.com Sun Jun 21 13:05:16 2009 From: deniz.a.m.dogan at gmail.com (Deniz Dogan) Date: Sun Jun 21 12:48:20 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <4A3E6570.90504@btinternet.com> References: <4A3E6570.90504@btinternet.com> Message-ID: <7b501d5c0906211005j3ec12b77waf63edbe1bc6438f@mail.gmail.com> 2009/6/21 Andrew Coppin : > OK, so I'm guessing there might be one or two (!) people around here who > know something about the Lambda calculus. > > I've written a simple interpretter that takes any valid Lambda expression > and performs as many beta reductions as possible. When the input is first > received, all the variables are renamed to be unique. > > Question: Does this guarantee that the reduction sequence will never contain > name collisions? > > I have a sinking feeling that it does not. However, I can find no > counter-example as yet. If somebody here can provide either a proof or a > counter-example, that would be helpful. I'm no expert, but it sounds to me like you're doing the equivalent of "de Bruijn indexing", which is a method to avoid alpha conversion, which is basically what you're worried about. Therefore, I'm guessing that there will be no name collisions. -- Deniz Dogan From asviraspossible at gmail.com Sun Jun 21 13:05:53 2009 From: asviraspossible at gmail.com (Victor Nazarov) Date: Sun Jun 21 12:48:56 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <4A3E6570.90504@btinternet.com> References: <4A3E6570.90504@btinternet.com> Message-ID: On Sun, Jun 21, 2009 at 8:53 PM, Andrew Coppin wrote: > OK, so I'm guessing there might be one or two (!) people around here who > know something about the Lambda calculus. > > I've written a simple interpretter that takes any valid Lambda expression > and performs as many beta reductions as possible. When the input is first > received, all the variables are renamed to be unique. > > Question: Does this guarantee that the reduction sequence will never contain > name collisions? > > I have a sinking feeling that it does not. However, I can find no > counter-example as yet. If somebody here can provide either a proof or a > counter-example, that would be helpful. > It seems obvious scince beta reduction never introduces new variales... -- Victor Nazarov From keithshep at gmail.com Sun Jun 21 13:09:39 2009 From: keithshep at gmail.com (Keith Sheppard) Date: Sun Jun 21 12:52:41 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <92e42b740906211008k52f0f454j84e6712b070b9a74@mail.gmail.com> References: <4A3E6570.90504@btinternet.com> <92e42b740906211008k52f0f454j84e6712b070b9a74@mail.gmail.com> Message-ID: <92e42b740906211009p195df785s59562f089e0fd590@mail.gmail.com> forgot to cc the cafe :-) On Sun, Jun 21, 2009 at 1:08 PM, Keith Sheppard wrote: > hmm, it's been a while but... > > i think this "infinite loop" with a free variable would cause collision > > (\a . a a) (\b . b b d) > > On Sun, Jun 21, 2009 at 12:53 PM, Andrew > Coppin wrote: >> OK, so I'm guessing there might be one or two (!) people around here who >> know something about the Lambda calculus. >> >> I've written a simple interpretter that takes any valid Lambda expression >> and performs as many beta reductions as possible. When the input is first >> received, all the variables are renamed to be unique. >> >> Question: Does this guarantee that the reduction sequence will never contain >> name collisions? >> >> I have a sinking feeling that it does not. However, I can find no >> counter-example as yet. If somebody here can provide either a proof or a >> counter-example, that would be helpful. >> >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe >> > > > > -- > keithsheppard.name > -- keithsheppard.name From miguelimo38 at yandex.ru Sun Jun 21 13:12:18 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Sun Jun 21 12:55:41 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <4A3E6570.90504@btinternet.com> References: <4A3E6570.90504@btinternet.com> Message-ID: <83E87D95-E725-4BF9-AD91-F5D0B7C42EC4@yandex.ru> An answer would probably depend on the reductions order you've chosen. Would that do? (\e -> e (\u -> e (\v -> u))) (\f -> \x -> f x) -- all variables have different names, see? = (\f -> \x -> f x) (\u -> (\f -> \x -> f x) (\v -> u)) = \x -> (\u -> (\f -> \x -> f x) (\v -> u)) x = \x -> (\f -> \x -> f x) (\v -> x) = \x -> \x -> (\v -> x) x -- Ouch! = \x -> \x -> x = \x -> id where the real answer is \x -> (\f -> \x -> f x) (\v -> x) = \x -> (\f -> \y -> f y) (\v -> x) = \x -> \y -> (\v -> x) y = \x -> \y -> x = \x -> const x On 21 Jun 2009, at 20:53, Andrew Coppin wrote: > OK, so I'm guessing there might be one or two (!) people around here > who know something about the Lambda calculus. > > I've written a simple interpretter that takes any valid Lambda > expression and performs as many beta reductions as possible. When > the input is first received, all the variables are renamed to be > unique. > > Question: Does this guarantee that the reduction sequence will never > contain name collisions? > > I have a sinking feeling that it does not. However, I can find no > counter-example as yet. If somebody here can provide either a proof > or a counter-example, that would be helpful. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From duncan.coutts at worc.ox.ac.uk Sun Jun 21 13:14:22 2009 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Sun Jun 21 12:57:53 2009 Subject: [Haskell-cafe] packages on Hackage? In-Reply-To: <5ae4f2ba0906182126w6a094213o4594f7f3b16c505e@mail.gmail.com> References: <5ae4f2ba0906182126w6a094213o4594f7f3b16c505e@mail.gmail.com> Message-ID: <1245604462.28197.220.camel@localhost> On Thu, 2009-06-18 at 23:26 -0500, Vasili I. Galchin wrote: > Hello, > > Haskell packages on Hackage can be hosted anywhere, yes? Yes. > If a Haskell package is hosted on Hackage, how often is it > backed up? It's not especially wise to rely on Hackage for your backup needs since it obviously does not cover your revision control history or changes since the last release. Duncan From miguelimo38 at yandex.ru Sun Jun 21 13:15:00 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Sun Jun 21 12:58:18 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <83E87D95-E725-4BF9-AD91-F5D0B7C42EC4@yandex.ru> References: <4A3E6570.90504@btinternet.com> <83E87D95-E725-4BF9-AD91-F5D0B7C42EC4@yandex.ru> Message-ID: <86B6D8C4-D4E6-4EF4-A318-1378BF5C2543@yandex.ru> Correction: I think that one can find an expression that causes name clashes anyway, I'm just not certain that there is one that would clash independent of whichever order you choose. On 21 Jun 2009, at 21:12, Miguel Mitrofanov wrote: > An answer would probably depend on the reductions order you've > chosen. Would that do? > > (\e -> e (\u -> e (\v -> u))) (\f -> \x -> f x) -- all variables > have different names, see? > > = (\f -> \x -> f x) (\u -> (\f -> \x -> f x) (\v -> u)) > > = \x -> (\u -> (\f -> \x -> f x) (\v -> u)) x > > = \x -> (\f -> \x -> f x) (\v -> x) > > = \x -> \x -> (\v -> x) x -- Ouch! > > = \x -> \x -> x > > = \x -> id > > > where the real answer is > > > \x -> (\f -> \x -> f x) (\v -> x) > > = \x -> (\f -> \y -> f y) (\v -> x) > > = \x -> \y -> (\v -> x) y > > = \x -> \y -> x > > = \x -> const x > > > On 21 Jun 2009, at 20:53, Andrew Coppin wrote: > >> OK, so I'm guessing there might be one or two (!) people around >> here who know something about the Lambda calculus. >> >> I've written a simple interpretter that takes any valid Lambda >> expression and performs as many beta reductions as possible. When >> the input is first received, all the variables are renamed to be >> unique. >> >> Question: Does this guarantee that the reduction sequence will >> never contain name collisions? >> >> I have a sinking feeling that it does not. However, I can find no >> counter-example as yet. If somebody here can provide either a proof >> or a counter-example, that would be helpful. >> >> _______________________________________________ >> 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 keithshep at gmail.com Sun Jun 21 13:18:42 2009 From: keithshep at gmail.com (Keith Sheppard) Date: Sun Jun 21 13:01:47 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <92e42b740906211009p195df785s59562f089e0fd590@mail.gmail.com> References: <4A3E6570.90504@btinternet.com> <92e42b740906211008k52f0f454j84e6712b070b9a74@mail.gmail.com> <92e42b740906211009p195df785s59562f089e0fd590@mail.gmail.com> Message-ID: <92e42b740906211018x7b85592an8ea2ce77fdc959e2@mail.gmail.com> scratch that... it's completely wrong On Sun, Jun 21, 2009 at 1:09 PM, Keith Sheppard wrote: > forgot to cc the cafe :-) > > On Sun, Jun 21, 2009 at 1:08 PM, Keith Sheppard wrote: >> hmm, it's been a while but... >> >> i think this "infinite loop" with a free variable would cause collision >> >> (\a . a a) (\b . b b d) >> >> On Sun, Jun 21, 2009 at 12:53 PM, Andrew >> Coppin wrote: >>> OK, so I'm guessing there might be one or two (!) people around here who >>> know something about the Lambda calculus. >>> >>> I've written a simple interpretter that takes any valid Lambda expression >>> and performs as many beta reductions as possible. When the input is first >>> received, all the variables are renamed to be unique. >>> >>> Question: Does this guarantee that the reduction sequence will never contain >>> name collisions? >>> >>> I have a sinking feeling that it does not. However, I can find no >>> counter-example as yet. If somebody here can provide either a proof or a >>> counter-example, that would be helpful. >>> >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> Haskell-Cafe@haskell.org >>> http://www.haskell.org/mailman/listinfo/haskell-cafe >>> >> >> >> >> -- >> keithsheppard.name >> > > > > -- > keithsheppard.name > -- keithsheppard.name From la at iki.fi Sun Jun 21 13:26:17 2009 From: la at iki.fi (Lauri Alanko) Date: Sun Jun 21 13:09:21 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <4A3E6570.90504@btinternet.com> References: <4A3E6570.90504@btinternet.com> Message-ID: <20090621172617.GA10579@cs.helsinki.fi> On Sun, Jun 21, 2009 at 05:53:04PM +0100, Andrew Coppin wrote: > I've written a simple interpretter that takes any valid Lambda > expression and performs as many beta reductions as possible. When the > input is first received, all the variables are renamed to be unique. > > Question: Does this guarantee that the reduction sequence will never > contain name collisions? With "name collisions" I'm assuming you mean inadvertent variable capture. The answer depends on your evaluation strategy. If you never reduce inside a lambda (e.g. call-by-name or call-by-value), then you will always be substituting a closed term in place of a variable, and nothing in a closed term can get captured. However, if by "as many reductions as possible" you mean "to normal form", then you also need to reduce inside lambdas. Then the story is different. Consider the following sequence of beta reductions: (\x. x x) (\y. \z. y z) -> (\y. \z. y z) (\y. \z. y z) -> \z. (\y. \z. y z) z -> \z. \z'. z z' Notice that in the original form, all variable names were unique, but then the variable "z" got duplicated, and the last reduction happened _inside_ the "\z." expression, which required renaming of the inner "z" in order to avoid variable capture and the erroneous result of "\z. \z. z z". Hope this helps. Lauri From byorgey at seas.upenn.edu Sun Jun 21 13:29:17 2009 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Sun Jun 21 13:12:19 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <4A3E6570.90504@btinternet.com> References: <4A3E6570.90504@btinternet.com> Message-ID: <20090621172917.GA22836@seas.upenn.edu> On Sun, Jun 21, 2009 at 05:53:04PM +0100, Andrew Coppin wrote: > OK, so I'm guessing there might be one or two (!) people around here who > know something about the Lambda calculus. > > I've written a simple interpretter that takes any valid Lambda expression > and performs as many beta reductions as possible. When the input is first > received, all the variables are renamed to be unique. > > Question: Does this guarantee that the reduction sequence will never > contain name collisions? > > I have a sinking feeling that it does not. However, I can find no > counter-example as yet. If somebody here can provide either a proof or a > counter-example, that would be helpful. Lambda calculus is one of those things that seems simple in theory (because it IS simple in theory) but can be tricky to implement correctly. I recommend reading the first few chapters of Benjamin Pierce's "Types and Programming Languages" for a good discussion of the issues involved (including explanations and implementations of both a "named" style, and a "de Bruijn index" style), and then also "I am not a number, I am a free variable" by McBride and McKinna, which explains a "locally nameless" style which mixes the best of both worlds. -Brent From bertram.felgenhauer at googlemail.com Sun Jun 21 13:56:00 2009 From: bertram.felgenhauer at googlemail.com (Bertram Felgenhauer) Date: Sun Jun 21 13:39:06 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <86B6D8C4-D4E6-4EF4-A318-1378BF5C2543@yandex.ru> References: <4A3E6570.90504@btinternet.com> <83E87D95-E725-4BF9-AD91-F5D0B7C42EC4@yandex.ru> <86B6D8C4-D4E6-4EF4-A318-1378BF5C2543@yandex.ru> Message-ID: <4a3e7433.1c05d00a.0a7e.1949@mx.google.com> Miguel Mitrofanov wrote: > Correction: I think that one can find an expression that causes name > clashes anyway, I'm just not certain that there is one that would clash > independent of whichever order you choose. Yes there is. Consider (\f g -> f (f (f (f (f (f g)))))) (\l a b -> l (b a)) (\x -> x) which has 6 variables in total. This reduces to the normal form \a b c d e f g -> g (f (e (d (c (b a))))) which requires 7 variables. So without alpha-conversion at least one of the original 6 variables will clash with itself. Bertram From andrewcoppin at btinternet.com Sun Jun 21 13:57:26 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jun 21 13:40:25 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <20090621172617.GA10579@cs.helsinki.fi> References: <4A3E6570.90504@btinternet.com> <20090621172617.GA10579@cs.helsinki.fi> Message-ID: <4A3E7486.1060401@btinternet.com> Lauri Alanko wrote: > With "name collisions" I'm assuming you mean inadvertent variable > capture. The answer depends on your evaluation strategy. If you never > reduce inside a lambda (e.g. call-by-name or call-by-value), then you > will always be substituting a closed term in place of a variable, and > nothing in a closed term can get captured. > > However, if by "as many reductions as possible" you mean "to normal > form", then you also need to reduce inside lambdas. Then the story is > different. Consider the following sequence of beta reductions: > > (\x. x x) (\y. \z. y z) > -> (\y. \z. y z) (\y. \z. y z) > -> \z. (\y. \z. y z) z > -> \z. \z'. z z' > > Notice that in the original form, all variable names were unique, but > then the variable "z" got duplicated, and the last reduction happened > _inside_ the "\z." expression, which required renaming of the inner > "z" in order to avoid variable capture and the erroneous result of > "\z. \z. z z". > > Hope this helps. > Ladies and gentlemen, we have a counter-example! (\x1 -> x1 x1) (\y2 -> \z3 -> y2 z3) (\y2 -> \z3 -> y2 z3) (\y2 -> \z3 -> y2 z3) \z3 -> (\y2 -> \z3 -> y2 z3) z3 \z3 -> \z3 -> z3 z3 This *should* of course be \z3 -> \z4 -> z3 z4 which is a different function. Now the operative question becomes... how in the name of God to I fix this? (The obvious approach would be to rerun the renamer; but would discarding the variable indicies introduce even more ambiguity? Hmm...) From iliya.kuznetsov at gmail.com Sun Jun 21 14:05:12 2009 From: iliya.kuznetsov at gmail.com (Iliya Kuznetsov) Date: Sun Jun 21 13:48:35 2009 Subject: [Haskell-cafe] secure store for passwords on CLIENT side Message-ID: Hello, haskellers, I've faced with some issue: how to store passwords securely on client's side? Of course there are many technics how to hash them on server side but sure all of them can't be used in my case (because of nature of hash). There is some platform-independent application written on Haskell and it requires login name/password for asking some web services through SOAP. I can ask it every time when it's called, but probably I should prepare some way to store this secure info on somewhere. The other side (in most cases!) can use only plain authorization method. For me the best way for this task -- storing the puzzled password somewhere in user's home directory ($HOME or %APPDATA% or in Mac's place for that), but I don't know how to puzzle it securely. One idea is to use GPG-alike approach: make secret key automatically and store it in user's home and just encrypt the given passphrase with that secret key after logging on and decrypt with public key when needed. But this probably is overmuch for that task. -- Iliya Kuznetsov -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090621/3cd41a61/attachment.html From byorgey at seas.upenn.edu Sun Jun 21 14:10:18 2009 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Sun Jun 21 13:53:20 2009 Subject: [Haskell-cafe] Haskell Weekly News: Issue 122 - June 21, 2009 Message-ID: <20090621181018.GA26745@seas.upenn.edu> --------------------------------------------------------------------------- Haskell Weekly News http://sequence.complete.org/hwn/20090621 Issue 122 - June 21, 2009 --------------------------------------------------------------------------- Welcome to issue 122 of HWN, a newsletter covering developments in the [1]Haskell community. Are you ready for the [2]12th Annual ICFP programming contest? It begins this Friday, don't miss it! Let's reclaim Haskell's rightful place as the programming language of choice for discriminating hackers. Announcements Haskell protocol-buffers version 1.5.0. Chris Kuklewicz [3]announced version 1.5.0 of the [4]protocol-buffers, [5]protocol-buffers-descriptor, and [6]hprotoc packages to Hackage. This catches up to Google's version 2.1.0: support for "repeated" fields for primitive types; fields can now be marked deprecated; the type name resolver will no longer resolve type names to fields; and more. 12th Annual ICFP Contest. Mark Huntington Snyder [7]announced the 12th Annual [8]ICFP Programming Contest, hosted by the University of Kansas Computer Systems Design Laboratory at the Information and Telecommunication Technology Center. The contest will be held on the weekend of June 26-29. The contest task will be released sixteen seconds after 13:00 Central Daylight Time (US) on Friday, and entries will be accepted until 13:00:16 CDT on Monday. There is no preregistration required, and participation is free and open to all. Teams may participate from any location, and may use any programming language(s). Read the [9]contest blog or subscribe to the [10]RSS feed to receive timely updates before and during the contest. clock 0.1 released. Cetin Sert [11]announced the release of [12]clock, a package for convenient access to high-resolution clock and timer functions of different operating systems. It is planned to consist of two layers; the lower layer will provide direct access to OS-specific clock and timer functions like clock_gettime of Posix or GetTickCount of Windows, and its upper layer shall then provide a common API for all supported systems. Currently only the lower level is being developed. Turbinado V0.7. Alson Kemp [13]announced version 0.7 of [14]Turbinado, a Ruby-On-Rails-like web server and web framework for Haskell. It is designed to make creating web application using Haskell both easy and joyful. The primary additions in version 0.7 are FastCGI support and a new templating system (which includes HAML and HTML support). Additional details can be found [15]here. haskeline-class. Antoine Latter [16]announced [17]haskeline-class, a small library providing a newtyped MonadState instance for haskeline which lifts the class operations to an inner monad (as opposed to its existing instance). hyena. Johan Tibell [18]announced the first release of [19]hyena, a library for building web servers, based on the work on [20]iteratee style I/O by Oleg Kiselyov. The library allows you to create web servers that consume their input incrementally, without resorting to lazy I/O. This should lead to more predictable resource usage. Haskell-based iPhone development. Conal Elliott [21]announced a [22]collaboration wiki page for anyone working with Haskell to make iPhone apps. Fwd: Boston Haskell June 23rd meeting: openings for Lightning Talks. Ravi Nanavati [23]announced that there are several available slots for "lightning" (5 minute) talks at the June 23 meeting of the [24]Boston Area Haskell Users' Group. haskell-src-exts 1.0.0 rc1. Niklas Broberg [25]announced a series of release candidates for haskell-src-exts-1.0.0 (as of this writing, the most recent release candidate is version 0.5.6). This version is intended to fully support parsing of almost all Haskell extensions. Please help with testing! BostonHaskell: Next meeting - June 23rd at MIT CSAIL Reading Room (32-G882). Ravi Nanavati [26]announced the second meeting of the [27]Boston Area Haskell Users' Group, scheduled for Tuesday, June 23rd from 6:30pm - 8:30pm. It will be held in the MIT CSAIL Reading Room (32-G882, i.e. a room on the 8th floor of the Gates Tower of the MIT's Stata Center at 32 Vassar St in Cambridge, MA). Talks include "Automagic Font Conversion with Haskell Typeclasses" by Frank Berthold, and "Intermediate Language Representations via GADTs" by Nirav Dave. traversal transformations. Sjoerd Visscher [28]exhibited some code for Church-encoded container structures using their Foldable instance, and later [29]announced the [30]fmlist package based on the same code, along with a surprising example of a lazy 'middle-infinite' list (where elements can be taken from the beginning or the end!). hledger 0.6 released. Simon Michael [31]announced the release of [32]hledger 0.6. See the announcement for a list of the new features and other information. Discussion Adding swap to Data.Tuple. roconnor [33]proposed adding swap and swap' functions to Data.Tuple. Revamping the module hierarchy. Johan Tibell began an interesting [34]discussion about package names, module names, and the module hierarchy. Confusion on the third monad law when using lambda abstractions. Jon Strait [35]asked about the third monad law, leading to some clarification on what precisely the law says, and some interesting discussion on idiomatic use of the (<=<) (Kleisli composition) operator. Need some help with an infinite list. Gunther Schmidt [36]asked for some help generating a particular infinite list, and got a number of interesting suggestions. Blog noise [37]Haskell news from the [38]blogosphere. Blog posts from people new to the Haskell community are marked with >>>, be sure to welcome them! * Thomas ten Cate: [39]Cosmetics. Nice-looking icons for EclipseFP! * Niklas Broberg: [40]GSoC status report, week 4. More release candidates for haskell-src-exts 1.0.0. * >>> Uwe Hoffmann: [41]publishing nike runs, part 4: string templates. Real-world example of using HStringTemplate. * Andy Gill: [42]Call for Participation in the 12th Annual ICFP Programming Contest!. June 26-29! * Sebastian Fischer: [43]Reinventing Haskell Backtracking. * Remco Niemeijer: [44]Programming Praxis - Monte Carlo factorization. Remco implements Pollard's factorization algorithm in 9 lines of Haskell. * >>> Lee Duhem: [45]Understanding Functions Which Use 'instance Monad []' by Equational Reasoning. * Alex McLean: [46]Patterns in Haskell. A Haskell music generation EDSL. * David Amos: [47]Group generators for graph symmetries. * >>> adam: [48]Experience writing a ray tracer in Haskell. Adam's final project in a Haskell class taught by Mark Jones and Tim Sheard. * Petr Rockai: [49]soc progress 4. * Yaakov Nemoy: [50]Haskell Bindings to C from Start to Finish. Yaakov outlines his experience getting c2hs and the FFI to work. * Alex McLean: [51]Patterns in Haskell. Representing rhythmic patterns in Haskell. * >>> Abhishek Tiwari: [52]Haskell for Bioinformatics. * Roman Cheplyaka: [53]Shootout. A hilarious comic featuring sound advice on Haskell optimization. * Ketil Malde: [54]Dephd updates. * Neil Mitchell: [55]Draft paper on Derive, comments wanted. * Remco Niemeijer: [56]Programming Praxis - Who Owns The Zebra?. * Erik de Castro Lopo: [57]Two More for the Debian New Queue.. * David Amos: [58]Graph symmetries. * Alson Kemp: [59]Announce: Turbinado V0.7. * Gergely Patai: [60]You can draw your own graphs now!. * >>> Jens Petersen: [61]Haskell cabal-install rocks . Quotes of the Week * Botje: oh man. de bruijn again kicked me to groin the easy fix is to label your groin as (-1) :) * Pseudonym: Telling dons that something has been added to the shootout is the new telling Oleg that it can't be done in the type system. About the Haskell Weekly News New editions are posted to [62]the Haskell mailing list as well as to [63]the Haskell Sequence and [64]Planet Haskell. [65]RSS is also available, and headlines appear on [66]haskell.org. To help create new editions of this newsletter, please see the information on [67]how to contribute. Send stories to byorgey at cis dot upenn dot edu. The darcs repository is available at darcs get [68]http://code.haskell.org/~byorgey/code/hwn/ . References 1. http://haskell.org/ 2. http://icfpcontest.org/ 3. http://article.gmane.org/gmane.comp.lang.haskell.libraries/11331 4. http://hackage.haskell.org/package/protocol-buffers 5. http://hackage.haskell.org/package/protocol-buffers-descriptor 6. http://hackage.haskell.org/package/hprotoc 7. http://article.gmane.org/gmane.comp.lang.haskell.general/17298 8. http://icfpcontest.org/ 9. http://www.icfpcontest.org/wordpress 10. http://www.icfpcontest.org/wordpress/?feed=rss2 11. http://article.gmane.org/gmane.comp.lang.haskell.general/17279 12. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/clock 13. http://article.gmane.org/gmane.comp.lang.haskell.general/17277 14. http://wiki.github.com/turbinado/turbinado 15. http://www.alsonkemp.com/turbinado/announce-turbinado-v07/ 16. http://article.gmane.org/gmane.comp.lang.haskell.cafe/60246 17. http://hackage.haskell.org/package/haskeline-class 18. http://article.gmane.org/gmane.comp.lang.haskell.cafe/60117 19. http://hackage.haskell.org/package/hyena 20. http://hackage.haskell.org/package/iteratee 21. http://article.gmane.org/gmane.comp.lang.haskell.cafe/60104 22. http://haskell.org/haskellwiki/IPhone 23. http://article.gmane.org/gmane.comp.lang.haskell.cafe/60091 24. http://www.haskell.org/haskellwiki/Boston_Area_Haskell_Users%27_Group 25. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59993 26. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59991 27. http://www.haskell.org/haskellwiki/Boston_Area_Haskell_Users%27_Group 28. http://article.gmane.org/gmane.comp.lang.haskell.cafe/59894 29. http://article.gmane.org/gmane.comp.lang.haskell.cafe/60120 30. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/fmlist 31. http://www.haskell.org/pipermail/haskell-cafe/2009-June/062787.html 32. http://hledger.org/ 33. http://article.gmane.org/gmane.comp.lang.haskell.libraries/11326 34. http://thread.gmane.org/gmane.comp.lang.haskell.libraries/11325 35. http://thread.gmane.org/gmane.comp.lang.haskell.cafe/60105 36. http://thread.gmane.org/gmane.comp.lang.haskell.cafe/59999 37. http://planet.haskell.org/ 38. http://haskell.org/haskellwiki/Blog_articles 39. http://eclipsefp.wordpress.com/2009/06/20/cosmetics/ 40. http://nibrofun.blogspot.com/2009/06/gsoc-status-report-week-4.html 41. http://www.codemanic.com/uwe/2009/06/publishing-nike-runs-part-4-string-templates.html 42. http://blog.unsafeperformio.com/?p=53 43. http://www-ps.informatik.uni-kiel.de/~sebf/pub/atps09.html 44. http://bonsaicode.wordpress.com/2009/06/19/programming-praxis-monte-carlo-factorization/ 45. http://leeduhem.wordpress.com/2009/06/19/understanding-functions-which-use-list-monad-by-equational-reasoning/ 46. http://yaxu.org/patterns-in-haskell/ 47. http://haskellformaths.blogspot.com/2009/06/group-generators-for-graph-symmetries.html 48. http://blog.finiteimprobability.com/2009/06/18/experience-writing-a-ray-tracer-in-haskell/ 49. http://web.mornfall.net/blog/soc_progress_4.html 50. http://loupgaroublond.blogspot.com/2009/06/haskell-bindings-to-c-from-start-to.html 51. http://yaxu.org/patterns-in-haskell/ 52. http://www.abhishek-tiwari.com/2009/06/haskell-for-bioinformatics.html 53. http://ro-che.blogspot.com/2009/06/shootout.html 54. http://blog.malde.org/index.php/2009/06/16/dephd-updates/ 55. http://neilmitchell.blogspot.com/2009/06/draft-paper-on-derive-comments-wanted.html 56. http://bonsaicode.wordpress.com/2009/06/16/programming-praxis-who-owns-the-zebra/ 57. http://www.mega-nerd.com/erikd/Blog/CodeHacking/Debian/safe_uniplate.html 58. http://haskellformaths.blogspot.com/2009/06/graph-symmetries.html 59. http://www.alsonkemp.com/turbinado/announce-turbinado-v07/ 60. http://just-bottom.blogspot.com/2009/06/you-can-draw-your-own-graphs-now.html 61. http://juhp.blogspot.com/2009/06/haskell-cabal-install-rocks.html 62. http://www.haskell.org/mailman/listinfo/haskell 63. http://sequence.complete.org/ 64. http://planet.haskell.org/ 65. http://sequence.complete.org/node/feed 66. http://haskell.org/ 67. http://haskell.org/haskellwiki/HWN 68. http://code.haskell.org/~byorgey/code/hwn/ From miguelimo38 at yandex.ru Sun Jun 21 14:14:37 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Sun Jun 21 13:58:01 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <4a3e7433.1c05d00a.0a7e.1949@mx.google.com> References: <4A3E6570.90504@btinternet.com> <83E87D95-E725-4BF9-AD91-F5D0B7C42EC4@yandex.ru> <86B6D8C4-D4E6-4EF4-A318-1378BF5C2543@yandex.ru> <4a3e7433.1c05d00a.0a7e.1949@mx.google.com> Message-ID: Wow. Now you've showed it to me, it seems pretty obvious. That's what I like about math. On 21 Jun 2009, at 21:56, Bertram Felgenhauer wrote: > Miguel Mitrofanov wrote: >> Correction: I think that one can find an expression that causes name >> clashes anyway, I'm just not certain that there is one that would >> clash >> independent of whichever order you choose. > > Yes there is. > > Consider > > (\f g -> f (f (f (f (f (f g)))))) (\l a b -> l (b a)) (\x -> x) > > which has 6 variables in total. This reduces to the normal form > > \a b c d e f g -> g (f (e (d (c (b a))))) > > which requires 7 variables. So without alpha-conversion at least one > of > the original 6 variables will clash with itself. > > Bertram > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From miguelimo38 at yandex.ru Sun Jun 21 14:17:14 2009 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Sun Jun 21 14:00:38 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <4A3E7486.1060401@btinternet.com> References: <4A3E6570.90504@btinternet.com> <20090621172617.GA10579@cs.helsinki.fi> <4A3E7486.1060401@btinternet.com> Message-ID: Probably the easiest way to fix this was already proposed by Deniz Dogan: de Bruijn indices. On 21 Jun 2009, at 21:57, Andrew Coppin wrote: > Lauri Alanko wrote: >> With "name collisions" I'm assuming you mean inadvertent variable >> capture. The answer depends on your evaluation strategy. If you never >> reduce inside a lambda (e.g. call-by-name or call-by-value), then you >> will always be substituting a closed term in place of a variable, and >> nothing in a closed term can get captured. >> >> However, if by "as many reductions as possible" you mean "to normal >> form", then you also need to reduce inside lambdas. Then the story is >> different. Consider the following sequence of beta reductions: >> >> (\x. x x) (\y. \z. y z) >> -> (\y. \z. y z) (\y. \z. y z) >> -> \z. (\y. \z. y z) z >> -> \z. \z'. z z' >> >> Notice that in the original form, all variable names were unique, but >> then the variable "z" got duplicated, and the last reduction happened >> _inside_ the "\z." expression, which required renaming of the inner >> "z" in order to avoid variable capture and the erroneous result of >> "\z. \z. z z". >> >> Hope this helps. >> > > Ladies and gentlemen, we have a counter-example! > > (\x1 -> x1 x1) (\y2 -> \z3 -> y2 z3) > (\y2 -> \z3 -> y2 z3) (\y2 -> \z3 -> y2 z3) > \z3 -> (\y2 -> \z3 -> y2 z3) z3 > \z3 -> \z3 -> z3 z3 > > This *should* of course be > > \z3 -> \z4 -> z3 z4 > > which is a different function. > > Now the operative question becomes... how in the name of God to I > fix this? > > (The obvious approach would be to rerun the renamer; but would > discarding the variable indicies introduce even more ambiguity? > Hmm...) > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From andrewcoppin at btinternet.com Sun Jun 21 14:24:52 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jun 21 14:07:52 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <4A3E7486.1060401@btinternet.com> References: <4A3E6570.90504@btinternet.com> <20090621172617.GA10579@cs.helsinki.fi> <4A3E7486.1060401@btinternet.com> Message-ID: <4A3E7AF4.7060009@btinternet.com> Andrew Coppin wrote: > Ladies and gentlemen, we have a counter-example! > > (\x1 -> x1 x1) (\y2 -> \z3 -> y2 z3) > (\y2 -> \z3 -> y2 z3) (\y2 -> \z3 -> y2 z3) > \z3 -> (\y2 -> \z3 -> y2 z3) z3 > \z3 -> \z3 -> z3 z3 > > Now the operative question becomes... how in the name of God to I fix > this? > > (The obvious approach would be to rerun the renamer; but would > discarding the variable indicies introduce even more ambiguity? Hmm...) I knew alpha conversions were trixy little things! ;-) Well anyway, the obvious thing to do is after each reduction, strip off all the variable indicies and rerun the labeller to assign new indicies. But does this solution work properly in general? The labeller is carefully crafted to respect scoping, so that for example "\x -> x (\x -> x) x" becomes "\x1 -> x1 (\x2 -> x2) x1". But still, the final expression above is nicely labelled, yet wrong. How does this happen? Well, variable indicies are supposed to be unique. But in line 2 we see a bunch of them get duplicated. At this point, if you strip all the indicies and recompute them, you get (\y1 -> \z2 -> y1 z2) (\y3 -> \z4 -> y3 z4) There are now no spurious duplicates, and the reduction should proceed through the remaining steps without incident. So rerunning the labeller works *for this example*. But does it work in general? As an alternative, I could completely reprogram my entire application to use de Bruijn indices. Hmm... From andrewcoppin at btinternet.com Sun Jun 21 14:48:30 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jun 21 14:31:29 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <4A3E7AF4.7060009@btinternet.com> References: <4A3E6570.90504@btinternet.com> <20090621172617.GA10579@cs.helsinki.fi> <4A3E7486.1060401@btinternet.com> <4A3E7AF4.7060009@btinternet.com> Message-ID: <4A3E807E.9050609@btinternet.com> Andrew Coppin wrote: > Well anyway, the obvious thing to do is after each reduction, strip > off all the variable indicies and rerun the labeller to assign new > indicies. But does this solution work properly in general? No. Supposing some Lambda expression eventually reduces to, say, \x1 -> \x2 -> x1 x2 Now strip off all the indicies: \x -> \x -> x x ...and recompute them... \x1 -> \x2 -> x2 x2 FAIL. To make it worth properly, I would have to (at least) make the renamer respect any indicies which are already present. It's nontrivial, but doable. Of course, the ?1,643,264 question is... would it work even then? From andrewcoppin at btinternet.com Sun Jun 21 15:24:24 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jun 21 15:07:24 2009 Subject: [Haskell-cafe] Type system trickery Message-ID: <4A3E88E8.1060208@btinternet.com> I have a datatype with about a dozen constructors. I'd like to find a way to use the type system to prevent one of the constructors from being used in certain places. But I can't think of a way to do that. data Foobar = Foo Foobar | Bar Foobar | Zoo Foobar I want the type system to track whether or not Zoo has been used in a specific value. Sure, you can check for it at runtime, but I'd be happier if the type system can guarantee its absence when required. I tried this: data Zoo x = Zoo x | NoZoo x data GeneralFoobar f = Foo f | Bar f type Foobar = GeneralFoobar Foobar type FoobarZ = GeneralFoobar (Zoo FoobarZ) but the type checker seems to not like it. (Plus I now have to wade through miles of NoZoo wrappers everywhere.) The other alternative is to just duplicate the entire data declaration, sans the Zoo constructor... but I'd obviously prefer not to have to do that. (E.g., if I ever need to alter the declaration, I now have two copies to keep in sync.) Suggestions? From jeremy at n-heptane.com Sun Jun 21 15:53:35 2009 From: jeremy at n-heptane.com (Jeremy Shaw) Date: Sun Jun 21 15:36:38 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <4A3E6570.90504@btinternet.com> References: <4A3E6570.90504@btinternet.com> Message-ID: <87fxdte534.wl%jeremy@n-heptane.com> Hello, Have you read the lambda calculus chapter in: The Implementation of Functional Programming Languages by Simon Peyton Jones, published by Prentice Hall, 1987: http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/ - jeremy From niklas.broberg at gmail.com Sun Jun 21 15:55:23 2009 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Sun Jun 21 15:38:26 2009 Subject: [Haskell-cafe] Type system trickery In-Reply-To: <4A3E88E8.1060208@btinternet.com> References: <4A3E88E8.1060208@btinternet.com> Message-ID: On Sun, Jun 21, 2009 at 9:24 PM, Andrew Coppin wrote: > I have a datatype with about a dozen constructors. I'd like to find a way to > use the type system to prevent one of the constructors from being used in > certain places. But I can't think of a way to do that. > > ?data Foobar = > ? Foo Foobar | > ? Bar Foobar | > ? Zoo Foobar > > I want the type system to track whether or not Zoo has been used in a > specific value. Sure, you can check for it at runtime, but I'd be happier if > the type system can guarantee its absence when required. That's what GADTs are for: data Flag = HasZoo | NoZoo data Foobar a where Foo :: Foobar a -> Foobar a Bar :: Foobar a -> Foobar a Zoo :: Foobar a -> Foobar HasZoo f :: Foobar NoZoo -> Int f foobar = ... -- foobar cannot be Zoo here Cheers, /Niklas From daniel.is.fischer at web.de Sun Jun 21 15:57:48 2009 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sun Jun 21 15:41:41 2009 Subject: [Haskell-cafe] Type system trickery In-Reply-To: <4A3E88E8.1060208@btinternet.com> References: <4A3E88E8.1060208@btinternet.com> Message-ID: <200906212157.48393.daniel.is.fischer@web.de> Am Sonntag 21 Juni 2009 21:24:24 schrieb Andrew Coppin: > I have a datatype with about a dozen constructors. I'd like to find a > way to use the type system to prevent one of the constructors from being > used in certain places. But I can't think of a way to do that. > > data Foobar = > Foo Foobar | > Bar Foobar | > Zoo Foobar > > I want the type system to track whether or not Zoo has been used in a > specific value. Sure, you can check for it at runtime, but I'd be > happier if the type system can guarantee its absence when required. > > I tried this: > > data Zoo x = > Zoo x | > NoZoo x > > data GeneralFoobar f = > Foo f | > Bar f > > type Foobar = GeneralFoobar Foobar > type FoobarZ = GeneralFoobar (Zoo FoobarZ) > > but the type checker seems to not like it. (Plus I now have to wade > through miles of NoZoo wrappers everywhere.) > > The other alternative is to just duplicate the entire data declaration, > sans the Zoo constructor... but I'd obviously prefer not to have to do > that. (E.g., if I ever need to alter the declaration, I now have two > copies to keep in sync.) > > Suggestions? GADTs? data Okay data HasZoo data Aye data Nay class IsOkay a b | a -> b where instance IsOkay Okay Aye where instance IsOkay HasZoo Nay where data Foobar where Bling :: Foobar a Foo :: Foobar a -> Foobar a Bar :: Foobar a -> Foobar a Zoo :: Foobar a -> Foobar HasZoo use :: (IsOkay a Aye) => Foobar a -> whatever From andrewcoppin at btinternet.com Sun Jun 21 16:00:20 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jun 21 15:43:19 2009 Subject: [Haskell-cafe] Type system trickery In-Reply-To: References: <4A3E88E8.1060208@btinternet.com> Message-ID: <4A3E9154.7030109@btinternet.com> Niklas Broberg wrote: > On Sun, Jun 21, 2009 at 9:24 PM, Andrew > Coppin wrote: > >> data Foobar = >> Foo Foobar | >> Bar Foobar | >> Zoo Foobar >> >> I want the type system to track whether or not Zoo has been used in a >> specific value. Sure, you can check for it at runtime, but I'd be happier if >> the type system can guarantee its absence when required. >> > > That's what GADTs are for: > > data Flag = HasZoo | NoZoo > > data Foobar a where > Foo :: Foobar a -> Foobar a > Bar :: Foobar a -> Foobar a > Zoo :: Foobar a -> Foobar HasZoo > ...so I use "Foobar x" to mean any kind of value, "Foobar NoZoo" for a value that definitely doesn't contain Zoo, and "Foobar HasZoo" for... one that definitely does? Or maybe does? (Not that I care about this, but for completeness I'd like to know.) A slight complication is that Foobar refers to a second type which exhibits a similar behaviour - but presumably I can utilise the same solution there also... From kamil at dworakowski.name Sun Jun 21 16:01:40 2009 From: kamil at dworakowski.name (Kamil Dworakowski) Date: Sun Jun 21 15:44:46 2009 Subject: [Haskell-cafe] Optimizing spelling correction program Message-ID: Hi all, I want to learn how to optimize Haskell code on the Norvig's spelling correction program [1]. Peter Norvig has written the program in Python, quite a literate translation to Haskell (thanks to Grzegorz Chrupala) [2] was also available. Both versions are about 23 LOCs, and Haskell version is four times slower, 2m25s versus 36s. All the numbers I give come from running the program on a list of 806 misspellings, Haskell version compiled with - O2 and -fforce-recomp flags. I started with trial and error approach. Just preventing a repetitive call to keysSet brought the running time down to 1m48s. I also restructured the edits1 function and dropped all uses of sets, which haven't been pulling their own weight. This brought the running time down to 55s. Not quite there yet but close. Reading the Profiling chapter in the RWH book enabled me to do some more informed optimizing. At this point the GC time was about 2% of the overall runnig time, Grzegorz has done a good job of using strict versions of functions where necessary. The timing per expression however showed something useful, 70% of the time was being spent around determining membership in the known words dictionary (Data.Map). There are about 30 000 items in the dictionary. Right... Python uses hashtables while here I have a tree with log n access time. I did not want to use the Data.HashTable, it would pervade my program with IO. The alternative is an ideal hashmap that never gets changed. This program creates a dictionary at start which then is only being used to read from: an ideal application for the Data.PerfectHash by Mark Wotton available on Hackage [3]. The PerfectHash is a dictionary keyed by ByteStrings, so I had to migrate the program to use these instead of Strings. Sadly it increased the running time to 59s. Adding PerfectHash brought the running time down to 39s. I have done some code restructuring with the view to publishing it, which brought the running time up to 45s. The code is available on patch-tag [4] for anyone to scrutinize and hopefully point out mistakes (it uses big.txt and misspellings file which are linked to from Norvig's page [1]). At this point [5] I don't know how to proceed. The program is still slower than Python. The -ddump-simpl dump does not give me any clues, there is too much of it and I don't understand most of it. The GC time is about 10% of the total, and according to the profiler almost half the time is spent in the member function, and almost all the rest in edits1. Shouldn't it run much faster than the interpreted Python? Frankly, I am not impressed with the PerfectHash performance; It looks as if it is only two times faster than Data.Map. Is this because of the number of elements? 1. http://www.norvig.com/spell-correct.html 2. http://pitekus.blogspot.com/2007/04/norvigs-spelling-corrector-in-haskell.html 3. http://hackage.haskell.org/package/PerfectHash 4. http://patch-tag.com/r/spellcorrect/ 5. http://patch-tag.com/r/spellcorrect/snapshot/hash/20090621192727-a99e5-fed48a7ccf07b79c572fddb0304648fe80d39904/content/pretty/SpellingCorrection.hs From andrewcoppin at btinternet.com Sun Jun 21 16:16:12 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jun 21 15:59:11 2009 Subject: [Haskell-cafe] Type system trickery In-Reply-To: References: <4A3E88E8.1060208@btinternet.com> Message-ID: <4A3E950C.7090004@btinternet.com> Niklas Broberg wrote: > That's what GADTs are for: > > data Flag = HasZoo | NoZoo > > data Foobar a where > Foo :: Foobar a -> Foobar a > Bar :: Foobar a -> Foobar a > Zoo :: Foobar a -> Foobar HasZoo > Ouch #1: This appears to instantly disable deriving the Eq, Ord and Show instances I want. :-/ From niklas.broberg at gmail.com Sun Jun 21 16:16:58 2009 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Sun Jun 21 16:00:01 2009 Subject: [Haskell-cafe] Type system trickery In-Reply-To: <4A3E9154.7030109@btinternet.com> References: <4A3E88E8.1060208@btinternet.com> <4A3E9154.7030109@btinternet.com> Message-ID: >> That's what GADTs are for: >> >> data Flag = HasZoo | NoZoo Eh, I wrote this a bit fast obviously (no dependent types here). Like Daniel Fischer wrote, these should rather be separate data types, i.e. data HasZoo data NoZoo The rest is still correct though. >> data Foobar a where >> ?Foo :: Foobar a -> Foobar a >> ?Bar :: Foobar a -> Foobar a >> ?Zoo :: Foobar a -> Foobar HasZoo > > ...so I use "Foobar x" to mean any kind of value, "Foobar NoZoo" for a value > that definitely doesn't contain Zoo, and "Foobar HasZoo" for... one that > definitely does? Or maybe does? (Not that I care about this, but for > completeness I'd like to know.) Yep, you are correct. Actually, you don't have to use NoZoo, you could use e.g. Foobar () or Foobar (Maybe Bool) if you like. Anything that isn't HasZoo. Cheers, /Niklas From dons at galois.com Sun Jun 21 16:18:01 2009 From: dons at galois.com (Don Stewart) Date: Sun Jun 21 16:02:57 2009 Subject: [Haskell-cafe] Optimizing spelling correction program In-Reply-To: References: Message-ID: <20090621201801.GA2871@whirlpool.galois.com> kamil: > Hi all, > > I want to learn how to optimize Haskell code on the Norvig's spelling > correction program [1]. Peter Norvig has written the program in > Python, > quite a literate translation to Haskell (thanks to Grzegorz Chrupala) > [2] was also available. > > Both versions are about 23 LOCs, and Haskell version is four times > slower, 2m25s versus 36s. All the numbers I give come from running the > program on a list of 806 misspellings, Haskell version compiled with - > O2 > and -fforce-recomp flags. > > I started with trial and error approach. Just preventing a repetitive > call to keysSet brought the running time down to 1m48s. I also > restructured the edits1 function and dropped all uses of sets, which > haven't been pulling their own weight. This brought the running time > down to 55s. Not quite there yet but close. > > Reading the Profiling chapter in the RWH book enabled me to do some > more > informed optimizing. At this point the GC time was about 2% of the > overall runnig time, Grzegorz has done a good job of using strict > versions of functions where necessary. The timing per expression > however > showed something useful, 70% of the time was being spent around > determining membership in the known words dictionary (Data.Map). There > are about 30 000 items in the dictionary. What are the keys in your Map? Strict ByteStrings? And you're using ghc 6.10.x? -- Don From dave at zednenem.com Sun Jun 21 16:37:28 2009 From: dave at zednenem.com (David Menendez) Date: Sun Jun 21 16:20:30 2009 Subject: [Haskell-cafe] Type system trickery In-Reply-To: <4A3E9154.7030109@btinternet.com> References: <4A3E88E8.1060208@btinternet.com> <4A3E9154.7030109@btinternet.com> Message-ID: <49a77b7a0906211337l561ec852ned73c81d04b1dcae@mail.gmail.com> On Sun, Jun 21, 2009 at 4:00 PM, Andrew Coppin wrote: > Niklas Broberg wrote: >> >> On Sun, Jun 21, 2009 at 9:24 PM, Andrew >> Coppin wrote: >> >>> I want the type system to track whether or not Zoo has been used in a >>> specific value. Sure, you can check for it at runtime, but I'd be happier >>> if >>> the type system can guarantee its absence when required. >>> >> >> That's what GADTs are for: ... > ...so I use "Foobar x" to mean any kind of value, "Foobar NoZoo" for a value > that definitely doesn't contain Zoo, and "Foobar HasZoo" for... one that > definitely does? Or maybe does? (Not that I care about this, but for > completeness I'd like to know.) If you don't need code that's polymorphic between Foobar HasZoo and Foobar NoZoo, you could just newtype Foobar and only export smart constructors. module NoZoo (NoZoo, noZoo, mkNZ, mkNZ', unNZ) where newtype NoZoo = NZ Foobar noZoo :: Foobar -> Bool noZoo = ... mkNZ :: Foobar -> NoZoo mkNZ = NZ . assert "Zoo" . noZoo mkNZ' :: Foobar -> Maybe NoZoo mkNZ' x | noZoo x = Just x | otherwise = Nothing unNZ :: NoZoo -> Foobar unNZ (NZ x) = x Assuming noZoo is written correctly, this is enough to guarantee that unNZ never produces a value of Foobar containing Zoo. Oleg Kiselyov and Chung-chieh Shan have written about this. Try or search for "lightweight static capabilities". -- Dave Menendez From andrewcoppin at btinternet.com Sun Jun 21 17:04:39 2009 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun Jun 21 16:47:39 2009 Subject: [Haskell-cafe] Type system trickery In-Reply-To: <49a77b7a0906211337l561ec852ned73c81d04b1dcae@mail.gmail.com> References: <4A3E88E8.1060208@btinternet.com> <4A3E9154.7030109@btinternet.com> <49a77b7a0906211337l561ec852ned73c81d04b1dcae@mail.gmail.com> Message-ID: <4A3EA067.7000008@btinternet.com> David Menendez wrote: > If you don't need code that's polymorphic between Foobar HasZoo and > Foobar NoZoo, you could just newtype Foobar and only export smart > constructors. > Unfortunately I want to be able to print both of them out. (After all, the printing algorithm is identical whether Zoo is present or not - except that if Zoo isn't there, you don't need to handle Zoo!) Nice idea though. From magnus at therning.org Sun Jun 21 17:04:36 2009 From: magnus at therning.org (Magnus Therning) Date: Sun Jun 21 16:47:46 2009 Subject: [Haskell-cafe] secure store for passwords on CLIENT side In-Reply-To: References: Message-ID: <4A3EA064.8030407@therning.org> Iliya Kuznetsov wrote: > Hello, haskellers, > > I've faced with some issue: how to store passwords securely on client's > side? Of course there are many technics how to hash them on server side > but sure all of them can't be used in my case (because of nature of hash). > There is some platform-independent application written on Haskell and it > requires login name/password for asking some web services through SOAP. > I can ask it every time when it's called, but probably I should prepare > some way to store this secure info on somewhere. The other side (in most > cases!) can use only plain authorization method. > > For me the best way for this task -- storing the puzzled password > somewhere in user's home directory ($HOME or %APPDATA% or in Mac's place > for that), but I don't know how to puzzle it securely. > One idea is to use GPG-alike approach: make secret key automatically and > store it in user's home and just encrypt the given passphrase with that > secret key after logging on and decrypt with public key when needed. But > this probably is overmuch for that task. I'm not really sure I understand what you want to do, but it basically comes down to two things: 1. if you have something that needs to be kept secret from the user of the client, and you are thinking of keeping that secret _on_ the client, then _STOP_, there's simply no good way of doing that 2. if you want to store a secret that is already known to the user of the client, then you are best off storing it using a built-in systems for that, on Windows you have DPAPI (that might be old info, you should look at MSDN to find what you use nowadays), on Mac there's a secret store (I've forgotten what it's called now), in Gnome you have the keyring, in KDE you have kwallet For the latter you are likely to have to write your own FFI layer for using any of that from Haskell. I'm sure a nice Haskell x-platform abstraction would be greatly appreciated by the community ;-) Hope it helps. /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus?therning?org Jabber: magnus?therning?org http://therning.org/magnus identi.ca|twitter: magthe -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 197 bytes Desc: OpenPGP digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090621/e98117b2/signature.bin From kamil at dworakowski.name Sun Jun 21 17:44:07 2009 From: kamil at dworakowski.name (Kamil Dworakowski) Date: Sun Jun 21 17:27:08 2009 Subject: [Haskell-cafe] Re: Optimizing spelling correction program In-Reply-To: <20090621201801.GA2871@whirlpool.galois.com> References: <20090621201801.GA2871@whirlpool.galois.com> Message-ID: > What are the keys in your Map? Strict ByteStrings? > > And you're using ghc 6.10.x? For the record, I use 6.10.1 and strict ByteString everywhere now. I used to have some lazy IO with vanilla strings, but switching to Data.ByteString.Char8.readFile didn't change the time at all. The big.txt is about 6megs. Profiling output says there are about 100 000 000 entries for the lookup function. http://patch-tag.com/r/spellcorrect/snapshot/current/content/pretty From vanenkj at gmail.com Sun Jun 21 17:45:04 2009 From: vanenkj at gmail.com (John Van Enk) Date: Sun Jun 21 17:28:06 2009 Subject: [Haskell-cafe] Suggestion for Network.Socket in regards to PortNumber Message-ID: Hello List, Is there any one else in favor of hiding the PortNum constructor in Network.Socket in the next release? Here's why: Prelude> :m + Network.Socket Data.Word Prelude Network.Socket Data.Word> let p = 5000 :: Word16 Prelude Network.Socket Data.Word> let p' = PortNum p Prelude Network.Socket Data.Word> let p'' = fromIntegral p :: PortNumber Loading package parsec-2.1.0.1 ... linking ... done. Loading package network-2.2.1.1 ... linking ... done. Prelude Network.Socket Data.Word> p 5000 Prelude Network.Socket Data.Word> p' 34835 Prelude Network.Socket Data.Word> p'' 5000 Notice that using the PortNum constructor does not at all do what the user expects. This really should be a hidden constructor. Perhaps we can add the following: mkPortNum :: (Num a) => a -> PortNumber mkPortNum p = fromIntegral p /jve From donn at avvanta.com Sun Jun 21 18:02:59 2009 From: donn at avvanta.com (Donn Cave) Date: Sun Jun 21 17:46:01 2009 Subject: [Haskell-cafe] Suggestion for Network.Socket in regards to PortNumber References: Message-ID: <20090621220259.77E7693C13@mail.avvanta.com> Quoth John Van Enk , [... example showing that PortNum is stored in network byte order ] > Notice that using the PortNum constructor does not at all do what the > user expects. This really should be a hidden constructor. Could you elaborate, what does the user expect? Donn From lennart at augustsson.net Sun Jun 21 18:16:52 2009 From: lennart at augustsson.net (Lennart Augustsson) Date: Sun Jun 21 17:59:56 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <4A3E6570.90504@btinternet.com> References: <4A3E6570.90504@btinternet.com> Message-ID: As others have pointed out, it is not enough to rename before reduction. It should be pretty obvious since when you do substitution and copy a lambda expression into more than once place you will introduce variables with the same name. You can keep unique variables by "cloning" during substitution, i.e., renaming the bound variables. -- Lennart On Sun, Jun 21, 2009 at 6:53 PM, Andrew Coppin wrote: > OK, so I'm guessing there might be one or two (!) people around here who > know something about the Lambda calculus. > > I've written a simple interpretter that takes any valid Lambda expression > and performs as many beta reductions as possible. When the input is first > received, all the variables are renamed to be unique. > > Question: Does this guarantee that the reduction sequence will never contain > name collisions? > > I have a sinking feeling that it does not. However, I can find no > counter-example as yet. If somebody here can provide either a proof or a > counter-example, that would be helpful. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From lennart at augustsson.net Sun Jun 21 18:17:46 2009 From: lennart at augustsson.net (Lennart Augustsson) Date: Sun Jun 21 18:00:59 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <7b501d5c0906211005j3ec12b77waf63edbe1bc6438f@mail.gmail.com> References: <4A3E6570.90504@btinternet.com> <7b501d5c0906211005j3ec12b77waf63edbe1bc6438f@mail.gmail.com> Message-ID: Actually, keeping all names distinct is not de Bruijn numbering, it's called the Barendregt convention. On Sun, Jun 21, 2009 at 7:05 PM, Deniz Dogan wrote: > 2009/6/21 Andrew Coppin : >> OK, so I'm guessing there might be one or two (!) people around here who >> know something about the Lambda calculus. >> >> I've written a simple interpretter that takes any valid Lambda expression >> and performs as many beta reductions as possible. When the input is first >> received, all the variables are renamed to be unique. >> >> Question: Does this guarantee that the reduction sequence will never contain >> name collisions? >> >> I have a sinking feeling that it does not. However, I can find no >> counter-example as yet. If somebody here can provide either a proof or a >> counter-example, that would be helpful. > > I'm no expert, but it sounds to me like you're doing the equivalent of > "de Bruijn indexing", which is a method to avoid alpha conversion, > which is basically what you're worried about. Therefore, I'm guessing > that there will be no name collisions. > > -- > Deniz Dogan > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From vanenkj at gmail.com Sun Jun 21 18:59:03 2009 From: vanenkj at gmail.com (John Van Enk) Date: Sun Jun 21 18:42:07 2009 Subject: [Haskell-cafe] Suggestion for Network.Socket in regards to PortNumber In-Reply-To: <20090621220259.77E7693C13@mail.avvanta.com> References: <20090621220259.77E7693C13@mail.avvanta.com> Message-ID: On Sun, Jun 21, 2009 at 6:02 PM, Donn Cave wrote: > Could you elaborate, what does the user expect? Users will probably expect (PortNum 0x2000) to represent a port number of 0x2000 (8192), not 0x0020 (32). /jve From thomas.dubuisson at gmail.com Sun Jun 21 19:22:42 2009 From: thomas.dubuisson at gmail.com (Thomas DuBuisson) Date: Sun Jun 21 19:05:45 2009 Subject: [Haskell-cafe] Suggestion for Network.Socket in regards to PortNumber In-Reply-To: References: Message-ID: <4c44d90b0906211622i39dfccb3qd7c57ed2a5d38b6e@mail.gmail.com> I'm in favor of the entire Network library being reworked with an improved API that is higher level and type-safe instead of a direct translation/FFI of Berkeley sockets. I also would like the Network package to export Data instances for headers while taking advantage of pretty, prettyclass, and parsec. I started such work with network-data but never really got off the ground with it. Thomas On Sun, Jun 21, 2009 at 2:45 PM, John Van Enk wrote: > Hello List, > > Is there any one else in favor of hiding the PortNum constructor in > Network.Socket in the next release? Here's why: > > Prelude> :m + Network.Socket Data.Word > Prelude Network.Socket Data.Word> let p = 5000 :: Word16 > Prelude Network.Socket Data.Word> let p' = PortNum p > Prelude Network.Socket Data.Word> let p'' = fromIntegral p :: PortNumber > Loading package parsec-2.1.0.1 ... linking ... done. > Loading package network-2.2.1.1 ... linking ... done. > Prelude Network.Socket Data.Word> p > 5000 > Prelude Network.Socket Data.Word> p' > 34835 > Prelude Network.Socket Data.Word> p'' > 5000 > > Notice that using the PortNum constructor does not at all do what the > user expects. This really should be a hidden constructor. > > Perhaps we can add the following: > > mkPortNum :: (Num a) => a -> PortNumber > mkPortNum p = fromIntegral p > > /jve > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From byorgey at seas.upenn.edu Sun Jun 21 20:14:27 2009 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Sun Jun 21 19:57:29 2009 Subject: [Haskell-cafe] Slightly off-topic: Lambda calculus In-Reply-To: <4A3E807E.9050609@btinternet.com> References: <4A3E6570.90504@btinternet.com> <20090621172617.GA10579@cs.helsinki.fi> <4A3E7486.1060401@btinternet.com> <4A3E7AF4.7060009@btinternet.com> <4A3E807E.9050609@btinternet.com> Message-ID: <20090622001427.GA10375@seas.upenn.edu> On Sun, Jun 21, 2009 at 07:48:30PM +0100, Andrew Coppin wrote: > Andrew Coppin wrote: >> Well anyway, the obvious thing to do is after each reduction, strip off >> all the variable indicies and rerun the labeller to assign new indicies. >> But does this solution work properly in general? > > No. > > Supposing some Lambda expression eventually reduces to, say, > > \x1 -> \x2 -> x1 x2 > > Now strip off all the indicies: > > \x -> \x -> x x > > ...and recompute them... > > \x1 -> \x2 -> x2 x2 > > FAIL. > > To make it worth properly, I would have to (at least) make the renamer > respect any indicies which are already present. It's nontrivial, but > doable. Of course, the ?1,643,264 question is... would it work even then? I reiterate the pointers to reading material that I gave earlier. A lot of really smart people have spent a lot of time thinking about this already; it's likely not worth any more of your time to try figuring it out yourself. (It's definitely worth some initial time struggling with it, so that you can properly appreciate the solutions---but it sounds like you've already done that!) Briefly, the key operation is substitution---*while* doing a substitution you have to somehow check that names aren't clashing, and possibly rename some things if necessary (or if using de Bruijn indices, you may need to shift some indices around while doing substitution). If you wait until *after* doing a substitution to fix up the names, it's too late. But don't take my word for it, go read about it somewhere. =) -Brent From niklas.broberg at gmail.com Sun Jun 21 20:59:02 2009 From: niklas.broberg at gmail.com (Niklas Broberg) Date: Sun Jun 21 20:42:04 2009 Subject: [Haskell-cafe] Re: ANN: haskell-src-exts 1.0.0 rc1 (aka 0.5.2) In-Reply-To: References: Message-ID: Dear all, I'm pleased to announce to you haskell-src-exts-0.5.7, which is truly the first *real* release candidate for 1.0.0. By real, I mean that I could consider releasing it in this state. It is feature complete, fully documented, and has no remaining known bugs. But before I do, I'd like to run it past you all one final time. Please help me test it! Via cabal: cabal install haskell-src-exts Via darcs: darcs get http://code.haskell.org/haskell-src-exts On hackage: http://hackage.haskell.org/package/haskell-src-exts-0.5.7 Changes from 0.5.6: ===================== Two small bug fixes: * Fixed a bug in the parser productions that made SCC pragmas virtually unusable. Note that this fix includes a change in the AST for expressions. * Fixed a bug in the fixity mangler where some subexpressions