From adam.smyczek at gmail.com Thu May 1 02:28:50 2008 From: adam.smyczek at gmail.com (Adam Smyczek) Date: Thu May 1 02:23:17 2008 Subject: [Haskell-cafe] ANN: ReviewBoard 0.1 bindings Message-ID: This package is part of a development tool designed to monitor code changes, analyze dependencies etc. Actually, we are still in process to develop the tool and this binding is the first functional ready package others might be interested in as well. The package contains a basic set of API calls to ReviewBoard server and a small demo app, a command line tool that makes submitting new code review requests as easy as: svn diff | mkrr -r [reviewers] (ReviewBoard does not support darcs) :( For details see haddock documentation. The ReviewBoard project page: http://code.google.com/p/reviewboard/ And the bindings on hackage: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/ ReviewBoard-0.1 A thanks to this list for help with this project and help in getting started with Haskell by following many good threads. Adam From devriese at cs.tcd.ie Thu May 1 08:09:32 2008 From: devriese at cs.tcd.ie (Edsko de Vries) Date: Thu May 1 08:04:01 2008 Subject: [Haskell-cafe] Understanding tail recursion and trees Message-ID: <20080501120932.GB29147@netsoc.tcd.ie> Hi, I am writing a simple compiler for a small DSL embedded in Haskell, and am struggling to identify and remove the source of a stack error when compiling larger examples. To understand the issues better, I was playing around with tail recursion on trees when I came across the following problem. Suppose we want to count the number of leaves in a tree. The obvious naive (non tail-recursive) will run out of stack space quickly on larger trees. To test this, I defined a function that generates left (gentreeL, code below) or right (gentreeR) biased trees, that look like * * / \ / \ * * * * / \ / \ * * * * . . . . n n respectively; that is, a tree of depth n, with on the right (or the left) leaves only). Now, we can define define two traversals: one that has a tail call for the left subtree, after having traversed the right (acountL, below); and one that has a tail call for the right subtree, after having traversed the left (acountR). I was expecting acountL to work on the left biased tree but not on the right biased tree -- and that assumption turned out to be correct. However, I was also expecting (by "duality" :) acountR to work on the right biased tree, but not on the left biased tree, whereas in fact it works on both! (Indeed, it works on reallybigtree3, which combines the left and right biased trees, as well.) Can anyone explain why this is happening? Why is acountR not running out of stack space on the left biased tree? Also, if this is quirk rather than something I can rely on, is there a way to write a function that can count the number of leaves in reallybigtree3 without running out of stack space? Thanks (code follows), Edsko > data Tree = Leaf Integer | Branch Tree Tree > -- naive count > ncount :: Tree -> Integer > ncount (Leaf _) = 1 > ncount (Branch t1 t2) = ncount t1 + ncount t2 > -- generate left-biased tree (right nodes are always single leaves) > gentreeL :: Integer -> Tree > gentreeL 0 = Leaf 0 > gentreeL n = Branch (gentreeL (n-1)) (Leaf 0) > > -- generate right-based tree (left nodes are always single leaves) > gentreeR :: Integer -> Tree > gentreeR 0 = Leaf 0 > gentreeR n = Branch (Leaf 0) (gentreeR (n-1)) > > -- test examples > reallybigtree1 = gentreeL 2000000 > reallybigtree2 = gentreeR 2000000 > reallybigtree3 = Branch (gentreeL 2000000) (gentreeR 2000000) > > -- count with tail calls for the left subtree > acountL :: Tree -> Integer -> Integer > acountL (Leaf _) acc = acc + 1 > acountL (Branch t1 t2) acc = acountL t1 $! (acountL t2 acc) > > -- count with tail calls for the right subtree > acountR :: Tree -> Integer -> Integer > acountR (Leaf _) acc = acc + 1 > acountR (Branch t1 t2) acc = acountR t2 $! (acountL t1 acc) From miguelimo38 at yandex.ru Thu May 1 08:24:29 2008 From: miguelimo38 at yandex.ru (Miguel Mitrofanov) Date: Thu May 1 08:19:02 2008 Subject: [Haskell-cafe] Understanding tail recursion and trees In-Reply-To: <20080501120932.GB29147@netsoc.tcd.ie> References: <20080501120932.GB29147@netsoc.tcd.ie> Message-ID: <3C1C20E0-6619-4A87-9326-B45E0CBE74AB@yandex.ru> Copy-paste approach's failed you. Hint: try removing acountL definition and compiling everything else. >> -- count with tail calls for the left subtree >> acountL :: Tree -> Integer -> Integer >> acountL (Leaf _) acc = acc + 1 >> acountL (Branch t1 t2) acc = acountL t1 $! (acountL t2 acc) >> >> >> -- count with tail calls for the right subtree >> acountR :: Tree -> Integer -> Integer >> acountR (Leaf _) acc = acc + 1 >> acountR (Branch t1 t2) acc = acountR t2 $! (acountL t1 acc) > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From devriese at cs.tcd.ie Thu May 1 08:32:37 2008 From: devriese at cs.tcd.ie (Edsko de Vries) Date: Thu May 1 08:27:03 2008 Subject: [Haskell-cafe] Re: Understanding tail recursion and trees Message-ID: <20080501123236.GC29147@netsoc.tcd.ie> Hi, Thanks to Miguel for pointing out my silly error. So at least my understanding of tail recursion is correct :) So then the question becomes: what *is* the best way to write this function? One version I can think of is > ecount :: [Tree] -> Integer -> Integer > ecount [] acc = acc > ecount (Leaf _ : ts) acc = ecount ts $! (acc + 1) > ecount (Branch t1 t2 : ts) acc = ecount (t1 : t2 : ts) acc which essentially maintains an explicit stack and runs on all trees. Are there better ways to do this? Thanks again and sorry for my mistake, Edsko From felipe.lessa at gmail.com Thu May 1 08:44:43 2008 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Thu May 1 08:39:09 2008 Subject: [Haskell-cafe] Re: Understanding tail recursion and trees In-Reply-To: <20080501123236.GC29147@netsoc.tcd.ie> References: <20080501123236.GC29147@netsoc.tcd.ie> Message-ID: On Thu, May 1, 2008 at 9:32 AM, Edsko de Vries wrote: > So then the question becomes: what *is* the best way to write this function? I guess it would be simpler to have the counter on the data type and a smart branch constructor: > data Tree = Leaf Integer | Branch Integer Tree Tree > > count :: Tree -> Integer > count (Leaf _) = 1 > count (Branch c _ _) = c > > branch :: Tree -> Tree -> Tree > branch left right = Branch (count left + count right) left right > > gentreeL :: Integer -> Tree > gentreeL 0 = Leaf 0 > gentreeL n = branch (gentreeL (n-1)) (Leaf 0) etc. -- Felipe. From david.waern at gmail.com Thu May 1 09:42:19 2008 From: david.waern at gmail.com (David Waern) Date: Thu May 1 09:36:42 2008 Subject: [Haskell-cafe] ANN: Haddock version 2.1.0 Message-ID: Hi everyone, I'm pleased to announce Haddock 2.1.0. Hackage page: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/haddock-2.1.0 Changes since last version: * Fix a bug that made links point to the defining module instead of the "best" one (e.g Int pointing to GHC.Base instead of Data.Int) * Fix a couple of smaller bugs * The representation of DocName was changed in the library * Add a flag --no-warnings for turning off warnings David From wss at cs.nott.ac.uk Thu May 1 10:54:43 2008 From: wss at cs.nott.ac.uk (Wouter Swierstra) Date: Thu May 1 10:49:10 2008 Subject: [Haskell-cafe] Couple of formal questions In-Reply-To: <814617240804292014td3d79f9ve9f0e2345b851e2@mail.gmail.com> References: <814617240804292014td3d79f9ve9f0e2345b851e2@mail.gmail.com> Message-ID: <9729FF97-57A8-4B58-8447-4B78FFCEEE6B@cs.nott.ac.uk> Hi Creighton, > Where could I find a good treatment on data vs. codata & the > difference between well-founded recursion & well-founded(?) > corecursion? Bart Jacobs has some good papers on the subject. I found the draft of his book "Introduction to Coalgebra" quite good: http://www.cs.ru.nl/B.Jacobs/CLG/JacobsCoalgebraIntro.pdf > Where could I find a proof that the initial algebras & final > coalgebras of CPO coincide? I saw this referenced in the > "Bananas.." paper as a fact, but am not sure where this comes from. I couldn't find the statement you are referring to in "Functional Programming with Bananas, Lenses, Envelopes, and Barbed Wire" - but I'm not sure if this holds for every CPO. Having data and codata coincide is quite a curious property (I think it's sometimes called "algebraic compactness" - but don't quote me on this). Hope this helps, Wouter From matt at immute.net Thu May 1 11:10:55 2008 From: matt at immute.net (Matt Hellige) Date: Thu May 1 11:05:20 2008 Subject: [Haskell-cafe] Couple of formal questions In-Reply-To: <9729FF97-57A8-4B58-8447-4B78FFCEEE6B@cs.nott.ac.uk> References: <814617240804292014td3d79f9ve9f0e2345b851e2@mail.gmail.com> <9729FF97-57A8-4B58-8447-4B78FFCEEE6B@cs.nott.ac.uk> Message-ID: <5959041b0805010810k4eefaab2k172db83ae4a58627@mail.gmail.com> On Thu, May 1, 2008 at 9:54 AM, Wouter Swierstra wrote: > > > Where could I find a good treatment on data vs. codata & the difference > between well-founded recursion & well-founded(?) corecursion? > > > > Bart Jacobs has some good papers on the subject. I found the draft of his > book "Introduction to Coalgebra" quite good: > > http://www.cs.ru.nl/B.Jacobs/CLG/JacobsCoalgebraIntro.pdf > Indeed. I'd also recommend Varmo Vene's thesis, Categorical Programming with Inductive and Coinductive Types: http://www.cs.ut.ee/~varmo/papers/thesis.pdf Matt -- Matt Hellige / matt@immute.net http://matt.immute.net From adam.smyczek at gmail.com Thu May 1 11:34:44 2008 From: adam.smyczek at gmail.com (Adam Smyczek) Date: Thu May 1 11:29:12 2008 Subject: [Haskell-cafe] Haskell Web server In-Reply-To: <1ff5dedc0804250728y7c128270v23ecf62ad8c39ef7@mail.gmail.com> References: <1ff5dedc0804250728y7c128270v23ecf62ad8c39ef7@mail.gmail.com> Message-ID: <1841B69F-64FB-4C96-9421-EF06CE995914@gmail.com> A great step by step introduction: http://mult.ifario.us/p/wiring-haskell-into-a-fastcgi-web-server On Apr 25, 2008, at 7:28 AM, Cetin Sert wrote: > Hi, > > What is the fastest way to set up a web server that can redirect > requests to a haskell application and serve results returned by it? > > I need to demonstrate a simple visualization tool I have written > for analytic tableaux on Monday and need something easy and simple. > > Best Regards, > Cetin Sert > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe From felipe.lessa at gmail.com Thu May 1 11:43:46 2008 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Thu May 1 11:38:10 2008 Subject: [Haskell-cafe] Re: Understanding tail recursion and trees In-Reply-To: References: <20080501123236.GC29147@netsoc.tcd.ie> Message-ID: On Thu, May 1, 2008 at 9:44 AM, Felipe Lessa wrote: > On Thu, May 1, 2008 at 9:32 AM, Edsko de Vries wrote: > > So then the question becomes: what *is* the best way to write this function? > > I guess it would be simpler to have the counter on the data type and a > smart branch constructor: Under more careful analysis, it seems I just moved the stack overflow from the counter function to the generator =). Modifying the data type to > data Tree = Leaf Integer | Branch !Integer Tree Tree also won't work in this example (although it seems to fail earlier). However, I'd expect the data type above to work nicely with most real applications (that doesn't construct the entire tree in one go), such as Data.Map[1]. But the answer to your original question really seems to be using an explicit stack created in the heap. This technique is used in Data.Map in a certain case[2] and, although has received a lot of attention on a thread that sparked some time ago (I think it was [3]) for being merely a workaround over the limited stack, it seems to me it's a compulsory workaround for the time being when working with problems like yours. HTH, [1] http://haskell.org/ghc/docs/latest/html/libraries/containers/src/Data-Map.html#Map [2] http://haskell.org/ghc/docs/latest/html/libraries/containers/src/Data-Map.html#fromDistinctAscList [3] http://www.haskell.org/pipermail/haskell-cafe/2008-February/039104.html -- Felipe. From usenet at mkarcher.dialup.fu-berlin.de Thu May 1 11:58:43 2008 From: usenet at mkarcher.dialup.fu-berlin.de (Michael Karcher) Date: Thu May 1 11:53:29 2008 Subject: [Haskell-cafe] Re: Couple of formal questions References: <814617240804292014td3d79f9ve9f0e2345b851e2@mail.gmail.com> <9729FF97-57A8-4B58-8447-4B78FFCEEE6B@cs.nott.ac.uk> Message-ID: Wouter Swierstra wrote: > Hi Creighton, > > Where could I find a proof that the initial algebras & final > > coalgebras of CPO coincide? I saw this referenced in the > > "Bananas.." paper as a fact, but am not sure where this comes from. > I couldn't find the statement you are referring to in "Functional > Programming with Bananas, Lenses, Envelopes, and Barbed Wire" - but > I'm not sure if this holds for every CPO. Probably he was referring to the last paragraph of the introduction: Working in CPO has the advantage that the carriers of intial algebras and final co-algebras coincide, thus there is a single data type that comprises both finite and infinite elements. Regards, Michael Karcher From gwern0 at gmail.com Thu May 1 15:06:25 2008 From: gwern0 at gmail.com (Gwern Branwen) Date: Thu May 1 15:02:54 2008 Subject: [Haskell-cafe] ANN: Haddock version 2.1.0 In-Reply-To: References: Message-ID: <20080501190625.GB474@localhost> On 2008.05.01 15:42:19 +0200, David Waern scribbled 0.5K characters: > Hi everyone, > > I'm pleased to announce Haddock 2.1.0. > > Hackage page: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/haddock-2.1.0 > > Changes since last version: > > * Fix a bug that made links point to the defining module instead > of the "best" one (e.g Int pointing to GHC.Base instead of Data.Int) > > * Fix a couple of smaller bugs > > * The representation of DocName was changed in the library > > * Add a flag --no-warnings for turning off warnings > > David Out of curiosity: does this release fix the 'type'/--^ bug? I know I kept running into it on well-documented projects. -- gwern package Yakima Tzvrif Knife Tony Weekly Bob HRT TOS DJC -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20080501/d4121dd6/attachment.bin From daniil.elovkov at googlemail.com Thu May 1 16:10:50 2008 From: daniil.elovkov at googlemail.com (Daniil Elovkov) Date: Thu May 1 16:05:16 2008 Subject: [Haskell-cafe] Re: Understanding tail recursion and trees In-Reply-To: References: <20080501123236.GC29147@netsoc.tcd.ie> Message-ID: <481A23CA.3020903@gmail.com> Felipe Lessa wrote: > On Thu, May 1, 2008 at 9:44 AM, Felipe Lessa wrote: >> On Thu, May 1, 2008 at 9:32 AM, Edsko de Vries wrote: >> > So then the question becomes: what *is* the best way to write this function? >> >> I guess it would be simpler to have the counter on the data type and a >> smart branch constructor: > > Under more careful analysis, it seems I just moved the stack overflow > from the counter function to the generator =). Modifying the data type > to > >> data Tree = Leaf Integer | Branch !Integer Tree Tree > > also won't work in this example (although it seems to fail earlier). > However, I'd expect the data type above to work nicely with most real > applications (that doesn't construct the entire tree in one go), such > as Data.Map[1]. > > But the answer to your original question really seems to be using an > explicit stack created in the heap. This technique is used in Data.Map > in a certain case[2] and, although has received a lot of attention on > a thread that sparked some time ago (I think it was [3]) for being > merely a workaround over the limited stack, it seems to me it's a > compulsory workaround for the time being when working with problems > like yours. > I think that consuming heap instead of stack is the best we can do. I may be wrong, but it seems to be more or less impossible to traverse a tree in constant memory. Well, if the tree structure doesn't have back links (apart from left, right). The thing is we have to remember nodes to return and remember if we went to the left or to the right. The left or right biased tree is just a list-like structure, where we don't have to remember anything, we can just proceed. That's why it easy to traverse them in constant memory. Maybe, in a C program we could traverse a tree without back links in constant memory by XORing pointers and left-right booleans. That would employ the property of xor that (a xor b) xor a = b. But I'm not sure. Well, anyway, that's not about Haskell. From graham.fawcett at gmail.com Thu May 1 16:40:13 2008 From: graham.fawcett at gmail.com (Graham Fawcett) Date: Thu May 1 16:34:38 2008 Subject: [Haskell-cafe] Writing an 'expect'-like program with runInteractiveCommand Message-ID: Hi folks, I would like to communicate with an external, line-oriented process, which takes a sequence of one-line commands, each returning an arbitrary number of lines, and waits for another command after each response. So, something like: sendCmd :: (Handle, Handle) -> String -> IO [String] ... main = do handles <- connectToExternalProcess sendCmd handles "do something" resp <- sendCmd "get results" -- needs strict I/O, before "quit"? sendCmd "quit" mapM_ putStrLn resp I've tried using runInteractiveCommand, and several combinations of hFlush, hWaitForInput, etc., but I can't find a combination that actually works. I know this is a sketchy description, but can anyone offer some sample code, or point me toward a program that has similar behaviour? Thanks, Graham From david.waern at gmail.com Thu May 1 16:43:45 2008 From: david.waern at gmail.com (David Waern) Date: Thu May 1 16:38:11 2008 Subject: [Haskell-cafe] ANN: Haddock version 2.1.0 In-Reply-To: <20080501190625.GB474@localhost> References: <20080501190625.GB474@localhost> Message-ID: No it doesn't, but it's on the TODO list. It needs a fix in GHC. By the way, I'm going to experiment with doing the parsing of comments on the Haddock side instead of in GHC. If that works out, we won't have to fix these things in GHC anymore. If anyone wants to help out with Haddock, the darcs repository is at http://code.haskell.org/haddock David 2008/5/1 Gwern Branwen : > On 2008.05.01 15:42:19 +0200, David Waern scribbled 0.5K characters: > > > > Hi everyone, > > > > I'm pleased to announce Haddock 2.1.0. > > > > Hackage page: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/haddock-2.1.0 > > > > Changes since last version: > > > > * Fix a bug that made links point to the defining module instead > > of the "best" one (e.g Int pointing to GHC.Base instead of Data.Int) > > > > * Fix a couple of smaller bugs > > > > * The representation of DocName was changed in the library > > > > * Add a flag --no-warnings for turning off warnings > > > > David > > Out of curiosity: does this release fix the 'type'/--^ bug? I know I kept running into it on well-documented projects. > > -- > gwern > package Yakima Tzvrif Knife Tony Weekly Bob HRT TOS DJC > From tmorris at tmorris.net Thu May 1 17:18:50 2008 From: tmorris at tmorris.net (Tony Morris) Date: Thu May 1 17:13:19 2008 Subject: [Haskell-cafe] Test.QuickCheck.Gen Message-ID: <481A33BA.1050304@tmorris.net> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I am trying to understand the QuickCheck source in a bit of depth and I have noted that a Gen x is a function Int -> StdGen -> x, however, some of the combinators can at times, fail to ever produce a result by throwing an error. I include an example using ghci: *Test.QuickCheck> (f 0 (mkStdGen 0)) :: Int *** Exception: Prelude.(!!): negative index It seems this can be alleviated by changing Gen x to Int -> StdGen -> Maybe x and having the generator produce Nothing when a combinator fails. However, now the function promote cannot be written (I have tried and run into the conundrum of writing the function (a -> Maybe b) -> Maybe (a -> b)), which is used to generate functions. So, I'm caught on the fence about whether there is a possible improvement here (for example, should the elements function throw the error?), or if the current scenario is acceptable. I'm seeking comments about this, thanks! - -- Tony Morris http://tmorris.net/ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFIGjO6mnpgrYe6r60RAtohAKCBsl1lHxuNrBaLHuqwCN58PBHCIACbBALk YWkBkw9o9NUQbr+lgo0rXE0= =JQlH -----END PGP SIGNATURE----- From haskell at list.mightyreason.com Thu May 1 18:29:31 2008 From: haskell at list.mightyreason.com (ChrisK) Date: Thu May 1 18:24:12 2008 Subject: [Haskell-cafe] Re: Writing an 'expect'-like program with runInteractiveCommand In-Reply-To: References: Message-ID: <481A444B.7030409@list.mightyreason.com> Are you adjusting 'System.IO.hSetBuffering' to NoBuffering for those handles? Graham Fawcett wrote: > Hi folks, > > I would like to communicate with an external, line-oriented process, > which takes a sequence of one-line commands, each returning an > arbitrary number of lines, and waits for another command after each > response. So, something like: > > sendCmd :: (Handle, Handle) -> String -> IO [String] > ... > > main = do > handles <- connectToExternalProcess > sendCmd handles "do something" > resp <- sendCmd "get results" -- needs strict I/O, before "quit"? > sendCmd "quit" > mapM_ putStrLn resp > > I've tried using runInteractiveCommand, and several combinations of > hFlush, hWaitForInput, etc., but I can't find a combination that > actually works. > > I know this is a sketchy description, but can anyone offer some sample > code, or point me toward a program that has similar behaviour? > > Thanks, > Graham From vigalchin at gmail.com Thu May 1 20:42:37 2008 From: vigalchin at gmail.com (Galchin, Vasili) Date: Thu May 1 20:37:00 2008 Subject: [Haskell-cafe] elementary Maybe Monad problem .. sigh Message-ID: <5ae4f2ba0805011742j5f5d99e8gb1b7c85e5b6b5b57@mail.gmail.com> data Bozo = Bozo { id :: Int } bonzo :: Maybe Bozo -> IO () bonzo maybe_bozo = do if maybe_bozo == (Just (Bozo x)) then return () else return () ~ I want "x" to be a pattern that matches "id" .... ?? Kind regards, Vasili -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080501/27fc2e83/attachment.htm From claudiusmaximus at goto10.org Thu May 1 20:48:59 2008 From: claudiusmaximus at goto10.org (Claude Heiland-Allen) Date: Thu May 1 20:43:25 2008 Subject: [Haskell-cafe] elementary Maybe Monad problem .. sigh In-Reply-To: <5ae4f2ba0805011742j5f5d99e8gb1b7c85e5b6b5b57@mail.gmail.com> References: <5ae4f2ba0805011742j5f5d99e8gb1b7c85e5b6b5b57@mail.gmail.com> Message-ID: <481A64FB.4000407@goto10.org> Galchin, Vasili wrote: > > data Bozo = > Bozo { > id :: Int > } > > bonzo :: Maybe Bozo -> IO () > bonzo maybe_bozo = do > if maybe_bozo == (Just (Bozo x)) > then > return () > else > return () > ~ > > I want "x" to be a pattern that matches "id" .... ?? Try: bonzo (Just (Bozo x)) = return () bonzo Nothing = return () > Kind regards, Vasili Claude -- http://claudiusmaximus.goto10.org From lrpalmer at gmail.com Thu May 1 20:50:54 2008 From: lrpalmer at gmail.com (Luke Palmer) Date: Thu May 1 20:45:16 2008 Subject: [Haskell-cafe] elementary Maybe Monad problem .. sigh In-Reply-To: <5ae4f2ba0805011742j5f5d99e8gb1b7c85e5b6b5b57@mail.gmail.com> References: <5ae4f2ba0805011742j5f5d99e8gb1b7c85e5b6b5b57@mail.gmail.com> Message-ID: <7ca3f0160805011750k85e5c72y7336f6301e89abb9@mail.gmail.com> 2008/5/2 Galchin, Vasili : > > data Bozo = > Bozo { > id :: Int > } > > bonzo :: Maybe Bozo -> IO () > bonzo maybe_bozo = do > if maybe_bozo == (Just (Bozo x)) > then > return () > else > return () bonzo maybe_bozo = case maybe_bozo of Just (Bozo x) -> return () _ -> return () Or equivalently: bonzo (Just (Bozo x)) = return () bonzo _ = return () You should watch out for your use of id as a field name, since id is a builtin function and you will get ambiguity errors. Luke From vigalchin at gmail.com Thu May 1 21:18:43 2008 From: vigalchin at gmail.com (Galchin, Vasili) Date: Thu May 1 21:13:13 2008 Subject: [Haskell-cafe] elementary Maybe Monad problem .. sigh In-Reply-To: <7ca3f0160805011750k85e5c72y7336f6301e89abb9@mail.gmail.com> References: <5ae4f2ba0805011742j5f5d99e8gb1b7c85e5b6b5b57@mail.gmail.com> <7ca3f0160805011750k85e5c72y7336f6301e89abb9@mail.gmail.com> Message-ID: <5ae4f2ba0805011818y2fb6ec38y53e4d46614076449@mail.gmail.com> Sorry .. my example was bad. I want to use "x" .. in then branch where it occur ... e.g. bonzo :: Maybe Bozo -> IO () bonzo maybe_bozo = do case maybe_bozo of Just (Bozo x) -> x ........ _ -> ......... ?? Thanks, V. On Thu, May 1, 2008 at 7:50 PM, Luke Palmer wrote: > 2008/5/2 Galchin, Vasili : > > > > data Bozo = > > Bozo { > > id :: Int > > } > > > > bonzo :: Maybe Bozo -> IO () > > bonzo maybe_bozo = do > > if maybe_bozo == (Just (Bozo x)) > > then > > return () > > else > > return () > > bonzo maybe_bozo = > case maybe_bozo of > Just (Bozo x) -> return () > _ -> return () > > Or equivalently: > > bonzo (Just (Bozo x)) = return () > bonzo _ = return () > > You should watch out for your use of id as a field name, since id is a > builtin function and you will get ambiguity errors. > > Luke > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080501/d727c001/attachment.htm From vigalchin at gmail.com Thu May 1 21:27:21 2008 From: vigalchin at gmail.com (Galchin, Vasili) Date: Thu May 1 21:21:44 2008 Subject: [Haskell-cafe] elementary Maybe Monad problem .. sigh In-Reply-To: <5ae4f2ba0805011818y2fb6ec38y53e4d46614076449@mail.gmail.com> References: <5ae4f2ba0805011742j5f5d99e8gb1b7c85e5b6b5b57@mail.gmail.com> <7ca3f0160805011750k85e5c72y7336f6301e89abb9@mail.gmail.com> <5ae4f2ba0805011818y2fb6ec38y53e4d46614076449@mail.gmail.com> Message-ID: <5ae4f2ba0805011827t23f6cd9i7c3ea58e82a04482@mail.gmail.com> Here is a simpler case of what I want to do .. 1) To function1 pass in (Maybe Int). 2) If "Nothing" then pass nullPtr to C function. 3) If "Just 1", then pass a pointer to a "1" to teh same C function. Thanks, Vasili On Thu, May 1, 2008 at 8:18 PM, Galchin, Vasili wrote: > Sorry .. my example was bad. I want to use "x" .. in then branch where > it occur ... > > e.g. > bonzo :: Maybe Bozo -> IO () > bonzo maybe_bozo = do > case maybe_bozo of > Just (Bozo x) -> x ........ > _ -> ......... > > ?? > > Thanks, V. > > > On Thu, May 1, 2008 at 7:50 PM, Luke Palmer wrote: > > > 2008/5/2 Galchin, Vasili : > > > > > > data Bozo = > > > Bozo { > > > id :: Int > > > } > > > > > > bonzo :: Maybe Bozo -> IO () > > > bonzo maybe_bozo = do > > > if maybe_bozo == (Just (Bozo x)) > > > then > > > return () > > > else > > > return () > > > > bonzo maybe_bozo = > > case maybe_bozo of > > Just (Bozo x) -> return () > > _ -> return () > > > > Or equivalently: > > > > bonzo (Just (Bozo x)) = return () > > bonzo _ = return () > > > > You should watch out for your use of id as a field name, since id is a > > builtin function and you will get ambiguity errors. > > > > Luke > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080501/f10b6a6e/attachment.htm From dons at galois.com Thu May 1 21:48:57 2008 From: dons at galois.com (Don Stewart) Date: Thu May 1 21:43:21 2008 Subject: [Haskell-cafe] Announce: ghc-core, command line pager for reading GHC Core Message-ID: <20080502014857.GA1722@scytale.galois.com> Just a quick announcement, I've uploaded to hackage 'ghc-core' , a wrapper over ghc for displaying the optimised core and assembly language ghc produces from your programs. The code is colourised by hscolour, and displayed in a pager, git-log style. This will be useful for those who like looking at optimised Haskell. You can quickly get an idea of what kind of core and assembly your code is turning into, and the effect of various flags on the result. Usage: $ ghc-core Foo.hs $ ghc-core Foo.hs -optc-O2 -fvia-C Get it here, http://hackage.haskell.org/cgi-bin/hackage-scripts/package/ghc-core Screenshot, http://galois.com/~dons/images/ghc-core.png Cheers, Don From qdunkan at gmail.com Thu May 1 22:12:06 2008 From: qdunkan at gmail.com (Evan Laforge) Date: Thu May 1 22:06:31 2008 Subject: [Haskell-cafe] elementary Maybe Monad problem .. sigh In-Reply-To: <5ae4f2ba0805011827t23f6cd9i7c3ea58e82a04482@mail.gmail.com> References: <5ae4f2ba0805011742j5f5d99e8gb1b7c85e5b6b5b57@mail.gmail.com> <7ca3f0160805011750k85e5c72y7336f6301e89abb9@mail.gmail.com> <5ae4f2ba0805011818y2fb6ec38y53e4d46614076449@mail.gmail.com> <5ae4f2ba0805011827t23f6cd9i7c3ea58e82a04482@mail.gmail.com> Message-ID: <2518b95d0805011912v6a73d208mc4acf8753469035d@mail.gmail.com> 2008/5/1 Galchin, Vasili : > Here is a simpler case of what I want to do .. > > 1) To function1 pass in (Maybe Int). > > 2) If "Nothing" then pass nullPtr to C function. > > 3) If "Just 1", then pass a pointer to a "1" to teh same C function. Check out Foreign.maybeWith. From donn at avvanta.com Fri May 2 00:16:29 2008 From: donn at avvanta.com (Donn Cave) Date: Fri May 2 00:11:01 2008 Subject: [Haskell-cafe] Re: Writing an 'expect'-like program with runInteractiveCommand In-Reply-To: <481A444B.7030409@list.mightyreason.com> References: <481A444B.7030409@list.mightyreason.com> Message-ID: <8C5358FD-9099-432B-AEFD-3C4889EFA69C@avvanta.com> Graham Fawcett wrote: > I would like to communicate with an external, line-oriented process, > which takes a sequence of one-line commands, each returning an > arbitrary number of lines, and waits for another command after each > response. So, something like: > sendCmd :: (Handle, Handle) -> String -> IO [String] You may need to make some compromises to get this within the realm of the possible, if I understand your objective. - There is no way (at least on UNIX) to know when a read has been posted on the other end of your pipe/socket/pty/whatever. So you can't tell in this way when the external process has sent the last of the arbitrary number of lines and is now waiting for another command. If you have another way to know, or it doesn't really matter, then fine. - The vast majority of `line-oriented' software are actually going to block buffer their output when writing to a pipe, because that's what C I/O does. If you're lucky, the program you're dealing with here will flush its output before it reads, but if it doesn't, you're hosed - there isn't any way to talk to this program `interactively' on a pipe. In this case, you need a pseudotty device, a sort of pipe that supports tty device ioctls. - Buffering on your side of the I/O is of course also worse than useless. I see the GHC 6.8 library supports pseudottys, so for general amusement I submit below a small demonstration program. Unfortunately it doesn't entirely work. The pseudotty works, but I'm unable to turn off ECHO on the slave. So each master line yields two slave lines, and my program expects only one and gets behind on that account. So the command has to include its own "stty -echo". The commented lines attempt to turn of ECHO, but on MacOS X that causes the program to fail mysteriously. Donn Cave, donn@avvanta.com -------------------------------------------------- import System.Posix.Terminal (TerminalMode(..), TerminalState(..), withoutMode, getTerminalAttributes, setTerminalAttributes, openPseudoTerminal, getSlaveTerminalName) import System (getArgs) import System.Posix.Types (Fd, ProcessID) import System.Posix.Process (forkProcess, executeFile) import System.Posix.IO (stdInput, stdOutput, closeFd, dupTo, fdWrite, fdRead) pchild :: Fd -> IO () -> IO () pchild slaveFd exec = do dupTo slaveFd stdInput dupTo slaveFd stdOutput closeFd slaveFd exec ptyOpen :: IO () -> IO (ProcessID, Fd) ptyOpen exec = do (master, slave) <- openPseudoTerminal -- tc <- getTerminalAttributes slave -- let tc = withoutMode tc EchoLF -- setTerminalAttributes slave tc WhenDrained pid <- forkProcess (pchild slave exec) closeFd slave return (pid, master) ioact p0 p1 m0 m1 = do (d, n) <- fdRead m0 512 fdWrite p1 d (e, n) <- fdRead p0 512 fdWrite m1 e ioact p0 p1 m0 m1 main = do (cmd:args) <- getArgs (pid, fd) <- ptyOpen (executeFile cmd True args Nothing) ioact fd fd stdInput stdOutput From derek.a.elkins at gmail.com Fri May 2 01:12:19 2008 From: derek.a.elkins at gmail.com (Derek Elkins) Date: Fri May 2 01:06:46 2008 Subject: [Haskell-cafe] Re: Understanding tail recursion and trees In-Reply-To: <481A23CA.3020903@gmail.com> References: <20080501123236.GC29147@netsoc.tcd.ie> <481A23CA.3020903@gmail.com> Message-ID: <1209705139.5514.3.camel@derek-laptop> On Fri, 2008-05-02 at 00:10 +0400, Daniil Elovkov wrote: > Felipe Lessa wrote: > > On Thu, May 1, 2008 at 9:44 AM, Felipe Lessa wrote: > >> On Thu, May 1, 2008 at 9:32 AM, Edsko de Vries wrote: > >> > So then the question becomes: what *is* the best way to write this function? > >> > >> I guess it would be simpler to have the counter on the data type and a > >> smart branch constructor: > > > > Under more careful analysis, it seems I just moved the stack overflow > > from the counter function to the generator =). Modifying the data type > > to > > > >> data Tree = Leaf Integer | Branch !Integer Tree Tree > > > > also won't work in this example (although it seems to fail earlier). > > However, I'd expect the data type above to work nicely with most real > > applications (that doesn't construct the entire tree in one go), such > > as Data.Map[1]. > > > > But the answer to your original question really seems to be using an > > explicit stack created in the heap. This technique is used in Data.Map > > in a certain case[2] and, although has received a lot of attention on > > a thread that sparked some time ago (I think it was [3]) for being > > merely a workaround over the limited stack, it seems to me it's a > > compulsory workaround for the time being when working with problems > > like yours. > > > > I think that consuming heap instead of stack is the best we can do. > > I may be wrong, but it seems to be more or less impossible to traverse a > tree in constant memory. Well, if the tree structure doesn't have back > links (apart from left, right). > > The thing is we have to remember nodes to return and remember if we went > to the left or to the right. The left or right biased tree is just a > list-like structure, where we don't have to remember anything, we can > just proceed. That's why it easy to traverse them in constant memory. > > Maybe, in a C program we could traverse a tree without back links in > constant memory by XORing pointers and left-right booleans. That would > employ the property of xor that (a xor b) xor a = b. But I'm not sure. > > Well, anyway, that's not about Haskell. http://www.cs.indiana.edu/~jsobel/Recycling/recycling.html From ndmitchell at gmail.com Fri May 2 03:33:31 2008 From: ndmitchell at gmail.com (Neil Mitchell) Date: Fri May 2 03:27:53 2008 Subject: [Haskell-cafe] Announce: ghc-core, command line pager for reading GHC Core In-Reply-To: <20080502014857.GA1722@scytale.galois.com> References: <20080502014857.GA1722@scytale.galois.com> Message-ID: <404396ef0805020033q74dfbad4qfb5bf1a425c3fa03@mail.gmail.com> Hi Don, > Just a quick announcement, I've uploaded to hackage 'ghc-core' , a > wrapper over ghc for displaying the optimised core and assembly language > ghc produces from your programs. This is cool, but it still lags behind the facilities found in yhc-core. http://yhc06.blogspot.com/2006/12/yhccorehtml.html I have found that any effort put into improving Core viewing tools repays itself rather quickly, and that HTML output with hyperlinks is incredibly handy! Thanks Neil From prstanley at ntlworld.com Fri May 2 03:43:34 2008 From: prstanley at ntlworld.com (PR Stanley) Date: Fri May 2 03:38:00 2008 Subject: [Haskell-cafe] Re: Function Type Calculation (Take 2) Message-ID: <7.0.1.0.0.20080502084159.01d2a3e0@ntlworld.com> Just in case anyone missed this: [1] funk f x = f (funk f) x f :: a x :: b funk f x :: c therefore funk :: a -> b -> c RHS f (funk f) x :: c f (funk f) :: d -> c x :: d f :: e -> d -> c funk :: h -> e f :: h unification f :: a = h = (e -> d -> c) x b = d No. x :: b = d (a typo?) Paul: What's wrong with x being of type b and of type d? Could you perhaps explain the error please? Don't forget also that funk :: a -> b -> c = h -> e, which means that e = b -> c Paul: is that something to do with partial application? (funk f) is a partially applied function, correct? Again an explanation would be appreciated. therefore funk :: ((h -> e) -> b -> c) -> b -> c No. I don't understand where you've got this expression from. It's funk :: a -> b -> c = (e -> d -> c) -> b -> c = ((b -> c) -> b -> c) - > b -> c According to GHCi: Prelude> let funk f x = f (funk f) x Prelude> :t funk funk :: ((t1 -> t) -> t1 -> t) -> t1 -> t which is about the same. Thanks Paul From thomas at 0xc29.net Fri May 2 05:58:54 2008 From: thomas at 0xc29.net (Thomas Girod) Date: Fri May 2 05:53:26 2008 Subject: [Haskell-cafe] sound synthesis Message-ID: <481AE5DE.2020003@0xc29.net> Hi there. Following this advice (http://reddit.com/info/6hknz/comments/c03vdc7), I'm posting here. Recently, I read a few articles about Haskell (and FP in general) and music/sound. I remember an article ranting about how lazy evaluation would be great to do signal processing, but it was lacking real world example. I tried to do a little something about it, even though I'm still an haskell apprentice. So, here I come with a small bit of code, waiting for your insights to improve it. The task is to generate a sine wave and pipe it to /dev/dsp on my linux box. There is probably a nicer way to make some noise, like using SDL audio API bindings, but I didn't take the time to poke around this yet. So here it is : > module Main where > import qualified Data.ByteString as B > import Data.Word > import IO (stdout) > rate = 44100 > sinusFloat :: [Float] > sinusFloat = map (\t -> (1 + sin (t*880*2*pi/rate)) / 2) [0..44099] > sinusWord :: [Word8] > sinusWord = map (\s -> floor (s * max)) sinusFloat > where max = 255 > byte = B.pack sinusWord > main = B.hPut stdout byte It is supposed to generate a 880hz sine wav playing for one second, by typing ./bin > /dev/dsp, assuming your soundcard has a 44100hz samplingrate. /dev/dsp is supposed to receive its audio flux as an unsigned byte stream, that's why I'm converting my sine from [-1;1] to [0;1] and then to [0;255] Word8. However, I must miss something because the sound does not have the right frequency and is played too long. I guess the default sound format is 44100hz 16bits stereo, which would explain why it doesn't behave as expected. I'm wondering how I could convert a [Word16] to ByteString, and how I could use lazy evaluation to generate an infinite sine that stops with the interupt. Thomas From lemming at henning-thielemann.de Fri May 2 06:22:22 2008 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Fri May 2 06:15:20 2008 Subject: [Haskell-cafe] sound synthesis In-Reply-To: <481AE5DE.2020003@0xc29.net> References: <481AE5DE.2020003@0xc29.net> Message-ID: On Fri, 2 May 2008, Thomas Girod wrote: > Hi there. Following this advice > (http://reddit.com/info/6hknz/comments/c03vdc7), I'm posting here. > > > Recently, I read a few articles about Haskell (and FP in general) and > music/sound. > > I remember an article ranting about how lazy evaluation would be great to do > signal processing, but it was lacking real world example. There are some 'real world examples', however speed is currently the factor which limits the fun. Currently you get immediate results with the SuperCollider interface or with the CSound interface of Haskore: http://www.haskell.org/haskellwiki/Applications_and_libraries/Music_and_sound Cf. Haskell Art mailing list: http://lists.lurk.org/mailman/listinfo/haskell-art > I tried to do a little something about it, even though I'm still an haskell > apprentice. So, here I come with a small bit of code, waiting for your > insights to improve it. > > The task is to generate a sine wave and pipe it to /dev/dsp on my linux box. > There is probably a nicer way to make some noise, like using SDL audio API > bindings, but I didn't take the time to poke around this yet. > > So here it is : > >> module Main where > >> import qualified Data.ByteString as B >> import Data.Word >> import IO (stdout) > >> rate = 44100 > >> sinusFloat :: [Float] >> sinusFloat = map (\t -> (1 + sin (t*880*2*pi/rate)) / 2) [0..44099] > >> sinusWord :: [Word8] >> sinusWord = map (\s -> floor (s * max)) sinusFloat >> where max = 255 > >> byte = B.pack sinusWord > >> main = B.hPut stdout byte > > It is supposed to generate a 880hz sine wav playing for one second, by typing > ./bin > /dev/dsp, assuming your soundcard has a 44100hz samplingrate. > > /dev/dsp is supposed to receive its audio flux as an unsigned byte stream, > that's why I'm converting my sine from [-1;1] to [0;1] and then to [0;255] > Word8. > > However, I must miss something because the sound does not have the right > frequency and is played too long. I guess the default sound format is 44100hz > 16bits stereo, which would explain why it doesn't behave as expected. > > I'm wondering how I could convert a [Word16] to ByteString, With Data.Binary. > and how I could use lazy evaluation to generate an infinite sine that > stops with the interupt. So far I used a really silly way, but it worked for me so far: I start 'play' from SOX package and pipe my signal into it: http://darcs.haskell.org/synthesizer/src/Sox/Play.hs From claudiusmaximus at goto10.org Fri May 2 06:21:25 2008 From: claudiusmaximus at goto10.org (Claude Heiland-Allen) Date: Fri May 2 06:15:53 2008 Subject: [Haskell-cafe] sound synthesis In-Reply-To: <481AE5DE.2020003@0xc29.net> References: <481AE5DE.2020003@0xc29.net> Message-ID: <481AEB25.3050904@goto10.org> Thomas Girod wrote: > Hi there. Following this advice > (http://reddit.com/info/6hknz/comments/c03vdc7), I'm posting here. > > > Recently, I read a few articles about Haskell (and FP in general) and > music/sound. > > I remember an article ranting about how lazy evaluation would be great > to do signal processing, but it was lacking real world example. > > I tried to do a little something about it, even though I'm still an > haskell apprentice. So, here I come with a small bit of code, waiting > for your insights to improve it. > > The task is to generate a sine wave and pipe it to /dev/dsp on my linux > box. There is probably a nicer way to make some noise, like using SDL > audio API bindings, but I didn't take the time to poke around this yet. > > So here it is : > >> module Main where > >> import qualified Data.ByteString as B >> import Data.Word >> import IO (stdout) > >> rate = 44100 > >> sinusFloat :: [Float] >> sinusFloat = map (\t -> (1 + sin (t*880*2*pi/rate)) / 2) [0..44099] > >> sinusWord :: [Word8] >> sinusWord = map (\s -> floor (s * max)) sinusFloat >> where max = 255 > >> byte = B.pack sinusWord > >> main = B.hPut stdout byte > > It is supposed to generate a 880hz sine wav playing for one second, by > typing ./bin > /dev/dsp, assuming your soundcard has a 44100hz > samplingrate. > > /dev/dsp is supposed to receive its audio flux as an unsigned byte > stream, that's why I'm converting my sine from [-1;1] to [0;1] and then > to [0;255] Word8. > > However, I must miss something because the sound does not have the right > frequency and is played too long. I guess the default sound format is > 44100hz 16bits stereo, which would explain why it doesn't behave as > expected. Nope: The default is 8-bit unsigned samples, using one channel (mono), and an 8 kHz sampling rate. http://www.oreilly.de/catalog/multilinux/excerpt/ch14-05.htm Changing to rate = 8000 and sinusFloat = ... [0..rate-1] gives the expected output. > I'm wondering how I could convert a [Word16] to ByteString, and how I > could use lazy evaluation to generate an infinite sine that stops with > the interupt. > > Thomas Claude -- http://claudiusmaximus.goto10.org From jerzy.karczmarczuk at info.unicaen.fr Fri May 2 06:25:52 2008 From: jerzy.karczmarczuk at info.unicaen.fr (jerzy.karczmarczuk@info.unicaen.fr) Date: Fri May 2 06:20:14 2008 Subject: [Haskell-cafe] sound synthesis In-Reply-To: <481AE5DE.2020003@0xc29.net> References: <481AE5DE.2020003@0xc29.net> Message-ID: Thomas Girod: > Recently, I read a few articles about Haskell (and FP in general) and > music/sound. > > I remember an article ranting about how lazy evaluation would be great to > do signal processing, but it was lacking real world example. Check (e.g. through Google) what Henning Thielemann wrote about. I can offer you something written not in Haskell, but in Clean (the conversion to Haskell is largely trivial), see e.g. this PADL paper, I have it on-line: http://users.info.unicaen.fr/~karczma/arpap/cleasyn.pdf > The task is to generate a sine wave and pipe it to /dev/dsp on my linux > box. There is probably a nicer way to make some noise, like using SDL > audio API bindings, but I didn't take the time to poke around this yet. > I'm wondering how I could convert a [Word16] to ByteString, and how I > could use lazy evaluation to generate an infinite sine that stops with the > interupt. "Infinite sine that stops" is a bit contradictory. In my view the solution is the following. You generate your infinite whatever. Sine, Karplus-Strong sound, flute, whatever, you combine all in one infinite stream, and you don't care at all about stopping. [In Clean I used unboxed, spine-lazy, but head-strict lists. The format was floating-point]. THEN, during the conversion, piping, construction of a .wav table (vector) you think about the time-limitation of the stream. I played with static constraints (concrete number of converted samples). If you want to do it dynamically, then, either you know how to interrupt *any* infinite process within Haskell, or you have to learn how to do it... Here people more competent than myself will surely help you. Good luck, and thanks for your interest in a this fabulous field. Jerzy Karczmarczuk From david.waern at gmail.com Fri May 2 09:48:05 2008 From: david.waern at gmail.com (David Waern) Date: Fri May 2 09:42:26 2008 Subject: [Haskell] Re: [Haskell-cafe] ANN: Haddock version 2.1.0 In-Reply-To: <481A46C0.3050209@gmail.com> References: <20080501190625.GB474@localhost> <481A46C0.3050209@gmail.com> Message-ID: 2008/5/2 Simon Marlow : > David Waern wrote: > > > No it doesn't, but it's on the TODO list. It needs a fix in GHC. > > > > By the way, I'm going to experiment with doing the parsing of comments > > on the Haddock side instead of in GHC. > > If that works out, we won't have to fix these things in GHC anymore. > > > > Sounds great - along the lines that we discussed on cvs-ghc a while back? Yes, something along the lines of separately parsing the comments and recording their source locations, and then trying to match them with the source locations of the AST nodes. I don't think there are any lexical rules for where Haddock comments can exist, so it should work. David From graham.fawcett at gmail.com Fri May 2 09:55:28 2008 From: graham.fawcett at gmail.com (Graham Fawcett) Date: Fri May 2 09:49:50 2008 Subject: [Haskell-cafe] Re: Writing an 'expect'-like program with runInteractiveCommand In-Reply-To: <8C5358FD-9099-432B-AEFD-3C4889EFA69C@avvanta.com> References: <481A444B.7030409@list.mightyreason.com> <8C5358FD-9099-432B-AEFD-3C4889EFA69C@avvanta.com> Message-ID: On Fri, May 2, 2008 at 12:16 AM, Donn Cave wrote: > Graham Fawcett wrote: > > > > I would like to communicate with an external, line-oriented process, > > which takes a sequence of one-line commands, each returning an > > arbitrary number of lines, and waits for another command after each > > response. So, something like: > > sendCmd :: (Handle, Handle) -> String -> IO [String] > You may need to make some compromises to get this within the realm > of the possible, if I understand your objective. > - There is no way (at least on UNIX) to know when a read has been posted > on the other end of your pipe/socket/pty/whatever... Yes, and I should have realized this. After my post, I tried writing the same program in another language, and ran into the same problems. Thanks very much for the response. I'm going to play with your example, and see if I can make it work in this case (and if not, I will still learn from studying it!). In case it's of interest, I see that E.W. Karlsen wrote a series of articles (ten years ago!) on using Haskell to manage asynchronous processes, and included an "expect-like" tool in his UniForM Workbench: http://www.informatik.uni-bremen.de/~ewk/WB.html By the way, what I'm trying to do is to interact with a Berkeley XML database; there's no existing Haskell wrapper for its API, and for this particular task the cost of writing one is too high. I was going to interact with the 'dbxml' command-line utility as a poor-man's FFI. Given the issues you've raised, instead I might use a language that has an existing DBXML interface, and call that from Haskell (e.g. Python via MissingPy). Thanks again, Graham > So you can't tell in this > way when the external process has sent the last of the arbitrary number > of > lines and is now waiting for another command. If you have another way to > know, or it doesn't really matter, then fine. > > - The vast majority of `line-oriented' software are actually going to block > buffer > their output when writing to a pipe, because that's what C I/O does. If > you're > lucky, the program you're dealing with here will flush its output before > it reads, > but if it doesn't, you're hosed - there isn't any way to talk to this > program > `interactively' on a pipe. In this case, you need a pseudotty device, a > sort of > pipe that supports tty device ioctls. > > - Buffering on your side of the I/O is of course also worse than useless. > > I see the GHC 6.8 library supports pseudottys, so for general amusement > I submit below a small demonstration program. Unfortunately it doesn't > entirely work. The pseudotty works, but I'm unable to turn off ECHO on the > slave. So each master line yields two slave lines, and my program expects > only one and gets behind on that account. So the command has to include > its own "stty -echo". The commented lines attempt to turn of ECHO, but on > MacOS X that causes the program to fail mysteriously. > > Donn Cave, donn@avvanta.com > -------------------------------------------------- > import System.Posix.Terminal (TerminalMode(..), TerminalState(..), > withoutMode, getTerminalAttributes, setTerminalAttributes, > openPseudoTerminal, getSlaveTerminalName) > import System (getArgs) > import System.Posix.Types (Fd, ProcessID) > import System.Posix.Process (forkProcess, executeFile) > import System.Posix.IO (stdInput, stdOutput, closeFd, dupTo, fdWrite, > fdRead) > > pchild :: Fd -> IO () -> IO () > pchild slaveFd exec = do > dupTo slaveFd stdInput > dupTo slaveFd stdOutput > closeFd slaveFd > exec > > ptyOpen :: IO () -> IO (ProcessID, Fd) > ptyOpen exec = do > (master, slave) <- openPseudoTerminal > -- tc <- getTerminalAttributes slave > -- let tc = withoutMode tc EchoLF > -- setTerminalAttributes slave tc WhenDrained > pid <- forkProcess (pchild slave exec) > closeFd slave > return (pid, master) > > ioact p0 p1 m0 m1 = do > (d, n) <- fdRead m0 512 > fdWrite p1 d > (e, n) <- fdRead p0 512 > fdWrite m1 e > ioact p0 p1 m0 m1 > > main = do > (cmd:args) <- getArgs > (pid, fd) <- ptyOpen (executeFile cmd True args Nothing) > ioact fd fd stdInput stdOutput > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From a.biurvOir4 at asuhan.com Fri May 2 10:19:53 2008 From: a.biurvOir4 at asuhan.com (Kim-Ee Yeoh) Date: Fri May 2 10:14:14 2008 Subject: [Haskell-cafe] Couple of formal questions In-Reply-To: References: <814617240804292014td3d79f9ve9f0e2345b851e2@mail.gmail.com> <9729FF97-57A8-4B58-8447-4B78FFCEEE6B@cs.nott.ac.uk> Message-ID: <17020475.post@talk.nabble.com> I'm not sure there's a proof as such, more like a definitional absence of distinction between initiality and finality. In other words, the CPO framework is orthogonal to such extremality considerations. Perhaps someone here knows about work enriching CPOs in that direction. -- Kim-Ee Michael Karcher-7 wrote: > > Wouter Swierstra wrote: >> Hi Creighton, >> > Where could I find a proof that the initial algebras & final >> > coalgebras of CPO coincide? I saw this referenced in the >> > "Bananas.." paper as a fact, but am not sure where this comes from. > > Probably he was referring to the last paragraph of the introduction: > > Working in CPO has the advantage that the carriers of intial algebras > and final co-algebras coincide, thus there is a single data type that > comprises both finite and infinite elements. > -- View this message in context: http://www.nabble.com/Couple-of-formal-questions-tp16974927p17020475.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. From claus.reinke at talk21.com Fri May 2 10:35:37 2008 From: claus.reinke at talk21.com (Claus Reinke) Date: Fri May 2 10:30:06 2008 Subject: [Haskell] Re: [Haskell-cafe] ANN: Haddock version 2.1.0 References: <20080501190625.GB474@localhost><481A46C0.3050209@gmail.com> Message-ID: <012e01c8ac61$cc2f0d60$bf078351@cr3lt> > 2008/5/2 Simon Marlow : >> David Waern wrote: >> >> > No it doesn't, but it's on the TODO list. It needs a fix in GHC. >> > >> > By the way, I'm going to experiment with doing the parsing of comments >> > on the Haddock side instead of in GHC. >> > If that works out, we won't have to fix these things in GHC anymore. >> > >> >> Sounds great - along the lines that we discussed on cvs-ghc a while back? > > Yes, something along the lines of separately parsing the comments and > recording their source locations, and then > trying to match them with the source locations of the AST nodes. yay!-) i hope that the haddock-independent part (parsing, preserving, and accessing comments) becomes part of the GHC API in a form that would fix trac ticket #1886, then we could finally start writing (ghc) haskell source-to-source transformations without losing pragmas or comments! losing layout would still be a pain, but that could be dealt with later - at least the code would remain functional under some form of (pretty . id . parse). please keep us posted about your experiments, claus From qdunkan at gmail.com Fri May 2 11:22:21 2008 From: qdunkan at gmail.com (Evan Laforge) Date: Fri May 2 11:16:42 2008 Subject: [Haskell-cafe] sound synthesis In-Reply-To: <481AE5DE.2020003@0xc29.net> References: <481AE5DE.2020003@0xc29.net> Message-ID: <2518b95d0805020822u21870bf0u56a94e6ac93e7f83@mail.gmail.com> > I remember an article ranting about how lazy evaluation would be great to > do signal processing, but it was lacking real world example. The nyquist language does this. It's not haskell, but it does use lazy evaluation for signals. From david.waern at gmail.com Fri May 2 11:37:59 2008 From: david.waern at gmail.com (David Waern) Date: Fri May 2 11:32:19 2008 Subject: [Haskell] Re: [Haskell-cafe] ANN: Haddock version 2.1.0 In-Reply-To: <012e01c8ac61$cc2f0d60$bf078351@cr3lt> References: <20080501190625.GB474@localhost> <481A46C0.3050209@gmail.com> <012e01c8ac61$cc2f0d60$bf078351@cr3lt> Message-ID: 2008/5/2 Claus Reinke : > > > 2008/5/2 Simon Marlow : > > > > > David Waern wrote: > > > > > > > No it doesn't, but it's on the TODO list. It needs a fix in GHC. > > > > > > > > By the way, I'm going to experiment with doing the parsing of comments > > > > on the Haddock side instead of in GHC. > > > > If that works out, we won't have to fix these things in GHC anymore. > > > > > > > > > > Sounds great - along the lines that we discussed on cvs-ghc a while > back? > > > > > > > Yes, something along the lines of separately parsing the comments and > > recording their source locations, and then > > trying to match them with the source locations of the AST nodes. > > > > yay!-) i hope that the haddock-independent part (parsing, preserving, > and accessing comments) becomes part of the GHC API in a form that would > fix trac ticket #1886, then we could finally start writing (ghc) haskell > source-to-source transformations without losing pragmas or comments! > losing layout would still be a pain, but that could be dealt with > later - at least the code would remain functional under some > form of (pretty . id . parse). Hmm. When it comes Haddock, things are simpler than in a refactoring situation, since we don't need to know exactly where the comments appear in the concrete syntax. The original Haddock parser is very liberal in where you can place comments. For example, it doesn't matter if you place a comment before or after a comma in a record field list, it is still attached to the previous (or next, depending on the type of comment) field. I need to take another look at the grammar to confirm that this is true in general, though. But anyway, my plan was to do this entirely in Haddock, not do the "preserving" part that you mention, and not do anything to GHC. David David From byorgey at gmail.com Fri May 2 11:38:06 2008 From: byorgey at gmail.com (Brent Yorgey) Date: Fri May 2 11:32:27 2008 Subject: [Haskell-cafe] elementary Maybe Monad problem .. sigh In-Reply-To: <5ae4f2ba0805011818y2fb6ec38y53e4d46614076449@mail.gmail.com> References: <5ae4f2ba0805011742j5f5d99e8gb1b7c85e5b6b5b57@mail.gmail.com> <7ca3f0160805011750k85e5c72y7336f6301e89abb9@mail.gmail.com> <5ae4f2ba0805011818y2fb6ec38y53e4d46614076449@mail.gmail.com> Message-ID: <22fcbd520805020838v1a0264adtb99676b72ded8d5c@mail.gmail.com> 2008/5/1 Galchin, Vasili : > Sorry .. my example was bad. I want to use "x" .. in then branch where > it occur ... > > e.g. > bonzo :: Maybe Bozo -> IO () > bonzo maybe_bozo = do > case maybe_bozo of > Just (Bozo x) -> x ........ > _ -> ......... > > ?? > Sure, after pattern-matching on the x (using a case, or a top-level pattern match), you are free to use x in the resulting branch. For example: bonzo (Just (Bozo x)) = print (show x) >> return x -- or whatever bonzo Nothing = return () -Brent -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080502/d68c8d11/attachment.htm From byorgey at gmail.com Fri May 2 11:45:21 2008 From: byorgey at gmail.com (Brent Yorgey) Date: Fri May 2 11:39:40 2008 Subject: [Haskell-cafe] Re: Function Type Calculation (Take 2) In-Reply-To: <7.0.1.0.0.20080502084159.01d2a3e0@ntlworld.com> References: <7.0.1.0.0.20080502084159.01d2a3e0@ntlworld.com> Message-ID: <22fcbd520805020845m64057ed4gd15340c370209fdb@mail.gmail.com> > unification > f :: a = h = (e -> d -> c) > x b = d > > No. x :: b = d (a typo?) > Paul: What's wrong with x being of type b and of type d? > Could you perhaps explain the error please? > Nothing's wrong, you just forgot a ::, that is, you wrote x b = d instead of x :: b = d. > > > Don't forget also that > > funk :: a -> b -> c = h -> e, > > which means that e = b -> c > Paul: is that something to do with partial application? > (funk f) is a partially applied function, correct? Again an explanation > would be appreciated. > It's because function arrows associate to the right, so a -> b -> c is really shorthand for (a -> (b -> c)). If (a -> (b -> c)) = h -> e, then a = h and (b -> c) = e. -Brent -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080502/32e97ed3/attachment.htm From antonmuhin at gmail.com Fri May 2 14:00:28 2008 From: antonmuhin at gmail.com (anton muhin) Date: Fri May 2 13:54:52 2008 Subject: [Haskell-cafe] Understanding tail recursion and trees In-Reply-To: <20080501120932.GB29147@netsoc.tcd.ie> References: <20080501120932.GB29147@netsoc.tcd.ie> Message-ID: <5953a1d00805021100h4d00633en24b06842eaf2b5be@mail.gmail.com> Well, if you could change your data structure, probably something like this could work (in spirit of Daniil's response): module Main where data Tree = Tree { parent :: Maybe (Either Tree Tree) , left :: Maybe Tree , right :: Maybe Tree } buildTree :: (a -> (Maybe a, Maybe a)) -> a -> Tree buildTree f = buildTree' Nothing where buildTree' p a = let t = Tree { parent = p, left = mkP Left t l, right = mkP Right t r } in t where (l, r) = f a mkP f t v = fmap (buildTree' (Just $ f t)) v leftmost :: Tree -> Tree leftmost tree = maybe tree leftmost (left tree) up :: Tree -> Maybe Tree up tree = maybe Nothing (either Just up) (parent tree) next :: Tree -> Maybe Tree next tree = maybe (up tree) (Just . leftmost) (right tree) nodes :: Tree -> Int nodes = f 0 . Just . leftmost where f n = maybe n ((f $! (n + 1)) . next) mkBalanced :: Int -> Tree mkBalanced = buildTree f where f 0 = (Nothing, Nothing) f n = (Just (n - 1), Just (n - 1)) mkLeftist :: Int -> Tree mkLeftist = buildTree f where f 0 = (Nothing, Nothing) f n = (Just (n - 1), Nothing) mkRightist :: Int -> Tree mkRightist = buildTree f where f 0 = (Nothing, Nothing) f n = (Nothing, Just (n - 1)) test v = do putStrLn "..." print $ nodes v main = do test $ mkLeftist 2000000 test $ mkRightist 2000000 test $ mkBalanced 20 yours, anton. On Thu, May 1, 2008 at 4:09 PM, Edsko de Vries wrote: > Hi, > > I am writing a simple compiler for a small DSL embedded in Haskell, and > am struggling to identify and remove the source of a stack error when > compiling larger examples. To understand the issues better, I was > playing around with tail recursion on trees when I came across the > following problem. > > Suppose we want to count the number of leaves in a tree. The obvious > naive (non tail-recursive) will run out of stack space quickly on larger > trees. To test this, I defined a function that generates left (gentreeL, > code below) or right (gentreeR) biased trees, that look like > > * * > / \ / \ > * * * * > / \ / \ > * * * * > . . > . . > n n > > respectively; that is, a tree of depth n, with on the right (or the > left) leaves only). > > Now, we can define define two traversals: one that has a tail call for > the left subtree, after having traversed the right (acountL, below); and > one that has a tail call for the right subtree, after having traversed > the left (acountR). > > I was expecting acountL to work on the left biased tree but not on the > right biased tree -- and that assumption turned out to be correct. > However, I was also expecting (by "duality" :) acountR to work on the > right biased tree, but not on the left biased tree, whereas in fact it > works on both! (Indeed, it works on reallybigtree3, which combines the > left and right biased trees, as well.) > > Can anyone explain why this is happening? Why is acountR not running out > of stack space on the left biased tree? > > Also, if this is quirk rather than something I can rely on, is there a > way to write a function that can count the number of leaves in > reallybigtree3 without running out of stack space? > > Thanks (code follows), > > Edsko > > > data Tree = Leaf Integer | Branch Tree Tree > > > -- naive count > > ncount :: Tree -> Integer > > ncount (Leaf _) = 1 > > ncount (Branch t1 t2) = ncount t1 + ncount t2 > > > -- generate left-biased tree (right nodes are always single leaves) > > gentreeL :: Integer -> Tree > > gentreeL 0 = Leaf 0 > > gentreeL n = Branch (gentreeL (n-1)) (Leaf 0) > > > > -- generate right-based tree (left nodes are always single leaves) > > gentreeR :: Integer -> Tree > > gentreeR 0 = Leaf 0 > > gentreeR n = Branch (Leaf 0) (gentreeR (n-1)) > > > > -- test examples > > reallybigtree1 = gentreeL 2000000 > > reallybigtree2 = gentreeR 2000000 > > reallybigtree3 = Branch (gentreeL 2000000) (gentreeR 2000000) > > > > -- count with tail calls for the left subtree > > acountL :: Tree -> Integer -> Integer > > acountL (Leaf _) acc = acc + 1 > > acountL (Branch t1 t2) acc = acountL t1 $! (acountL t2 acc) > > > > -- count with tail calls for the right subtree > > acountR :: Tree -> Integer -> Integer > > acountR (Leaf _) acc = acc + 1 > > acountR (Branch t1 t2) acc = acountR t2 $! (acountL t1 acc) > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From keith at oreilly.com Fri May 2 16:00:44 2008 From: keith at oreilly.com (Keith Fahlgren) Date: Fri May 2 15:55:05 2008 Subject: [Haskell-cafe] [ANN] Next Bay FP Meeting: Bryan O'Sullivan on Concurrent and multicore programming in Haskell Message-ID: <481B72EC.3070502@oreilly.com> Hi, Our next BayFP meeting will be this Thursday, May 8th, 2008 at 7:30pm. We'll feature Bryan O'Sullivan on Concurrent and multicore programming in Haskell. Bryan is a co-author of the upcoming O'Reilly book Real World Haskell [http://book.realworldhaskell.org/]. (among all sorts of other snazzy endeavors) Talking about multicore is all the rage, so I expect folks to bring a lot of people! :-) Details here: http://www.bayfp.org/blog/2008/05/02/may-8th-meeting-bryan-osullivan-on-concurrent-and-multicore-programming-in-haskell/ Many thanks to Alex Payne at Twitter for hosting this month's meeting. They've been very supportive of BayFP and we appreciate their continued hosting. Twitter's address is: 164 South Park St San Francisco, CA 94107 Alex says: It's a building with a dark green door. People can just come on in and walk to their right to a large conference room. We'll start at 7:30pm. As always, this is a free event. If you want pizza, please select which type here (and bring a few $$s): Pizza Selection Form [http://bayfp.wufoo.com/forms/bryan-osullivan-bay-fp/] Keith From mads_lindstroem at yahoo.dk Fri May 2 16:31:59 2008 From: mads_lindstroem at yahoo.dk (Mads =?ISO-8859-1?Q?Lindstr=F8m?=) Date: Fri May 2 16:29:16 2008 Subject: [Haskell-cafe] Using Template Haskell to make type-safe database access Message-ID: <1209760319.4242.4.camel@localhost.localdomain> Hi, I was wondering if anybody had experimented with using Template Haskell (TH) and ordinary SQL to make type-safe database access? To clarify what I am thinking about I will sketch how it could be done. The TH function should take two inputs. SQL (as a string) and a database source name (DSN). It should return an IO action as output. The TH-function should: 1. Connect to the database using the DSN 2. Ask the database which types will be returned from the expression 3. Build an IO action which can be used to execute the SQL at run-time. The action could return the result as a (lazy) list. Due to step two we can make the returned values type-safe. Greetings, Mads Lindstr?m From midfield at gmail.com Fri May 2 21:13:48 2008 From: midfield at gmail.com (Ben) Date: Fri May 2 21:08:08 2008 Subject: [Haskell-cafe] castIOUArray and hPutArray redux Message-ID: <9157df230805021813lee5ddf1la5755eb7d128d537@mail.gmail.com> hi haskellers, have the issues with castIOUArray (and thus hGetArray, hPutArray) in Data.Array.IO discussed below been resolved? http://www.haskell.org/pipermail/libraries/2003-January/thread.html here is a (trivial) program which has rather unexpected behavior. (i'm switching to Data.Binary in the meantime.) import Data.Array.IO import System.IO (IOMode(..), openBinaryFile, hClose) dumpArray arr name = do h <- openBinaryFile name WriteMode w <- castIOUArray arr (l,u) <- getBounds w let len = u-1+1 hPutArray h w len hClose h return len loadArray name num = do arr <- newArray_ (1, num) h <- openBinaryFile name ReadMode read <- hGetArray h arr num if not(read == num) then error "Incorrect number of bytes read in from array!" else return arr len = 20 main = do arr <- newArray (1, len) 1::IO(IOUArray Int Int) size <- dumpArray arr "foo" arr2' <- loadArray "foo" size arr2 <- (castIOUArray arr2')::IO(IOUArray Int Int) e1 <- getElems arr e2 <- getElems arr2 print e1 print e2 print size print $ show (arr == arr2) best, b From dons at galois.com Fri May 2 21:16:32 2008 From: dons at galois.com (Don Stewart) Date: Fri May 2 21:10:55 2008 Subject: [Haskell-cafe] castIOUArray and hPutArray redux In-Reply-To: <9157df230805021813lee5ddf1la5755eb7d128d537@mail.gmail.com> References: <9157df230805021813lee5ddf1la5755eb7d128d537@mail.gmail.com> Message-ID: <20080503011632.GA17863@scytale.galois.com> midfield: > hi haskellers, > > have the issues with castIOUArray (and thus hGetArray, hPutArray) in > Data.Array.IO discussed below been resolved? > > http://www.haskell.org/pipermail/libraries/2003-January/thread.html > > here is a (trivial) program which has rather unexpected behavior. > (i'm switching to Data.Binary in the meantime.) Could you clarify what benefit the low level direct array IO has over Data.Binary? -- Don (thinking about how to best do IO for a new arrays library) From midfield at gmail.com Fri May 2 21:39:41 2008 From: midfield at gmail.com (Ben) Date: Fri May 2 21:34:01 2008 Subject: [Haskell-cafe] castIOUArray and hPutArray redux In-Reply-To: <20080503011632.GA17863@scytale.galois.com> References: <9157df230805021813lee5ddf1la5755eb7d128d537@mail.gmail.com> <20080503011632.GA17863@scytale.galois.com> Message-ID: <9157df230805021839x644fd2fan546cfeae36525acd@mail.gmail.com> hi there, i assume you're asking about benefits with respect to serialization? other than some performance hacks, probably none. there was no good reason for me to use hPutArray and the like, i just saw them in the API docs and decided to try them out -- and got burned! Data.Binary has worked great for me so far. take care, ben On 5/2/08, Don Stewart wrote: > midfield: > > > hi haskellers, > > > > have the issues with castIOUArray (and thus hGetArray, hPutArray) in > > Data.Array.IO discussed below been resolved? > > > > http://www.haskell.org/pipermail/libraries/2003-January/thread.html > > > > here is a (trivial) program which has rather unexpected behavior. > > (i'm switching to Data.Binary in the meantime.) > > > Could you clarify what benefit the low level direct array IO has over Data.Binary? > > -- Don (thinking about how to best do IO for a new arrays library) > From j.vimal at gmail.com Fri May 2 23:50:52 2008 From: j.vimal at gmail.com (Vimal) Date: Fri May 2 23:45:17 2008 Subject: [Haskell-cafe] [ANN] Next Bay FP Meeting: Bryan O'Sullivan on Concurrent and multicore programming in Haskell In-Reply-To: <481B72EC.3070502@oreilly.com> References: <481B72EC.3070502@oreilly.com> Message-ID: On 03/05/2008, Keith Fahlgren wrote: > Hi, > > > Our next BayFP meeting will be this Thursday, May 8th, 2008 at 7:30pm. > We'll feature Bryan O'Sullivan on Concurrent and multicore programming > in Haskell. Bryan is a co-author of the upcoming O'Reilly book Real Cant wait for the video! How long before the video comes up on the website? -- Vimal From bulat.ziganshin at gmail.com Sat May 3 01:31:44 2008 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Sat May 3 01:34:28 2008 Subject: [Haskell-cafe] castIOUArray and hPutArray redux In-Reply-To: <9157df230805021813lee5ddf1la5755eb7d128d537@mail.gmail.com> References: <9157df230805021813lee5ddf1la5755eb7d128d537@mail.gmail.com> Message-ID: <1637126257.20080503093144@gmail.com> Hello Ben, Saturday, May 3, 2008, 5:13:48 AM, you wrote: > have the issues with castIOUArray (and thus hGetArray, hPutArray) in > Data.Array.IO discussed below been resolved? there is alternative arrays library [1], where bounds are recalculated when casting [1] http://haskell.org/haskellwiki/Library/ArrayRef -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From dave at zednenem.com Sat May 3 02:21:40 2008 From: dave at zednenem.com (David Menendez) Date: Sat May 3 02:15:58 2008 Subject: [Haskell-cafe] Re: Understanding tail recursion and trees In-Reply-To: <481A23CA.3020903@gmail.com> References: <20080501123236.GC29147@netsoc.tcd.ie> <481A23CA.3020903@gmail.com> Message-ID: <49a77b7a0805022321w76935b0bl5be07e24d4441b46@mail.gmail.com> On Thu, May 1, 2008 at 4:10 PM, Daniil Elovkov wrote: > Felipe Lessa wrote: > > > On Thu, May 1, 2008 at 9:44 AM, Felipe Lessa > wrote: > > > > > On Thu, May 1, 2008 at 9:32 AM, Edsko de Vries > wrote: > > > > So then the question becomes: what *is* the best way to write this > function? > > > > > > I guess it would be simpler to have the counter on the data type and a > > > smart branch constructor: > > > > > > > Under more careful analysis, it seems I just moved the stack overflow > > from the counter function to the generator =). Modifying the data type > > to > > > > > > > data Tree = Leaf Integer | Branch !Integer Tree Tree > > > > > > > also won't work in this example (although it seems to fail earlier). > > However, I'd expect the data type above to work nicely with most real > > applications (that doesn't construct the entire tree in one go), such > > as Data.Map[1]. > > > > But the answer to your original question really seems to be using an > > explicit stack created in the heap. This technique is used in Data.Map > > in a certain case[2] and, although has received a lot of attention on > > a thread that sparked some time ago (I think it was [3]) for being > > merely a workaround over the limited stack, it seems to me it's a > > compulsory workaround for the time being when working with problems > > like yours. > > > > > > I think that consuming heap instead of stack is the best we can do. > > I may be wrong, but it seems to be more or less impossible to traverse a > tree in constant memory. Well, if the tree structure doesn't have back links > (apart from left, right). I think Huet's Zipper is intended to solve this sort of problem. data Path = Top | BranchL Path Tree | BranchR Tree Path type Zipper = (Path, Tree) openZipper :: Tree -> Zipper openZipper t = (Top, t) Conceptually the zipper is a tree with one subtree selected. You can move the selection point with the (partial) functions defined below. downL, downR, up :: Zipper -> Zipper downL (p, Branch l r) = (BranchL p r, l) downR (p, Branch l r) = (BranchR l p, r) up (BranchL p r, l) = (p, Branch l r) up (BranchR l p, r) = (p, Branch l r) Note that these functions just shuffle existing subtrees around. Depending on your traversal pattern, these can run in roughly constant space. Using the zipper, we can define functions that traverse the entire tree and return a new tree: number :: Tree -> Tree number t = down Top t 0 where down p (Leaf _) n = up p (Leaf n) $! n + 1 down p (Branch l r) n = down (BranchL p r) l n up Top t n = t up (BranchL p r) l n = down (BranchR l p) r n up (BranchR l p) r n = up p (Branch l r) n For something like counting, we can simplify considerably because we don't need to retain the already-traversed portion of the tree. acountZ :: Tree -> Integer acountZ t = down t [] 0 where down (Branch l r) p i = down l (r:p) i down (Leaf _) (p:ps) i = down p ps $! i + 1 down (Leaf _) [] i = i + 1 -- Dave Menendez From bd at fushizen.net Sat May 3 05:19:17 2008 From: bd at fushizen.net (Bryan Donlan) Date: Sat May 3 05:13:40 2008 Subject: [Haskell-cafe] Control.Exception.evaluate - 'correct definition' not so correct Message-ID: <20080503091917.GA5333@shion.is.fushizen.net> Hi all, After some discussion on #haskell I decided to bring this issue to haskell-cafe. GHC's documentation for Control.Exception.evaluate states: evaluate :: a -> IO a Forces its argument to be evaluated when the resultant IO action is executed. It can be used to order evaluation with respect to other IO operations; its semantics are given by evaluate x `seq` y ==> y evaluate x `catch` f ==> (return $! x) `catch` f evaluate x >>= f ==> (return $! x) >>= f Note: the first equation implies that (evaluate x) is not the same as (return $! x). A correct definition is evaluate x = (return $! x) >>= return However, if >>= is strict on its first argument, then this definition is no better than (return $! x). One might next consider: evaluate x = (return x) >>= (return $!) However, according to the monad laws, this is equivalent to: evaluate x = return $! x and we're back to where we started. Although GHC's implementation of IO is somewhat more relaxed about this, there is no guarentee that this will be the case in all IO implementations, or future versions of GHC, or different optimization flags, or... The best I've come up with so far is: evaluate x = newIORef (return $! x) >>= join . readIORef In any case, if >>= is to be guarenteed lazy, this ought to be documented somewhere (or is it?). Otherwise Control.Exception's docs should be updated to provide a more correct example and/or the caveat that >>= must not be left-strict for the example implementation to be correct. Thanks, Bryan Donlan -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 827 bytes Desc: Digital signature Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20080503/c8447352/attachment.bin From apfelmus at quantentunnel.de Sat May 3 06:56:38 2008 From: apfelmus at quantentunnel.de (apfelmus) Date: Sat May 3 06:51:15 2008 Subject: [Haskell-cafe] Re: Control.Exception.evaluate - 'correct definition' not so correct In-Reply-To: <20080503091917.GA5333@shion.is.fushizen.net> References: <20080503091917.GA5333@shion.is.fushizen.net> Message-ID: Bryan Donlan wrote: > > evaluate x = (return $! x) >>= return > > However, if >>= is strict on its first argument, then this definition is > no better than (return $! x). According to the monad law f >>= return = f every (>>=) ought to be strict in its first argument, so it indeed seems that the implementation given in the documentation is wrong. Regards, apfelmus From jules at jellybean.co.uk Sat May 3 07:21:40 2008 From: jules at jellybean.co.uk (Jules Bean) Date: Sat May 3 07:16:02 2008 Subject: [Haskell-cafe] Re: Control.Exception.evaluate - 'correct definition' not so correct In-Reply-To: References: <20080503091917.GA5333@shion.is.fushizen.net> Message-ID: <481C4AC4.1000909@jellybean.co.uk> apfelmus wrote: > Bryan Donlan wrote: >> >> evaluate x = (return $! x) >>= return >> >> However, if >>= is strict on its first argument, then this definition is >> no better than (return $! x). > > According to the monad law > > f >>= return = f > > every (>>=) ought to be strict in its first argument, so it indeed seems > that the implementation given in the documentation is wrong. But it is known that the monad laws only apply up to some weaker equivalence than 'seq-equivalence'. This has been discussed here countless times by people who understand it better than me. As I understand the summary the "=" sign in the monad laws mean "represent identical actions, in terms of the effects produced and the result returned". A kind of observational-equivalence for monad execution, but weaker than direct equational equivalence in the presence of seq. (Some people view this as more of a bug in "seq" than in the monad laws) Jules From devriese at cs.tcd.ie Sat May 3 12:30:01 2008 From: devriese at cs.tcd.ie (Edsko de Vries) Date: Sat May 3 12:24:22 2008 Subject: [Haskell-cafe] Re: Understanding tail recursion and trees In-Reply-To: <49a77b7a0805022321w76935b0bl5be07e24d4441b46@mail.gmail.com> References: <20080501123236.GC29147@netsoc.tcd.ie> <481A23CA.3020903@gmail.com> <49a77b7a0805022321w76935b0bl5be07e24d4441b46@mail.gmail.com> Message-ID: <20080503163000.GA2192@netsoc.tcd.ie> Hi, > I think Huet's Zipper is intended to solve this sort of problem. > > data Path = Top | BranchL Path Tree | BranchR Tree Path > type Zipper = (Path, Tree) > > openZipper :: Tree -> Zipper > openZipper t = (Top, t) > > Conceptually the zipper is a tree with one subtree selected. You can > move the selection point with the (partial) functions defined below. > > downL, downR, up :: Zipper -> Zipper > downL (p, Branch l r) = (BranchL p r, l) > downR (p, Branch l r) = (BranchR l p, r) > up (BranchL p r, l) = (p, Branch l r) > up (BranchR l p, r) = (p, Branch l r) > > Note that these functions just shuffle existing subtrees around. > Depending on your traversal pattern, these can run in roughly constant > space. > > Using the zipper, we can define functions that traverse the entire > tree and return a new tree: > > number :: Tree -> Tree > number t = down Top t 0 > where > down p (Leaf _) n = up p (Leaf n) $! n + 1 > down p (Branch l r) n = down (BranchL p r) l n > > up Top t n = t > up (BranchL p r) l n = down (BranchR l p) r n > up (BranchR l p) r n = up p (Branch l r) n Please correct me if I'm wrong, but doesn't the the size of the zipper grow every time we move down the left branch? I.e., by the time we reach the leaf, we'll have a zipper (BranchL (BranchL ..)) of size the depth of the tree? Or am I missing something? Edsko From dave at zednenem.com Sat May 3 14:20:59 2008 From: dave at zednenem.com (David Menendez) Date: Sat May 3 14:15:17 2008 Subject: [Haskell-cafe] Re: Understanding tail recursion and trees In-Reply-To: <20080503163000.GA2192@netsoc.tcd.ie> References: <20080501123236.GC29147@netsoc.tcd.ie> <481A23CA.3020903@gmail.com> <49a77b7a0805022321w76935b0bl5be07e24d4441b46@mail.gmail.com> <20080503163000.GA2192@netsoc.tcd.ie> Message-ID: <49a77b7a0805031120r29ab2521m3160156c1f18b33@mail.gmail.com> On Sat, May 3, 2008 at 12:30 PM, Edsko de Vries wrote: > > > I think Huet's Zipper is intended to solve this sort of problem. > > > > data Path = Top | BranchL Path Tree | BranchR Tree Path > > type Zipper = (Path, Tree) > > > > openZipper :: Tree -> Zipper > > openZipper t = (Top, t) > > > > Conceptually the zipper is a tree with one subtree selected. You can > > move the selection point with the (partial) functions defined below. > > > > downL, downR, up :: Zipper -> Zipper > > downL (p, Branch l r) = (BranchL p r, l) > > downR (p, Branch l r) = (BranchR l p, r) > > up (BranchL p r, l) = (p, Branch l r) > > up (BranchR l p, r) = (p, Branch l r) > > > > Note that these functions just shuffle existing subtrees around. > > Depending on your traversal pattern, these can run in roughly constant > > space. > > > > Using the zipper, we can define functions that traverse the entire > > tree and return a new tree: > > > > number :: Tree -> Tree > > number t = down Top t 0 > > where > > down p (Leaf _) n = up p (Leaf n) $! n + 1 > > down p (Branch l r) n = down (BranchL p r) l n > > > > up Top t n = t > > up (BranchL p r) l n = down (BranchR l p) r n > > up (BranchR l p) r n = up p (Branch l r) n > > Please correct me if I'm wrong, but doesn't the the size of the zipper > grow every time we move down the left branch? I.e., by the time we reach > the leaf, we'll have a zipper (BranchL (BranchL ..)) of size the depth > of the tree? Or am I missing something? If there are no other references to the tree, then each time a new node in the zipper is created, the corresponding node in the original tree can be discarded. Typically, the garbage won't be collected immediately, so there will be some growth in actual memory usage, but this will be bounded. If there are other references to the tree, then the nodes in the original tree cannot be reclaimed. Even so, the zipper never grows in size beyond the longest path from root to leaf in the tree. -- Dave Menendez From keith at oreilly.com Sat May 3 14:43:37 2008 From: keith at oreilly.com (Keith Fahlgren) Date: Sat May 3 14:37:56 2008 Subject: [Haskell-cafe] [ANN] Next Bay FP Meeting: Bryan O'Sullivan on Concurrent and multicore programming in Haskell In-Reply-To: References: <481B72EC.3070502@oreilly.com> Message-ID: <481CB259.5030002@oreilly.com> On 5/2/08 8:50 PM, Vimal wrote: > On 03/05/2008, Keith Fahlgren wrote: >> Hi, >> >> >> Our next BayFP meeting will be this Thursday, May 8th, 2008 at 7:30pm. >> We'll feature Bryan O'Sullivan on Concurrent and multicore programming >> in Haskell. Bryan is a co-author of the upcoming O'Reilly book Real > > Cant wait for the video! How long before the video comes up on the website? We've typically been able to get videos up after about a week. Keith From nahuelrullo at gmail.com Sun May 4 02:12:41 2008 From: nahuelrullo at gmail.com (Nahuel Rullo) Date: Sun May 4 02:07:01 2008 Subject: [Haskell-cafe] Haskell PNG Writer Message-ID: Hi list, i am new in Haskell. I need to make images (PNG, JPEG) with haskell, if you can give me a tutorial, thanks! -- Nahuel Rullo From andrewcoppin at btinternet.com Sun May 4 04:47:31 2008 From: andrewcoppin at btinternet.com (Andrew Coppin) Date: Sun May 4 04:41:47 2008 Subject: [Haskell-cafe] Haskell PNG Writer In-Reply-To: References: Message-ID: <481D7823.9010306@btinternet.com> Nahuel Rullo wrote: > Hi list, i am new in Haskell. I need to make images (PNG, JPEG) with > haskell, if you can give me a tutorial, thanks! > Gtk2hs has the ability to read and write PNG and JPEG images. Have a look at the Graphics.UI.Gtk.Gdk.Pixbuf module: http://www.haskell.org/gtk2hs/docs/gtk2hs-docs-0.9.12/Graphics-UI-Gtk-Gdk-Pixbuf.html Specifically, look at pixbufNewFromFile and pixbufSave. If you then take a look at the Graphics.UI.Gtk.Gdk.Drawable module, you'll see a bunch of functions for drawing onto a Pixbuf. (Alternatively you can use Cairo.) However, if you're trying to draw an algorithmically generated set of pixels, you'll probably want to manipulate the underlying bitmap directly. This is Not Fun. Take a look at the QuickDraw demo to see how it's done... HTH. From lrpalmer at gmail.com Sun May 4 05:03:26 2008 From: lrpalmer at gmail.com (Luke Palmer) Date: Sun May 4 04:57:44 2008 Subject: [Haskell-cafe] Haskell PNG Writer In-Reply-To: References: Message-ID: <7ca3f0160805040203yaf9217ch85fc2b1fbad7379@mail.gmail.com> SDL-image (http://hackage.haskell.org/cgi-bin/hackage-scripts/package/SDL-image-0.5.2) also supports this. Luke On Sun, May 4, 2008 at 12:12 AM, Nahuel Rullo wrote: > Hi list, i am new in Haskell. I need to make images (PNG, JPEG) with > haskell, if you can give me a tutorial, thanks! > > -- > Nahuel Rullo > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > From hthiel.char at zonnet.nl Sun May 4 07:46:51 2008 From: hthiel.char at zonnet.nl (Hans van Thiel) Date: Sun May 4 07:43:09 2008 Subject: [Haskell-cafe] Haskell PNG Writer In-Reply-To: References: Message-ID: <1209901611.2792.3.camel@localhost.localdomain> On Sun, 2008-05-04 at 03:12 -0300, Nahuel Rullo wrote: > Hi list, i am new in Haskell. I need to make images (PNG, JPEG) with > haskell, if you can give me a tutorial, thanks! I don't know about jpeg, but for png (with Cairo) see: http://darcs.haskell.org/gtk2hs/docs/tutorial/Tutorial_Port/app1.xhtml Regards, Hans van Thiel From byorgey at gmail.com Sun May 4 07:57:12 2008 From: byorgey at gmail.com (Brent Yorgey) Date: Sun May 4 07:51:27 2008 Subject: [Haskell-cafe] Haskell PNG Writer In-Reply-To: References: Message-ID: <22fcbd520805040457o2e11b22cgfbb285879f3e5c6d@mail.gmail.com> On Sun, May 4, 2008 at 2:12 AM, Nahuel Rullo wrote: > Hi list, i am new in Haskell. I need to make images (PNG, JPEG) with > haskell, if you can give me a tutorial, thanks! > What kind of images do you need to make? -Brent -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080504/db27ec57/attachment.htm From amarquaye.ivan at hotmail.com Sun May 4 08:24:04 2008 From: amarquaye.ivan at hotmail.com (Ivan Amarquaye) Date: Sun May 4 08:18:19 2008 Subject: [Haskell-cafe] really difficult for a beginner like me... In-Reply-To: References: Message-ID: Hi everyone, this is my first posting on here and this was what drove me here and the quest to know more as i anticipate a lot of help and direction in this quite new and different environment haskell.I have this paper that i'm working on and need to solve these scenarios/ cases based on some sample codes: Scenarios/cases: 1) Allow words to be hyphenated and treat the hyphenated word as a single word (including the hyphen). 2) As for no. 2 but if the hyphen is the last character on a line treat the hyphenated word as a single word without the hyphen. 3) Treat a capitalised word (one or more capital letters) the same as lower case, i.e. only the lower case word appears in the index. 4) Treat a word ending in an ?s? as a plural and thus the same as the singular, i.e. only the singular appears in the index. 5) As for no. 5 but (a) treat suffix ?ss? as not a plural; and (b) treat the plural suffixes ?sses?, ?zzes?, ?oes?, ?xes?, ?shes?, ?ches? the same as the singular, i.e. without the ?es?, e.g. ?branches? (except for 4- and 5-letter plurals with suffices ?oes? and ?ches?, e.g. ?floes?, and 4-letter plural suffix ?xes?); and (c) treat the plural suffix ?ies? (except for 4-letter plurals, e.g. ?pies?) as the singular suffix ?y?. 6) Make the output more readable in the form of an index table. 7) Use an output file 8) Include a user-friendly menu by which the user can choose input and output file names. This is the code i'm supposed tomodify and in some cases create new functions to support.I also need some explanation as the various approaches in solving them.............................................................................................. The function makeIndex given a document produces a list of entries. Each entry is a word and a list of line numbers (for words > 4 letters) Type definitions: import Prelude -- hiding (Word) -- predefined Word hidden, so we can define ours -- type String = [Char] defined in Prelude type Doc = String type Line = String type Word = String -- our version makeIndex :: Doc -> [ ([Int], Word) ] A data-directed design considers a sequence of functions (i.e using composition operator ?.?) to transform the document of type, Doc, into an index of type, [ ([Int], Word) ]. splitUp the document, doc, into a list of lines, [Line]. numLines pairs each line with a line number, [(Int, Line)]. allNumWords splits lines into words and line no., [(Int, Word)]. sortLs sorts words into alphabetical order, [(Int, Word)]. makeLists makes a list for each line number, [([Int], Word)]. amalgamate nos. into a list of nos. for each word, [([Int], Word)]. shorten into a list for words > 4 letters, [([Int], Word)]. makeIndex = shorten . -- [([Int], Word)] -> [([Int], Word)] amalgamate . -- [([Int], Word)] -> [([Int], Word)] makeLists . -- [(Int, Word)] -> [([Int], Word)] sortLs . -- [(Int, Word)] -> [(Int, Word)] allNumWords . -- [(Int, Line)] -> [(Int, Word)] numLines . -- [Line] -> [(Int, Line)] splitUp -- Doc -> [Line] Last -- [a] -> [a ] splitUp function splitUp :: Doc -> [Line] splitUp [] = [] splitUp text = takeWhile (/='\n') text : -- first line (splitUp . -- splitup other lines dropWhile (==?\n?) . -- delete 1st newline(s) dropWhile (/='\n')) text -- other lines Example: splitUp ?hello world\n\nnext world? => [?hello world?, ?next world?] numLines function: numLines :: [Line] -> [(Int, Line)] numLines lines -- list of pairs of = zip [1 .. length lines] lines -- line no. & line Example: numLines [?hello world?, ?next world?] => [(1, ?hello world?), (2, ?next world?)] splitWords function: -- for each line -- a) split into words -- b) attach line no. to each word splitWords :: Line -> [Word] -- a) splitWords [ ] = [ ] splitWords line = takeWhile isLetter line : -- first word in line (splitWords . -- split other words dropWhile (not.isLetter && Last ==?-?) . -- delete separators dropWhile isLetter) line -- other words where isLetter ch = (?a?<=ch) && (ch<=?z?) || (?A?<=ch) && (ch<=?Z?) Example: splitWords ?hello world? => [?hello?, ?world?] allNumWords function: numWords :: (Int, Line) -> [(Int, Word)] -- b) numWords (number, line) = map addLineNum ( splitWords line) -- all line pairs where addLineNum word = (number, word) -- a pair allNumWords :: [(Int, Line)] -> [(Int, Word)] allNumWords = concat . map numWords -- doc pairs Examples: addLineNum ?hello? => (1, ?hello?) numWords (1, ?hello world?) => [(1, ?hello?), (1, ?world?)] allNumWords [(1, ?hello world?), (2, ?next world?)] => [(1, ?hello?), (1, ?world?), (2, ?next?), (2, ?world?)] SortLs function: sortLs :: [(Int, Word)] -> [(Int, Word)] sortLs [ ] = [ ] sortLs (a:x) = sortLs [b | b <- x, compare b a] -- sort 1st half ++ [a] ++ -- 1st in middle sortLs [b | b <- x, compare a b] -- sort 2nd half where compare (n1, w1) (n2, w2) = (w1 < w2) -- 1st word less || (w1 == w2 && n1 < n2) -- check no. Example: sortLs [(1, ?hello?), (1, ?world?), (2, ?next?), (2, ?world?)] => [(1, ?hello?), (2, ?next?), (1, ?world?), (2, ?world?)] makeLists function: makeLists :: [(Int, Word)] -> [([Int], Word)] makeLists = map mk -- all pairs where mk (num, word) = ([num], word) -- list of single no. Examples: mk (1, ?hello?) => ([1], ?hello?) makeLists [(1, ?hello?), (2, ?next?), (1, ?world?), (2, ?world?)] => [([1], ?hello?), ([2], ?next?), ([1], ?world?), ([2], ?world?)] Amalgamate function: amalgamate :: [([Int], Word)] -> [([Int], Word)] amalgamate [ ] = [ ] amalgamate [a] = [a] amalgamate ((n1, w1) : (n2, w2) : rest) -- pairs of pairs | w1 /= w2 = (n1, w1) : amalgamate ((n2, w2) : rest) | otherwise = amalgamate ((n1 ++ n2, w1) : rest) -- if words are same grow list of numbers Example: amalgamate [([1], ?hello?), ([2], ?next?), ([1], ?world?), ([2], ?world?)] => [([1], ?hello?), ([2], ?next?), ([1, 2], ?world?)] Shorten function: shorten :: [([Int], Word)] -> [([Int], Word)] shorten = filter long -- keep pairs >4 where long (num, word) = length word > 4 -- check word >4 Example: shorten [([1], ?hello?), ([2], ?next?), ([1, 2], ?world?)] => [([1], ?hello?), ([1, 2], ?world?)] _________________________________________________________________ Connect to the next generation of MSN Messenger? http://imagine-msn.com/messenger/launch80/default.aspx?locale=en-us&source=wlmailtagline -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080504/6d99c75c/attachment.htm From lrpalmer at gmail.com Sun May 4 08:53:24 2008 From: lrpalmer at gmail.com (Luke Palmer) Date: Sun May 4 08:47:42 2008 Subject: [Haskell-cafe] really difficult for a beginner like me... In-Reply-To: References: Message-ID: <7ca3f0160805040553m34cc441ekaf8a1d5feb82c@mail.gmail.com> 2008/5/4 Ivan Amarquaye : > Hi everyone, > > this is my first posting on here and this was what drove me here and the > quest to know more as i anticipate a lot of help and direction in this quite > new and different environment haskell.I have this paper that i'm working on > and need to solve these scenarios/ cases based on some sample codes: You might receive better help if you asked smaller, more specific questions. This looks like homework, and even if it's not, we are a homework-friendly crowd, meaning: nobody is going to write code for you. We will answer questions in words, point you to useful library functions, give you feedback on approaches you outline to us, etc. So break up the problem. Try no. 1 by yourself, and if you can't do it, then describe what you tried and how it didn't work. Giving an outline of how you think you should approach the problem from a purely functional perspective will help, so we can help you modify and correct that idea. The more thought you put in by yourself before asking us, the more you will get out of our responses. But be much more specific. I cannot answer a question this large. Luke From amarquaye.ivan at hotmail.com Sun May 4 09:36:25 2008 From: amarquaye.ivan at hotmail.com (Ivan Amarquaye) Date: Sun May 4 09:30:40 2008 Subject: [Haskell-cafe] really difficult for a beginner like me... In-Reply-To: <7ca3f0160805040553m34cc441ekaf8a1d5feb82c@mail.gmail.com> References: <7ca3f0160805040553m34cc441ekaf8a1d5feb82c@mail.gmail.com> Message-ID: thanks for the tip there....its been four gruesome days and i just don't seem to make any understanding of how to implement some changes or create some new functions due to the fact that im so new to Haskell and functional programming. For the very first case of allowing hyphenated words to be treated as single words i manged to successfully do that by adding to the definition of the splitWords function to also accept characters such as "-" and it worked perfectly after running it. The next case posed a headache for me as i have been on it for 3 days now. >From my understanding, it means in situations where your writing a sentence and you get to the end of the line while writing a word, you decide to put a hyphen there and continue on the other line. So the case demands that i allow sentences that end with hyphens and continue on the next line to drop the hyphen and be a single word on that same line without having to continue on the next line so this was how i foresee the input it in hugs: Input: makeIndex "these are the very same stuff they tell each-\nother" output: should be this: [[1]these],[[1]eachother]. 1 indicates they are on the same line and the others are left out as the index takes words greater than 4 characters and i have been struggling with this since. i tried on several counts to include in the splitwords function to dropWhile "-" is found in the words but it turned out an error.I also tried creating a new function to do that didnt succeed either can anybody help me out in this regard..... _________________________________________________________________ Explore the seven wonders of the world http://search.msn.com/results.aspx?q=7+wonders+world&mkt=en-US&form=QBRE -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080504/b6d55880/attachment.htm From prstanley at ntlworld.com Sun May 4 11:33:34 2008 From: prstanley at ntlworld.com (PR Stanley) Date: Sun May 4 11:27:46 2008 Subject: [Haskell-cafe] unapplying function definitions? Message-ID: <7.0.1.0.0.20080504163109.01d06a38@ntlworld.com> Hi What on earth is unapplying function definitions? The following is taken from chapter 13 of the Hutton book: "...when reasoning about programs, function definitions can be both applied from left to right and unapplied from right to left." Cheers Paul From tom.davie at gmail.com Sun May 4 11:52:50 2008 From: tom.davie at gmail.com (Thomas Davie) Date: Sun May 4 11:47:08 2008 Subject: [Haskell-cafe] unapplying function definitions? In-Reply-To: <7.0.1.0.0.20080504163109.01d06a38@ntlworld.com> References: <7.0.1.0.0.20080504163109.01d06a38@ntlworld.com> Message-ID: On 4 May 2008, at 17:33, PR Stanley wrote: > Hi > What on earth is unapplying function definitions? > The following is taken from chapter 13 of the Hutton book: > "...when reasoning about programs, function definitions can be both > applied from left to right and unapplied from right to left." Well, because of referential transparency, we can say that the left hand side of a function is exactly equal to the right hand side. Thus, we can instead of applying functions, and making progress towards a normal form, unapply them and get further away from a normal form... for example: 5 = head [5,6,7,8,9] = head ([5,6] ++ [7] ++ [8,9]) = head (([] ++ [5] ++ [6]) ++ [7] ++ [8,9]) ....... There are of course an infinite number of ways of doing this, so it's usually only interesting, if we have some reason for applying a specific expansion. Bob From prstanley at ntlworld.com Sun May 4 12:48:58 2008 From: prstanley at ntlworld.com (PR Stanley) Date: Sun May 4 12:43:09 2008 Subject: [Haskell-cafe] unapplying function definitions? In-Reply-To: References: <7.0.1.0.0.20080504163109.01d06a38@ntlworld.com> Message-ID: <7.0.1.0.0.20080504174712.01d13c50@ntlworld.com> >>Hi >>What on earth is unapplying function definitions? >>The following is taken from chapter 13 of the Hutton book: >>"...when reasoning about programs, function definitions can be both >>applied from left to right and unapplied from right to left." > >Well, because of referential transparency, we can say that the left >hand side of a function is exactly equal to the right hand side. >Thus, we can instead of applying functions, and making progress >towards a normal form, unapply them and get further away from a normal >form... for example: > >5 = head [5,6,7,8,9] = head ([5,6] ++ [7] ++ [8,9]) = head (([] ++ [5] >++ [6]) ++ [7] ++ [8,9]) ....... > >There are of course an infinite number of ways of doing this, so it's >usually only interesting, if we have some reason for applying a >specific expansion. > >>What is the normal form? From byorgey at gmail.com Sun May 4 13:03:18 2008 From: byorgey at gmail.com (Brent Yorgey) Date: Sun May 4 12:57:34 2008 Subject: [Haskell-cafe] unapplying function definitions? In-Reply-To: <7.0.1.0.0.20080504174712.01d13c50@ntlworld.com> References: <7.0.1.0.0.20080504163109.01d06a38@ntlworld.com> <7.0.1.0.0.20080504174712.01d13c50@ntlworld.com> Message-ID: <22fcbd520805041003v53b4d2fdne38795c8b42596e2@mail.gmail.com> On Sun, May 4, 2008 at 12:48 PM, PR Stanley wrote: > > Hi >>> What on earth is unapplying function definitions? >>> The following is taken from chapter 13 of the Hutton book: >>> "...when reasoning about programs, function definitions can be both >>> applied from left to right and unapplied from right to left." >>> >> >> Well, because of referential transparency, we can say that the left >> hand side of a function is exactly equal to the right hand side. >> Thus, we can instead of applying functions, and making progress >> towards a normal form, unapply them and get further away from a normal >> form... for example: >> >> 5 = head [5,6,7,8,9] = head ([5,6] ++ [7] ++ [8,9]) = head (([] ++ [5] >> ++ [6]) ++ [7] ++ [8,9]) ....... >> >> There are of course an infinite number of ways of doing this, so it's >> usually only interesting, if we have some reason for applying a >> specific expansion. >> >> What is the normal form? >>> >> Essentially, a normal form is an expression where there are no more function applications that can be evaluated. For example, the expression '5' is a normal form; 'succ 5' is not a normal form since the succ can be applied to the 5, producing the normal form 6. To give another example of what Hutton means, suppose we are given the function definition head (x:xs) = x Then if we have the expression 'head (1:2:[])', noting that this matches the left-hand side of the definition of head, we can apply that definition to produce the equivalent expression '1'. Given the expression '2', on the other hand, and noting that this matches the *right*-hand side of the definition of head, we can *unapply* the definition to produce the equivalent expression 'head (2:[4,5,6])' (for example). Applying a function definition (moving from the left side of the definition to the right side) brings us closer to a normal form, since there's one less function application. "Unapplying" a function definition (moving from the right side to the left side) moves us further away from normal form since we have introduced another function application. Of course, you would never want an evaluator to "unapply" functions in this way, but when reasoning about programs as humans, it can sometimes be useful in proving things. Does that help clear things up? -Brent -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080504/0a5c7959/attachment.htm From sebastian.sylvan at gmail.com Sun May 4 13:17:58 2008 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Sun May 4 13:12:14 2008 Subject: [Haskell-cafe] really difficult for a beginner like me... In-Reply-To: References: <7ca3f0160805040553m34cc441ekaf8a1d5feb82c@mail.gmail.com> Message-ID: <3d96ac180805041017k15974ffeua2185a76c83ba7e4@mail.gmail.com> 2008/5/4 Ivan Amarquaye : > thanks for the tip there....its been four gruesome days and i just don't > seem to make any understanding of how to implement some changes or create > some new functions due to the fact that im so new to Haskell and functional > programming. > > For the very first case of allowing hyphenated words to be treated as > single words i manged to successfully do that by adding to the definition of > the splitWords function to also accept characters such as "-" and it worked > perfectly after running it. > > The next case posed a headache for me as i have been on it for 3 days now. > >From my understanding, it means in situations where your writing a > sentence and you get to the end of the line while writing a word, you > decide to put a hyphen there and continue on the other line. So the case > demands that i allow sentences that end with hyphens and continue on the > next line to drop the hyphen and be a single word on that same line without > having to continue on the next line so this was how i foresee the input it > in hugs: > > Input: > makeIndex "these are the very same stuff they tell each-\nother" > > output: > should be this: [[1]these],[[1]eachother]. 1 indicates they are on the > same line and the others are left out as the index takes words greater than > 4 characters and i have been struggling with this since. i tried on several > counts to include in the splitwords function to dropWhile "-" is found in > the words but it turned out an error.I also tried creating a new function to > do that didnt succeed either can anybody help me out in this regard..... > > There are many ways of doing this of course. Perhaps you need to write a function like so: -- fixes up hyphenated words fixupHyphens :: [ (Int, Word) ] -> [ (Int, Word ) ] fixupHyphens ( (line1, word1):(line2:word2):xs ) | ... check if word1 ends with hyphen and line2 /= line1 ... = ( line1, ... something .. ) : fixupHyphens xs | otherwise = (line1, word1):(line2:word2): fixupHyphens xs fixupHyphens xs = xs Then you can insert this function in the appropriate place in the makeIndex function (probably before sorting, as you depend on the words showing up in order). -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080504/c95c0f4e/attachment-0001.htm From iavor.diatchki at gmail.com Sun May 4 20:30:37 2008 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Sun May 4 20:24:52 2008 Subject: [Haskell-cafe] Re: Control.Exception.evaluate - 'correct definition' not so correct In-Reply-To: References: <20080503091917.GA5333@shion.is.fushizen.net> Message-ID: <5ab17e790805041730o33b378e4u74f4f1f9e813e72b@mail.gmail.com> Hello, On Sat, May 3, 2008 at 3:56 AM, apfelmus wrote: > Bryan Donlan wrote: > > > > > evaluate x = (return $! x) >>= return > > > > However, if >>= is strict on its first argument, then this definition is > > no better than (return $! x). > > > > According to the monad law > > f >>= return = f > > every (>>=) ought to be strict in its first argument, so it indeed seems > that the implementation given in the documentation is wrong. >From the monad law we can conclude only that "(>>= return)" is strict, not (>>=) in general. For example, (>>=) for the reader monad is not strict in its first argument: m >>= f = \r -> f (m r) r So, "(undefined >> return 2) = (return 2)" -Iavor From waterson at maubi.net Sun May 4 23:40:08 2008 From: waterson at maubi.net (Chris Waterson) Date: Sun May 4 23:34:56 2008 Subject: [Haskell-cafe] sound synthesis In-Reply-To: <481AE5DE.2020003@0xc29.net> References: <481AE5DE.2020003@0xc29.net> Message-ID: <5963FB45-9EE9-470D-AB38-17F20CC95436@maubi.net> On May 2, 2008, at 2:58 AM, Thomas Girod wrote: > I remember an article ranting about how lazy evaluation would be > great to do signal processing, but it was lacking real world example. I did something similar a few weeks ago. I used libmad to lazily decode an MP3 file and play it using OS/X's core audio. Here's that post, with links to the libmad bindings (which might be useful for you, even if the CoreAudio isn't.) chris http://www.haskell.org/pipermail/haskell-cafe/2008-March/040796.html From RossBoylan at stanfordalumni.org Sun May 4 23:40:47 2008 From: RossBoylan at stanfordalumni.org (Ross Boylan) Date: Sun May 4 23:44:17 2008 Subject: [Haskell-cafe] Parsec on TeX Message-ID: I am new to Haskell and Parsec, and am trying to understand both. I tried to follow the example of how to use Parsec to parse TeX begin/end groups, but can't get it to run. I'm using HUGS -98 on Debian. When I copied the code I got errors about unknown terms (reserved and braces). I've tried to get them from the lexer, but now get this error :load grammar.hsl ERROR "grammar.hsl":21 - Type error in explicitly typed binding *** Term : envEnd *** Type : String -> GenParser Char a [Char] *** Does not match : String -> Parser () Can anyone help me understand what the problem is? Here's the code the caused the above error; I believe the part after --TeX example is verbatim from the Parsec documentation. I picked haskell as the language for to lexer "arbitrarily." import Text.ParserCombinators.Parsec import qualified Text.ParserCombinators.Parsec.Token as P import Text.ParserCombinators.Parsec.Language(haskell) reserved = P.reserved haskell braces = P.braces haskell -- TeX example environment = do{ name <- envBegin ; environment ; envEnd name } <|> return () envBegin :: Parser String envBegin = do{ reserved "\\begin" ; braces (many1 letter) } envEnd :: String -> Parser () envEnd name = do{ reserved "\\end" ; braces (string name) } From allbery at ece.cmu.edu Sun May 4 23:58:52 2008 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Sun May 4 23:53:07 2008 Subject: [Haskell-cafe] Parsec on TeX In-Reply-To: References: Message-ID: <56D0B8BD-1E2A-450F-9B5E-9CCDB3C4C94A@ece.cmu.edu> On 2008 May 4, at 23:40, Ross Boylan wrote: > ERROR "grammar.hsl":21 - Type error in explicitly typed binding > *** Term : envEnd > *** Type : String -> GenParser Char a [Char] > *** Does not match : String -> Parser () Hugs is prone to error messages that obscure the problem. The trick here is to realize that the type "Parser ()" is the same as "GenParser Char a ()"; this then tells you that you have used a function that returns a [Char] (aka String) where a type () (Haskell's version of (void)) is expected. > envEnd :: String -> Parser () > envEnd name = do{ reserved "\\end" > ; braces (string name) > } Line 21 is "; braces (string name)"; it is producing a String, when you need a (). One fix is to add one more line: > envEnd :: String -> Parser () > envEnd name = do reserved "\\end" > braces (string name) > return () Another possible fix is to change the type of "envEnd" to "String -> Parser String"; this may depend on how it's used. -- 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 dons at galois.com Mon May 5 00:00:44 2008 From: dons at galois.com (Don Stewart) Date: Sun May 4 23:55:01 2008 Subject: [Haskell-cafe] Parsec on TeX In-Reply-To: <56D0B8BD-1E2A-450F-9B5E-9CCDB3C4C94A@ece.cmu.edu> References: <56D0B8BD-1E2A-450F-9B5E-9CCDB3C4C94A@ece.cmu.edu> Message-ID: <20080505040044.GB15367@scytale.galois.com> allbery: > > On 2008 May 4, at 23:40, Ross Boylan wrote: > > >ERROR "grammar.hsl":21 - Type error in explicitly typed binding > >*** Term : envEnd > >*** Type : String -> GenParser Char a [Char] > >*** Does not match : String -> Parser () > > Hugs is prone to error messages that obscure the problem. The trick > here is to realize that the type "Parser ()" is the same as "GenParser > Char a ()"; this then tells you that you have used a function that > returns a [Char] (aka String) where a type () (Haskell's version of > (void)) is expected. Yeah, if you're on Debian it would make sense to install GHC -- its much more active, much faster, and supports more things. It's well maintained on Debian too. -- Don From derek.a.elkins at gmail.com Mon May 5 00:02:35 2008 From: derek.a.elkins at gmail.com (Derek Elkins) Date: Sun May 4 23:56:53 2008 Subject: [Haskell-cafe] Parsec on TeX In-Reply-To: References: Message-ID: <1209960155.5514.11.camel@derek-laptop> On Sun, 2008-05-04 at 20:40 -0700, Ross Boylan wrote: > I am new to Haskell and Parsec, and am trying to understand both. I tried > to follow the example of how to use Parsec to parse TeX begin/end groups, > but can't get it to run. I'm using HUGS -98 on Debian. > > When I copied the code I got errors about unknown terms (reserved and > braces). I've tried to get them from the lexer, but now get this error > :load grammar.hsl > ERROR "grammar.hsl":21 - Type error in explicitly typed binding > *** Term : envEnd > *** Type : String -> GenParser Char a [Char] > *** Does not match : String -> Parser () > > Can anyone help me understand what the problem is? > > Here's the code the caused the above error; I believe the part after --TeX > example is verbatim from the Parsec documentation. I picked haskell as the > language for to lexer "arbitrarily." > > import Text.ParserCombinators.Parsec > import qualified Text.ParserCombinators.Parsec.Token as P > import Text.ParserCombinators.Parsec.Language(haskell) > reserved = P.reserved haskell > braces = P.braces haskell > > > -- TeX example > environment = do{ name <- envBegin > ; environment > ; envEnd name > } > <|> return () > > envBegin :: Parser String > envBegin = do{ reserved "\\begin" > ; braces (many1 letter) > } > > envEnd :: String -> Parser () > envEnd name = do{ reserved "\\end" > ; braces (string name) > } braces returns, in this case, a string, so the type of envEnd is String -> Parser String. You can either change the type and add a return () to environment after envEnd or add a return () to envEnd. From RossBoylan at stanfordalumni.org Mon May 5 00:33:08 2008 From: RossBoylan at stanfordalumni.org (Ross Boylan) Date: Mon May 5 00:27:31 2008 Subject: [Haskell-cafe] Parsec on TeX In-Reply-To: <56D0B8BD-1E2A-450F-9B5E-9CCDB3C4C94A@ece.cmu.edu> References: <56D0B8BD-1E2A-450F-9B5E-9CCDB3C4C94A@ece.cmu.edu> Message-ID: <1209960860.8213.14.camel@corn.betterworld.us> On Sun, 2008-05-04 at 23:58 -0400, Brandon S. Allbery KF8NH wrote: > On 2008 May 4, at 23:40, Ross Boylan wrote: > > > ERROR "grammar.hsl":21 - Type error in explicitly typed binding > > *** Term : envEnd > > *** Type : String -> GenParser Char a [Char] > > *** Does not match : String -> Parser () > > Hugs is prone to error messages that obscure the problem. The trick > here is to realize that the type "Parser ()" is the same as "GenParser > Char a ()"; this then tells you that you have used a function that > returns a [Char] (aka String) where a type () (Haskell's version of > (void)) is expected. > > > envEnd :: String -> Parser () > > envEnd name = do{ reserved "\\end" > > ; braces (string name) > > } > > > Line 21 is "; braces (string name)"; it is producing a String, when > you need a (). One fix is to add one more line: > > > envEnd :: String -> Parser () > > envEnd name = do reserved "\\end" > > braces (string name) > > return () > > Another possible fix is to change the type of "envEnd" to "String -> > Parser String"; this may depend on how it's used. First, I'm really impressed with the fast and helpful responses from several people! So the example is wrong? What inference should I draw about the state of Parsec and its documentation? I was thinking of trying Frost et al's X-SAIGA, but that the better documentation for parsec would be a plus. I had thought HUGS made more sense for fiddling around, but it seems all I'm doing is loading files anyway. What is the style people use for this exploratory work? I've already installed haskell-mode for emacs and ghc6, but it's not clear to me to what extent the former servers as a development environment rather than just a language formatter. Thanks. From dons at galois.com Mon May 5 00:38:06 2008 From: dons at galois.com (Don Stewart) Date: Mon May 5 00:32:21 2008 Subject: [Haskell-cafe] Parsec on TeX In-Reply-To: <1209960860.8213.14.camel@corn.betterworld.us> References: <56D0B8BD-1E2A-450F-9B5E-9CCDB3C4C94A@ece.cmu.edu> <1209960860.8213.14.camel@corn.betterworld.us> Message-ID: <20080505043806.GC15367@scytale.galois.com> > I had thought HUGS made more sense for fiddling around, but it seems all > I'm doing is loading files anyway. What is the style people use for > this exploratory work? I've already installed haskell-mode for emacs > and ghc6, but it's not clear to me to what extent the former servers as > a development environment rather than just a language formatter. GHCi makes a great exploratory tool (and then you have the option of compiling the code as well). There are some nice integration tools with emacs and vim, but its also good to gain familiarity with ghci, the online documentation on haskell.org, and perhaps even drop by the #haskell IRC channel. Cheers, Don From allbery at ece.cmu.edu Mon May 5 00:52:20 2008 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Mon May 5 00:46:34 2008 Subject: [Haskell-cafe] Parsec on TeX In-Reply-To: <1209960860.8213.14.camel@corn.betterworld.us> References: <56D0B8BD-1E2A-450F-9B5E-9CCDB3C4C94A@ece.cmu.edu> <1209960860.8213.14.camel@corn.betterworld.us> Message-ID: On 2008 May 5, at 0:14, Ross Boylan wrote: > So the example is wrong? What inference should I draw about the state > of Parsec and its documentation? I was thinking of trying Frost et > al's > X-SAIGA, but that the better documentation for parsec would be a plus. The original documentation which you will probably find via Google is several years out of date; unfortunately, nobody has updated it and the newer API documentation lacks most of the actual details of how to *use* Parsec --- so really you need to have daan's Parsec paper and the Haskell library API documentation ( http://www.haskell.org/ghc/docs/latest/html/libraries/parsec/Text-ParserCombinators-Parsec.html ) open at the same time to see how things have changed. I will note that a newer version of Parsec is in devel