From el.zingo at gmail.com Sat Aug 2 22:09:24 2008 From: el.zingo at gmail.com (Alex Watt) Date: Sat Aug 2 22:09:14 2008 Subject: [Haskell-beginners] Pattern Matching Message-ID: <711c96310808021909w612988e8o4cfd52cd5b040f3e@mail.gmail.com> Hi there, The best way I can explain what I'd like to do is show an example, so here goes: same :: a -> a -> Bool same x x = True same _ _ = False Is there any way to do this in Haskell? The actual reason I'd like to do this is something slightly more complicated. I want to match against a list of elements, like so: foo [x,x,x] = ... Thanks for any help. - Alex -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080803/adb7448b/attachment.htm From rendel at daimi.au.dk Sat Aug 2 22:18:57 2008 From: rendel at daimi.au.dk (Tillmann Rendel) Date: Sat Aug 2 22:18:55 2008 Subject: [Haskell-beginners] Pattern Matching In-Reply-To: <711c96310808021909w612988e8o4cfd52cd5b040f3e@mail.gmail.com> References: <711c96310808021909w612988e8o4cfd52cd5b040f3e@mail.gmail.com> Message-ID: <48951591.5030207@daimi.au.dk> Alex Watt wrote: > The best way I can explain what I'd like to do is show an example, so > here goes: > > same :: a -> a -> Bool > same x x = True > same _ _ = False > > Is there any way to do this in Haskell? No, this is not possible. Each variable bound in a pattern has to be different. Maybe guards are a good alternative: same :: Eq a => a -> a -> Bool same x y | x == y = True same _ _ = False Note that you have to add an Eq constraint. > The actual reason I'd like to do this is something slightly more > complicated. I want to match against a list of elements, like so: > > foo[x,x,x] = ... Maybe you can employ the "all" function all :: (a -> Bool) -> [a] -> Bool in a guard, something like foo (x:xs) | all (x ==) xs = ... where you explicitly check that all list elements are equal to the first. Tillmann From allbery at ece.cmu.edu Sat Aug 2 22:37:10 2008 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Sat Aug 2 22:37:04 2008 Subject: [Haskell-beginners] Pattern Matching In-Reply-To: <711c96310808021909w612988e8o4cfd52cd5b040f3e@mail.gmail.com> References: <711c96310808021909w612988e8o4cfd52cd5b040f3e@mail.gmail.com> Message-ID: <6F7416E7-16BE-4DD9-AB17-9966A53F5213@ece.cmu.edu> On 2008 Aug 2, at 22:09, Alex Watt wrote: > same :: a -> a -> Bool > same x x = True > same _ _ = False > > Is there any way to do this in Haskell? The actual reason I'd like > to do this is something slightly more complicated. I want to match > against a list of elements, like so: Not with pattern matching by itself; using a name in a pattern creates a new binding. You can use guards: > same :: a -> a -> Bool > same x y | x == y = True > same _ _ = False which simplifies to > same :: a -> a -> Bool > same x y = x == y > foo [x,x,x] = ... > import Data.List > foo :: [a] -> Bool > foo x@(y:_:_:[]) = filter (== y) x This becomes unwieldy for large lists; you would instead switch to a guard: > import Data.List > foo :: [a] -> Bool > foo x@(y:x') | length x == N = filter (== y) x' -- N is your expected list length > foo _ = False or, possibly saving a few microseconds > import Data.List > foo :: [a] -> Bool > foo (y:x) | length x == N = filter (== y) x -- n is one less than your list length > foo _ = False -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080802/6356454f/attachment-0001.htm From chris at eidhof.nl Sun Aug 3 05:01:39 2008 From: chris at eidhof.nl (Chris Eidhof) Date: Sun Aug 3 05:01:31 2008 Subject: [Haskell-beginners] Pattern Matching In-Reply-To: <711c96310808021909w612988e8o4cfd52cd5b040f3e@mail.gmail.com> References: <711c96310808021909w612988e8o4cfd52cd5b040f3e@mail.gmail.com> Message-ID: Hey Alex, On 3 aug 2008, at 04:09, Alex Watt wrote: > Hi there, > > The best way I can explain what I'd like to do is show an example, > so here goes: > > same :: a -> a -> Bool > same x x = True > same _ _ = False > > Is there any way to do this in Haskell? The actual reason I'd like > to do this is something slightly more complicated. I want to match > against a list of elements, like so: > > foo [x,x,x] = ... If you want to check whether all elements of the list are the same, you'd need a function of type [a] -> Bool. There is no such function in the standard libraries (search for this type using Hoogle [1]). Fortunately, Hoogle will point us to all, which only needs a function from (a -> Bool) that is checked on every member of the list. One way we could solve this problem is to see whether all elements are equal to the first element. This is trivially expressed: allEqual :: Eq a => [a] -> Bool allEqual xs = all (== head xs) xs This also works for the empty list: because of lazy evaluation the expression "head xs" is only computed when actually needed. -chris [1]: http://www.haskell.org/hoogle/?q=[a]+-%3E+Bool From levi.stephen at gmail.com Mon Aug 4 01:12:05 2008 From: levi.stephen at gmail.com (Levi Stephen) Date: Mon Aug 4 01:11:51 2008 Subject: [Haskell-beginners] Representing a subset relationship Message-ID: <8341e4f40808032212p39ac196ev131860ad1cb089c1@mail.gmail.com> Hi, I was wondering what the best way to represent a 'subset' type relationship would be. The use case I'm looking at is where the subset would be a user selection, so a filter would not be appropriate. For example, say I have something like: type Order = [OrderItem] type OrderItem = OrderItem { qty :: Int, product: Product } Now I'd like the user to be able to select a number of items (e.g., priority shipping, gift wrapping) One possible way I can see is to add extra fields to the OrderItem record, but this seems like it would not be easy to extend. It doesn't seem like using [Product] would be appropriate as if the Product is updated it will need to be updated in both the OrderItem list and in the subset. Another approach would be to use a ProductIdType in place of Product, then look up the actual Product as needed. Are there other (and better) ways to do this? Thanks, Levi -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080804/61c96102/attachment.htm From daniel.is.fischer at web.de Mon Aug 4 09:23:36 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Mon Aug 4 09:21:25 2008 Subject: [Haskell-beginners] Representing a subset relationship In-Reply-To: <8341e4f40808032212p39ac196ev131860ad1cb089c1@mail.gmail.com> References: <8341e4f40808032212p39ac196ev131860ad1cb089c1@mail.gmail.com> Message-ID: <200808041523.36530.daniel.is.fischer@web.de> Am Montag, 4. August 2008 07:12 schrieb Levi Stephen: > Hi, > > I was wondering what the best way to represent a 'subset' type relationship > would be. The use case I'm looking at is where the subset would be a user > selection, so a filter would not be appropriate. > > For example, say I have something like: > > type Order = [OrderItem] > type OrderItem = OrderItem { qty :: Int, product: Product } > > Now I'd like the user to be able to select a number of items (e.g., > priority shipping, gift wrapping) > > One possible way I can see is to add extra fields to the OrderItem record, > but this seems like it would not be easy to extend. > > It doesn't seem like using [Product] would be appropriate as if the > Product is updated it will need to be updated in both the OrderItem list > and in the subset. > > Another approach would be to use a ProductIdType in place of Product, then > look up the actual Product as needed. > > Are there other (and better) ways to do this? > > Thanks, > Levi Perhaps something like data Extra = PriorityShipping | GiftWrapping ... data OrderItem = OrderItem { qty :: Int, product :: Product, extras :: [Extra] } ? Or make it type Quantity = Int type Order = [(Product, Quantity, [Extras])] ? Cheers, Daniel From paul.a.johnston at manchester.ac.uk Thu Aug 7 10:16:04 2008 From: paul.a.johnston at manchester.ac.uk (Paul Johnston) Date: Thu Aug 7 10:16:54 2008 Subject: [Haskell-beginners] Factorials using foldx Message-ID: Hi (First question so be gentle)! Just started to look at Haskell and I was wondering about various versions of calculating factorials. If I have facr 0 = 1 facr n = foldr (*) 1 [1..n] facl 0 = 1 facl n = foldl (*) 1 [1..n] Is there any difference in efficiency, I remember reading it is better to count down than to count up but left to right or right to left :-) Cheers Paul Paul Johnston Humanities Development Team Room 2.12 Bridgeford Street Building Manchester University Tel 0161 275 1396 Mail Paul.Johnston@manchester.ac.uk Web http://web-1.humanities.manchester.ac.uk/prjs/mcasspj/ How to shoot yourself in the foot Unix % ls foot.c foot.h foot.o toe.d toe.o %rm* .o rm:.o no such file or directory From daniel.is.fischer at web.de Thu Aug 7 11:16:47 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Thu Aug 7 11:14:26 2008 Subject: [Haskell-beginners] Factorials using foldx In-Reply-To: References: Message-ID: <200808071716.47517.daniel.is.fischer@web.de> Am Donnerstag, 7. August 2008 16:16 schrieb Paul Johnston: > Hi (First question so be gentle)! > Just started to look at Haskell and I was wondering about various versions > of calculating factorials. > > If I have > > facr 0 = 1 > facr n = foldr (*) 1 [1..n] > > facl 0 = 1 > facl n = foldl (*) 1 [1..n] > > Is there any difference in efficiency, I remember reading it is better to > count down than to count up but left to right or right to left :-) For this task, there will be no big difference unless the compiler's optimiser sees the strictness (which it can, if the type is appropriately determined). facr will build a thunk of the form 1 * (2 * (3 * (4 * (... * (n * 1) ...)))), there is no way the evaluation can start before the end of the list is reached, so the size of the thunk is O(n) and it will blow the stack if n is too large. facl will build a thunk of the form (...(((1 * 1) * 2) * 3) * ...) * n, which will also blow the stack if n is large enough. Since it is built from the inside out, it could be evaluated in each step to prevent the stack overflow, but because of the laziness, that will only happen if the implementation knows that it will be needed, which is for instance the case if you compile with -O (at least if you use GHC) and the type of facl can be deduced or is given as Int -> Int or Integer -> Integer. You can get that behaviour without relying on the optimiser by using the strict left fold foldl' from Data.List, which forces evaluation at each step. As a general rule, if you can get a result (or start producing a result) without traversing the entire list, use foldr. Examples for this are and = foldr (&&) True and or = foldr (||) False and for the case of producing partial results concat = foldr (++) []. If you need to consume the entire list to get a result, use foldl'. I don't know of any case where foldl is a better choice than foldl'. > > Cheers Paul > Cheers, Daniel From v.dijk.bas at gmail.com Thu Aug 7 11:35:57 2008 From: v.dijk.bas at gmail.com (Bas van Dijk) Date: Thu Aug 7 11:35:33 2008 Subject: [Haskell-beginners] Factorials using foldx In-Reply-To: References: Message-ID: On Thu, Aug 7, 2008 at 4:16 PM, Paul Johnston wrote: > Is there any difference in efficiency, I remember reading it is better to count down than to count up but left to right or right to left :-) I wrote a small wiki article on the differences beteen the various folds: http://haskell.org/haskellwiki/Foldr_Foldl_Foldl%27 regards, Bas From ajb at spamcop.net Fri Aug 8 01:00:23 2008 From: ajb at spamcop.net (ajb@spamcop.net) Date: Fri Aug 8 01:00:02 2008 Subject: [Haskell-beginners] Factorials using foldx In-Reply-To: <200808071716.47517.daniel.is.fischer@web.de> References: <200808071716.47517.daniel.is.fischer@web.de> Message-ID: <20080808010023.rpykulnv48w4c84k-nwo@webmail.spamcop.net> G'day all. Quoting Daniel Fischer : > facr will build a thunk of the form > 1 * (2 * (3 * (4 * (... * (n * 1) ...)))), [...] > facl will build a thunk of the form > (...(((1 * 1) * 2) * 3) * ...) * n, which will also blow the stack if n is > large enough. [...] > You can get that behaviour without relying on the optimiser by using the > strict left fold > > foldl' > > from Data.List, which forces evaluation at each step. There's one more possibility you should be aware of, assume you're trying to compute large factorials, and that's to use a binary tree-style recursion pattern. This one is bottom-up, but you could also do top-down: << {-# SPECIALIZE binaryProduct :: [Integer] -> Integer #-} binaryProduct :: (Num a) => [a] -> a binaryProduct [] = 1 binaryProduct [x] = x binaryProduct xs = binaryProduct (bip' xs) where bip' (x1:x2:xs) = x1*x2 : bip' xs bip' xs = xs fac1 :: Integer -> Integer fac1 n = foldl' (*) 1 [1..n] fac2 :: Integer -> Integer fac2 n = binaryProduct [1..n] >> The speed difference for large n is remarkable: << Factorial> fac1 100000 == fac2 100000 True Factorial> :set +s Factorial> fac1 100000 `seq` () () (6.27 secs, 9304407772 bytes) Factorial> fac2 100000 `seq` () () (0.31 secs, 20527124 bytes) >> (The `seq` () idiom, by the way, forces computation of the result without incurring the expense of calling "show". The "show" function on Integers is quite slow for very large numbers, and the factorial of 100,000 is a very large number.) As you can probably guess, the speedup is not due to lazy evaluation. A good exercise for bright students who know something about computer arithmetic: Why is the binary tree-style version so much faster? Cheers, Andrew Bromage From rendel at daimi.au.dk Fri Aug 8 06:24:44 2008 From: rendel at daimi.au.dk (Tillmann Rendel) Date: Fri Aug 8 06:24:16 2008 Subject: [Haskell-beginners] Factorials using foldx In-Reply-To: <20080808010023.rpykulnv48w4c84k-nwo@webmail.spamcop.net> References: <200808071716.47517.daniel.is.fischer@web.de> <20080808010023.rpykulnv48w4c84k-nwo@webmail.spamcop.net> Message-ID: <489C1EEC.1010802@daimi.au.dk> ajb@spamcop.net wrote: > There's one more possibility you should be aware of, assume you're > trying to compute large factorials, and that's to use a binary > tree-style recursion pattern. This one is bottom-up, but you could > also do top-down: Here's my top-down binary fold, with growing tree sizes to allow the processing of infinite lists. module Binfold where import System.Environment import Data.List -- fold the first 2 ** n elements tree-shaped binfold :: Int -> (a -> a -> a) -> a -> [a] -> (a, [a]) binfold n f i [] = (i, []) binfold 0 f i (x:xs) = (x, xs) binfold n f i xs = (f y z, xs'') where (y, xs') = binfold (pred n) f i xs (z, xs'') = binfold (pred n) f i xs' -- fold with a growing sequence of binfolds growfold :: Int -> (a -> a -> a) -> a -> [a] -> a growfold n f i [] = i growfold n f i xs = f y (growfold (succ n) f i xs') where (y, xs') = binfold n f i xs main = do [op, n] <- getArgs let fold = case op of "growfold" -> growfold 0 "foldr" -> foldr "foldl" -> foldl "foldl!" -> foldl' print . length . show . fold (*) 1 . enumFromTo 1 . read $ n $ ghc -O2 -main-is Binfold -o Binfold Binfold.hs $ time ./Binfold foldr 100000 456574 real 0m15.094s user 0m0.015s sys 0m0.031s $ time ./Binfold foldl 100000 456574 real 0m18.000s user 0m0.030s sys 0m0.015s $ time ./Binfold foldl! 100000 456574 real 0m4.641s user 0m0.031s sys 0m0.031s $ time ./Binfold growfold 100000 456574 real 0m0.954s user 0m0.015s sys 0m0.015s Tillmann From wyn44 at hotmail.com Sat Aug 9 07:21:08 2008 From: wyn44 at hotmail.com (Simon Parry) Date: Sat Aug 9 07:20:37 2008 Subject: [Haskell-beginners] SOEGraphics Message-ID: Hello, apologies if this is the wrong forum. I'm having trouble getting going with the SOEGraphics library (I'm trying to work my way through The Haskell School of Expression book). I'm running GHC 6.8.3 using emacs on a windows XP machine. I'm getting a 'Could not find module `GraphicsUtils'' load error when I import SOEGraphics but I can see the file in the correct folder (which is included in my .emacs file)? Any suggestions? thanks Simon Parry -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080809/957e0739/attachment-0001.htm From emmanuel.delaborde at cimex.com Mon Aug 11 11:47:03 2008 From: emmanuel.delaborde at cimex.com (emmanuel.delaborde) Date: Mon Aug 11 11:46:29 2008 Subject: [Haskell-beginners] Problem building packages Message-ID: <89909A3E-1586-49A3-A867-5D270E75A5BF@cimex.com> Hello, I am trying to build HAppS-Util with cabal-install it fails with the following message: could not execute: /Library/Frameworks/GHC.framework/Versions/608/usr/ lib/ghc-6.8.3/ghc-asm What can I do to circumvent this ? Thanks E ----------------------------------------------------------------------------------------------- This e-mail (and any attachments) is confidential and may contain personal views which are not the views of Cimex Media Ltd and any affiliated companies, unless specifically stated. It is intended for the use of the individual or group to whom it is addressed. If you have received it in error, please delete it from your system, do not use, copy or disclose the information in any way nor act in reliance on it and please notify postmaster@cimex.com A company registered in England Wales. Company Number 03765711 Registered Office : The Olde Bakehouse, 156 Watling Street East, Towcester, Northants NN12 6DB This email was scanned by Postini, the leading provider in Managed Email Security. From DekuDekuplex at Yahoo.com Wed Aug 13 07:53:16 2008 From: DekuDekuplex at Yahoo.com (Benjamin L.Russell) Date: Wed Aug 13 07:52:40 2008 Subject: [Haskell-beginners] purely functional (non-monadic) alternatives for Haskell animations in _The Haskell School of Expression_? Message-ID: Recently, I mentioned Paul Hudak's _The Haskell School of Expression_ (see http://www.haskell.org/soe/) as an example of using multimedia examples to motivate learning programming in another education-related programming mailing list, plt-scheme, in a thread there entitled "More pedagogic stuff" (see http://list.cs.brown.edu/pipermail/plt-scheme/2008-August/026441.html). In reply, a respondent, Matthias Felleisen, wrote the following (see http://list.cs.brown.edu/pipermail/plt-scheme/2008-August/026445.html): >P.S. Yes, I have read Paul's book and I think Haskell has something >to it. >You may be surprised to learn, however, that world.ss animations are >purely functional while Haskell animations (in Paul's book) are actually >quasi-imperative. That is, they are using monads and carry the >imperativeness >on their sleeves. In response to this claim, does anybody know how to rewrite Hudak's SOE animations so that they do not use monads and are "purely functional?" -- Benjamin L. Russell From DekuDekuplex at Yahoo.com Wed Aug 13 08:04:13 2008 From: DekuDekuplex at Yahoo.com (Benjamin L.Russell) Date: Wed Aug 13 08:04:08 2008 Subject: [Haskell-beginners] SOEGraphics References: Message-ID: On Sat, 9 Aug 2008 12:21:08 +0100, "Simon Parry" wrote: >Hello, > >apologies if this is the wrong forum. > >I'm having trouble getting going with the SOEGraphics library (I'm trying to work my way through The Haskell School of Expression book). > >I'm running GHC 6.8.3 using emacs on a windows XP machine. > >I'm getting a 'Could not find module `GraphicsUtils'' load error when I import SOEGraphics but I can see the file in the correct folder (which is included in my .emacs file)? > >Any suggestions? Sorry, but I don't have a copy of the book with me, and your problem is apparently not listed in the SOE "Bugs/Errata" page (see http://www.haskell.org/soe/Bug/erata.htm). Could you please provide a sample of the code that you are running? Also, what do you mean by "I can see the file in the correct folder (which is included in my .emacs file)?" Is 'Could not find module `GraphicsUtils'' the exact error message that you are getting? -- Benjamin L. Russell From chaddai.fouche at gmail.com Wed Aug 13 08:25:54 2008 From: chaddai.fouche at gmail.com (=?ISO-8859-1?Q?Chadda=EF_Fouch=E9?=) Date: Wed Aug 13 08:25:12 2008 Subject: [Haskell-beginners] purely functional (non-monadic) alternatives for Haskell animations in _The Haskell School of Expression_? In-Reply-To: References: Message-ID: 2008/8/13 Benjamin L. Russell : >>P.S. Yes, I have read Paul's book and I think Haskell has something >>to it. >>You may be surprised to learn, however, that world.ss animations are >>purely functional while Haskell animations (in Paul's book) are actually >>quasi-imperative. That is, they are using monads and carry the >>imperativeness >>on their sleeves. > > In response to this claim, does anybody know how to rewrite Hudak's > SOE animations so that they do not use monads and are "purely > functional?" > First, monad /= imperative It is important to establish this distinction which doesn't seem to be very clear in some minds... The IO monad allows imperative actions, the ST monad too, the Maybe Monad doesn't, neither does the List Monad... The State monad can be argued either way but all it does is make easier to use a pattern you often meet in non-monadic functional programming. The confusion is helped along by the do-notation in Haskell which definitely looks like imperative programming, but is only sugar over a purely functional form. Now, I don't know SOE very well and it is very possible that its description of animation is imperative but animations imply to handle time and order of operations anyway, so I don't really see how you could implement that in a more purely functional style, a monad is very good at describing ordered actions with a light syntax in a functional context. (Another aspect is if the details of the rendering of the animation is interleaved with the description, that is a more interesting subject, on which we could compare the code in world.ss and SOE) -- Jeda? From DekuDekuplex at Yahoo.com Wed Aug 13 08:28:28 2008 From: DekuDekuplex at Yahoo.com (Benjamin L.Russell) Date: Wed Aug 13 08:27:56 2008 Subject: [Haskell-beginners] Haskell in K-12 education? Message-ID: Does anybody know of any uses of Haskell in teaching programming in K-12 education? Recently, I read an interesting essay entitled "Why Computer Science Doesn?t Matter" (see http://www.ccs.neu.edu/home/matthias/essays/not-matter.html), by Matthias Felleisen and Shriram Krishnamurthi, on how using multimedia examples in teaching programming in K-12 education could potentially elevate programming to a Fourth R ("'rogramming"), in addition to the current Three Rs ("reading," "?riting," and "?ritmetic"). They suggest tying together programming and mathematics, using the idea that "modern arithmetic and algebra doesn?t have to be about numbers," but that "[i]t may involve images, strings, symbols, Cartesian points, and other forms of ?objects.?" Their discussion reminded me of _The Haskell School of Expression_ (see http://www.haskell.org/soe/), by Paul Hudak, which also uses multimedia examples to motivate programming, but at a more advanced (college) level. Currently, DrScheme (see http://www.drscheme.org/) (based on Scheme) and Squeak (see http://www.squeak.org/) (based on a dialect of Smalltalk) are two programming environments that are often used in K-12 schooling to teach programming, but I see no reason that Haskell could not fulfill this role as well. Does anybody know of any books/tools for using Haskell as a tool to teach programming in K-12 education? -- Benjamin L. Russell From Alistair.Bayley at invesco.com Wed Aug 13 08:43:22 2008 From: Alistair.Bayley at invesco.com (Bayley, Alistair) Date: Wed Aug 13 08:42:40 2008 Subject: [Haskell-beginners] purely functional (non-monadic) alternativesfor Haskell animations in _The Haskell School of Expression_? In-Reply-To: References: Message-ID: <125EACD0CAE4D24ABDB4D148C4593DA9049E951A@GBLONXMB02.corp.amvescap.net> > From: beginners-bounces@haskell.org > [mailto:beginners-bounces@haskell.org] On Behalf Of Chadda? Fouch? > > 2008/8/13 Benjamin L. Russell : > >>P.S. Yes, I have read Paul's book and I think Haskell has something > >>to it. > >>You may be surprised to learn, however, that world.ss animations are > >>purely functional while Haskell animations (in Paul's book) > are actually > >>quasi-imperative. That is, they are using monads and carry the > >>imperativeness > >>on their sleeves. > > > > In response to this claim, does anybody know how to rewrite Hudak's > > SOE animations so that they do not use monads and are "purely > > functional?" > > First, monad /= imperative > It is important to establish this distinction which doesn't seem to be > very clear in some minds... I think Matthias Felleisen probably understands this, but I could be wrong... I had a quick scan of the SOE source and it looks as though all of the graphics operations are in IO (). I don't see why you couldn't rearrange it so that describing shapes was purely functional, while rendering was still IO () (required by OpenGL, I assume), but it looks like it could be quite a bit of work. For animation, perhaps look at Conal Elliot's functional reactive work, but I don't know how usable it is: http://conal.net/ Alistair ***************************************************************** Confidentiality Note: The information contained in this message, and any attachments, may contain confidential and/or privileged material. It is intended solely for the person(s) or entity to which it is addressed. Any review, retransmission, dissemination, or taking of any action in reliance upon this information by persons or entities other than the intended recipient(s) is prohibited. If you received this in error, please contact the sender and delete the material from any computer. ***************************************************************** From chaddai.fouche at gmail.com Wed Aug 13 09:14:46 2008 From: chaddai.fouche at gmail.com (=?ISO-8859-1?Q?Chadda=EF_Fouch=E9?=) Date: Wed Aug 13 09:14:03 2008 Subject: [Haskell-beginners] purely functional (non-monadic) alternativesfor Haskell animations in _The Haskell School of Expression_? In-Reply-To: <125EACD0CAE4D24ABDB4D148C4593DA9049E951A@GBLONXMB02.corp.amvescap.net> References: <125EACD0CAE4D24ABDB4D148C4593DA9049E951A@GBLONXMB02.corp.amvescap.net> Message-ID: 2008/8/13 Bayley, Alistair : >> First, monad /= imperative >> It is important to establish this distinction which doesn't seem to be >> very clear in some minds... > > I think Matthias Felleisen probably understands this, but I could be wrong... > I think so too, but we're on Haskell-beginners and the formulation was much too ambiguous to let it pass, I would prefer that beginners in Haskell don't start with the idea that Monad are always imperative, it's already too current a misunderstanding. > > I had a quick scan of the SOE source and it looks as though all of the graphics operations are in IO (). I don't see why you couldn't rearrange it so that describing shapes was purely functional, while rendering was still IO () (required by OpenGL, I assume), but it looks like it could be quite a bit of work. > That's unfortunate. Of course IO (or some FRP hiding the IO) is still required to do the rendering, but it would be much nicer to split those concerns. -- Jeda? From DekuDekuplex at Yahoo.com Thu Aug 14 01:10:21 2008 From: DekuDekuplex at Yahoo.com (Benjamin L.Russell) Date: Thu Aug 14 10:10:36 2008 Subject: [Haskell-beginners] purely functional (non-monadic) alternativesfor Haskell animations in _The Haskell School of Expression_? References: <125EACD0CAE4D24ABDB4D148C4593DA9049E951A@GBLONXMB02.corp.amvescap.net> Message-ID: On Wed, 13 Aug 2008 14:14:46 +0100, "Chaddai Fouche" wrote: >2008/8/13 Bayley, Alistair : >>> First, monad /= imperative >>> It is important to establish this distinction which doesn't seem to be >>> very clear in some minds... >> >> I think Matthias Felleisen probably understands this, but I could be wrong... >> > >I think so too, but we're on Haskell-beginners and the formulation was >much too ambiguous to let it pass, I would prefer that beginners in >Haskell don't start with the idea that Monad are always imperative, >it's already too current a misunderstanding. Can you recommend any specific examples to illustrate this point to a programmer/educator from a Scheme background arguing that specific libraries in world.ss are more functional than the monadic examples for animations in SOE? If possible, I would like to write a rebuttal to his claim, using specific examples. >> I had a quick scan of the SOE source and it looks as though all of the graphics operations are in IO (). I don't see why you couldn't rearrange it so that describing shapes was purely functional, while rendering was still IO () (required by OpenGL, I assume), but it looks like it could be quite a bit of work. >> > >That's unfortunate. Of course IO (or some FRP hiding the IO) is still >required to do the rendering, but it would be much nicer to split >those concerns. That's probably the point that Felleisen was addressing. If functions have any side-effects, then they aren't purely functional, but in order to perform rendering, side-effects would be necessary in both Haskell and Scheme, so this can't be his point. Therefore, he must be referring to other functions written in a more purely functional style in world.ss than in SOE. In order to address his point, they would probably be need to be rewritten in a purely functional style. -- Benjamin L. Russell From el.zingo at gmail.com Thu Aug 14 10:33:26 2008 From: el.zingo at gmail.com (Alex Watt) Date: Thu Aug 14 10:32:40 2008 Subject: [Haskell-beginners] Ruby Quiz Solution #15 - won't work after compilation Message-ID: <711c96310808140733w3629d784t2f1e687137153e9f@mail.gmail.com> If I call "main" in ghci, my program runs as it should, but if I try compiling it, and then running the result of that compilation, i.e.: $ ghc -o animal_game game.hs $ ./animal_game unexpected things occur, particularly "getChar" does not work correctly, and if I take a route that doesn't lead to getChar needing to be called, the program stops running at the end of 2nd run despite your response to the do-you-want-to-play-again-question. $ ./animal_game .... Do you want to play again? (y/n) y .... Do you want to play again? (y/n) y Thanks for playing! $ The source code is here: http://rafb.net/p/7fYlEV72.html I don't know how long that will stay up there, so let me know if it's gone and I'll repaste or find a better alternative. What would also be nice is any comments on the actual code; as a begginner, it's nice to get some feedback, and I might as well also ask the following question. Originally I wanted to the types to be as such: data Animal = Animal String data Question a b = Question String a b -- where a is a Question or an Animal, as is b The problem is I wanted methods that had types that were able to accept an argument of type Animal or Question, and for it to act appropriately on that type, I tried adding them to common type classes (a new one I created called 'Askable' which contained a method 'ask'), but I ran into a whole bunch of problems. Is there any easy way to do it? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080814/59b5b8a4/attachment-0001.htm From byorgey at seas.upenn.edu Thu Aug 14 15:13:22 2008 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Thu Aug 14 15:12:34 2008 Subject: [Haskell-beginners] Ruby Quiz Solution #15 - won't work after compilation In-Reply-To: <711c96310808140733w3629d784t2f1e687137153e9f@mail.gmail.com> References: <711c96310808140733w3629d784t2f1e687137153e9f@mail.gmail.com> Message-ID: <20080814191322.GA24420@minus.seas.upenn.edu> On Thu, Aug 14, 2008 at 03:33:26PM +0100, Alex Watt wrote: > If I call "main" in ghci, my program runs as it should, but if I try > compiling it, and then running the result of that compilation, i.e.: > > $ ghc -o animal_game game.hs > $ ./animal_game > > unexpected things occur, particularly "getChar" does not work correctly, and When you say 'getchar does not work correctly', exactly what do you mean? I'm not sure of the problem, but this smells to me of something having to do with buffering and/or newline characters not getting handled properly. > What would also be nice is any comments on the actual code; as a begginner, > it's nice to get some feedback, and I might as well also ask the following > question. Originally I wanted to the types to be as such: > > data Animal = Animal String > data Question a b = Question String a b -- where a is a Question or an > Animal, as is b > > The problem is I wanted methods that had types that were able to accept > an argument of type Animal or Question, and for it to act appropriately on > that type, I tried adding them to common type classes (a new one I created > called 'Askable' which contained a method 'ask'), but I ran into a whole > bunch of problems. Is there any easy way to do it? Creating an 'Askable' type class sounds like it would be a great solution in certain instances; the problem to me looks like the fact that you want to create a data structure (a QuestionTree) which contains both Animals and Questions. This quickly leads into existential types---doable, but probably best left until later. At any rate, your current solution---making Animal and Question constructors of a data type, and implementing play' and other such functions by pattern matching---seems quite nice. It's certainly the approach I would take. In general your code looks very nice. The only comment I have is that I would separate out play' and getNewAnimal as separate top-level functions, rather than defining them in a 'where' block. Functions which are not top-level are difficult to test by themselves. -Brent From allbery at ece.cmu.edu Thu Aug 14 16:03:35 2008 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Thu Aug 14 16:02:53 2008 Subject: [Haskell-beginners] Ruby Quiz Solution #15 - won't work after compilation In-Reply-To: <20080814191322.GA24420@minus.seas.upenn.edu> References: <711c96310808140733w3629d784t2f1e687137153e9f@mail.gmail.com> <20080814191322.GA24420@minus.seas.upenn.edu> Message-ID: On Aug 14, 2008, at 15:13 , Brent Yorgey wrote: > On Thu, Aug 14, 2008 at 03:33:26PM +0100, Alex Watt wrote: >> If I call "main" in ghci, my program runs as it should, but if I try >> compiling it, and then running the result of that compilation, i.e.: >> >> $ ghc -o animal_game game.hs >> $ ./animal_game >> >> unexpected things occur, particularly "getChar" does not work >> correctly, and > > When you say 'getchar does not work correctly', exactly what do you > mean? I'm not sure of the problem, but this smells to me of something > having to do with buffering and/or newline characters not getting > handled properly. I'm thinking termios is in line mode still. System.Posix.Terminal is what he needs. -- 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 el.zingo at gmail.com Thu Aug 14 16:12:49 2008 From: el.zingo at gmail.com (Alex Watt) Date: Thu Aug 14 16:12:02 2008 Subject: [Haskell-beginners] Ruby Quiz Solution #15 - won't work after compilation In-Reply-To: References: <711c96310808140733w3629d784t2f1e687137153e9f@mail.gmail.com> <20080814191322.GA24420@minus.seas.upenn.edu> Message-ID: <711c96310808141312x5d34ebc7kf7eb1ecfbb05ff71@mail.gmail.com> Brent: getChar acts like getLine from what I can tell, it's a bit odd On 8/14/08, Brandon S. Allbery KF8NH wrote: > > > On Aug 14, 2008, at 15:13 , Brent Yorgey wrote: > > On Thu, Aug 14, 2008 at 03:33:26PM +0100, Alex Watt wrote: >> >>> If I call "main" in ghci, my program runs as it should, but if I try >>> compiling it, and then running the result of that compilation, i.e.: >>> >>> $ ghc -o animal_game game.hs >>> $ ./animal_game >>> >>> unexpected things occur, particularly "getChar" does not work correctly, >>> and >>> >> >> When you say 'getchar does not work correctly', exactly what do you >> mean? I'm not sure of the problem, but this smells to me of something >> having to do with buffering and/or newline characters not getting >> handled properly. >> > > I'm thinking termios is in line mode still. System.Posix.Terminal is what > he needs. > > -- > 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 > > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080814/6cb299c8/attachment.htm From daniel.is.fischer at web.de Thu Aug 14 17:29:55 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Thu Aug 14 17:27:07 2008 Subject: [Haskell-beginners] Ruby Quiz Solution #15 - won't work after compilation In-Reply-To: <711c96310808141312x5d34ebc7kf7eb1ecfbb05ff71@mail.gmail.com> References: <711c96310808140733w3629d784t2f1e687137153e9f@mail.gmail.com> <711c96310808141312x5d34ebc7kf7eb1ecfbb05ff71@mail.gmail.com> Message-ID: <200808142329.55217.daniel.is.fischer@web.de> Am Donnerstag, 14. August 2008 22:12 schrieb Alex Watt: > Brent: getChar acts like getLine from what I can tell, it's a bit odd > Buffering indeed, in ghci, IIRC, stdin and stdout aren't buffered by default, for binaries the default is line buffering, so the char won't be gotten until you type a newline. Changing your code to module Main where import System.IO main :: IO () main = do hSetBuffering stdin NoBuffering play (Animal "Dog") return () solves the problem: Think of an animal, I will try to guess what it is... Are you thinking of a Dog? (y/n) n I give up, you win! Please help me improve my guesses! What is the name of the animal you were thinking of? Cat Now please enter a question that answers yes for a Cat and no for a Dog Does it meow? Do you want to play again? (y/n) y Think of an animal, I will try to guess what it is... Does it meow? (y/n) n Are you thinking of a Dog? (y/n) n I give up, you win! Please help me improve my guesses! What is the name of the animal you were thinking of? Cow Now please enter a question that answers yes for a Cow and no for a Dog Is it useful? Do you want to play again? (y/n) y Think of an animal, I will try to guess what it is... Does it meow? (y/n) n Is it useful? (y/n) y Are you thinking of a Cow? (y/n) y I win this time. Do you want to play again? (y/n) n Thanks for playing.. On the other count, I have to agree with Brent, the code is very nice overall, but play' and getNewAnimal as top level functions would be better, and I don't really like the line play' question@(Question s y n) = do ans <- ask $ show question I'd prefer do ans <- ask s but that's purely a matter of taste. HTH, Daniel From el.zingo at gmail.com Thu Aug 14 18:47:50 2008 From: el.zingo at gmail.com (Alex Watt) Date: Thu Aug 14 18:47:02 2008 Subject: [Haskell-beginners] Ruby Quiz Solution #15 - won't work after compilation In-Reply-To: <200808142329.55217.daniel.is.fischer@web.de> References: <711c96310808140733w3629d784t2f1e687137153e9f@mail.gmail.com> <711c96310808141312x5d34ebc7kf7eb1ecfbb05ff71@mail.gmail.com> <200808142329.55217.daniel.is.fischer@web.de> Message-ID: <711c96310808141547y5272499fl480519c5c59f27ae@mail.gmail.com> Thanks Daniel, that worked brilliantly. I took yours and Brent's advice and brought play' and getNewAnimal out of the where block. Also, the line "do ans <- ask $ show question" was probably there due to some of the previous code, in which case that line would have been slightly better (in my opinion, anyway), but I've changed it now, because I prefer "do ans <- ask s" too. Thanks again. - Alex On 8/14/08, Daniel Fischer wrote: > > Am Donnerstag, 14. August 2008 22:12 schrieb Alex Watt: > > > Brent: getChar acts like getLine from what I can tell, it's a bit odd > > > > > Buffering indeed, in ghci, IIRC, stdin and stdout aren't buffered by > default, > for binaries the default is line buffering, so the char won't be gotten > until > you type a newline. Changing your code to > > module Main where > > import System.IO > > main :: IO () > main = do hSetBuffering stdin NoBuffering > play (Animal "Dog") > return () > > solves the problem: > > Think of an animal, I will try to guess what it is... > Are you thinking of a Dog? (y/n) > n > I give up, you win! > Please help me improve my guesses! > What is the name of the animal you were thinking of? > Cat > Now please enter a question that answers yes for a Cat and no for a Dog > Does it meow? > > Do you want to play again? (y/n) > y > > Think of an animal, I will try to guess what it is... > Does it meow? (y/n) > n > Are you thinking of a Dog? (y/n) > n > I give up, you win! > Please help me improve my guesses! > What is the name of the animal you were thinking of? > Cow > Now please enter a question that answers yes for a Cow and no for a Dog > Is it useful? > > Do you want to play again? (y/n) > y > > Think of an animal, I will try to guess what it is... > Does it meow? (y/n) > n > Is it useful? (y/n) > y > Are you thinking of a Cow? (y/n) > y > I win this time. > > Do you want to play again? (y/n) > > n > Thanks for playing.. > > On the other count, I have to agree with Brent, the code is very nice > overall, > but play' and getNewAnimal as top level functions would be better, and I > don't really like the line > > play' question@(Question s y n) = do ans <- ask $ show question > > I'd prefer do ans <- ask s > > but that's purely a matter of taste. > > HTH, > > Daniel > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080814/71c1ebe5/attachment.htm From DekuDekuplex at Yahoo.com Mon Aug 18 05:36:51 2008 From: DekuDekuplex at Yahoo.com (Benjamin L.Russell) Date: Mon Aug 18 05:36:11 2008 Subject: [Haskell-beginners] Is there a way to use images as parameters to Haskell functions? Message-ID: <90gia45nnqhdlhkf80djio4im58m9rrqqc@4ax.com> Recently, I came across a new book for beginner-level programmers that uses the idea of images as parameters to functions, and was wondering whether there is any way to do this in Haskell (they use PLT Scheme in DrScheme): How to Design Programs/2e: Prolog - Section 2 - Arithmetic and Arithmetic: http://www.ccs.neu.edu/home/matthias/HtDP/Prologue/book-Z-H-4.html > Before we show you how to do some ``real'' programming, let's discuss one more kind of data to spice things up: > >> At the above prompt, the actual image of is inserted, not the textual reference to the image. I.e., there is a picture at the prompt, instead of text. Further, these images can be used as parameters, similarly to strings, in functions; viz.: >One important library -- world.ss -- supports operations for computing the width and height of an image: > >(* (image-width ) > (image-height )) > >Once you have added a library to your program, clicking Run gives you > > 1200 > >because that's the area of a 30 x 40 image. The idea of using images as parameters to functions in teaching programming to beginners could be useful in motivating learning Haskell as well, and should be implementable as such. Does anybody know of any similar tool for Haskell? -- Benjamin L. Russell From DekuDekuplex at Yahoo.com Mon Aug 18 05:42:30 2008 From: DekuDekuplex at Yahoo.com (Benjamin L.Russell) Date: Mon Aug 18 05:41:53 2008 Subject: [Haskell-beginners] Is there a way to use images as parameters to Haskell functions? References: <90gia45nnqhdlhkf80djio4im58m9rrqqc@4ax.com> Message-ID: On Mon, 18 Aug 2008 18:36:51 +0900, Benjamin L.Russell wrote: >[...] > >>One important library -- world.ss -- supports operations for computing the width and height of an image: >> >>(* (image-width ) >> (image-height )) Sorry, but I forgot to include the references to images in the above function. It actually appeared as follows (replace the occurrences of "rocket-s.jpg" below with the actual images for the references): >>One important library -- world.ss -- supports operations for computing the width and height of an image: >> >>(* (image-width ) >> (image-height )) -- Benjamin L. Russell From bburd at drew.edu Tue Aug 19 14:30:37 2008 From: bburd at drew.edu (Barry Burd) Date: Tue Aug 19 14:29:41 2008 Subject: [Haskell-beginners] Absolute beginner's questions... Message-ID: <48AAD8DE.618A.0054.0@drew.edu> I'm just getting started with Haskell. I've written the following simple program: module Med where -- lst = [5, 3, 7, 8, 0, 2, 4, 1, 6] lst = [7, 3, 1, 2, 0, 9, 8] numLessThan x = length([y | y <- lst, y < x]) numGreaterThan x = length([y | y <- lst, y > x]) median = [ x | x <- lst, numLessThan x == numGreaterThan x] I realize that this code isn't very robust. My questions are as follows: - I remember running this code with some values of lst (containing an odd number of unique integer values) and getting the wrong answer. Is that possible? I can't replicate the results because I don't remember what values of lst didn't work. - How can I add a line or two to display intermediate results (in order to debug the code if necessary)? I've tried adding putTraceMsg but I keep getting parse errors. I probably haven't fully assimilated the syntax of functional programming yet. Thanks. From byorgey at seas.upenn.edu Tue Aug 19 15:16:52 2008 From: byorgey at seas.upenn.edu (Brent Yorgey) Date: Tue Aug 19 15:15:48 2008 Subject: [Haskell-beginners] Absolute beginner's questions... In-Reply-To: <48AAD8DE.618A.0054.0@drew.edu> References: <48AAD8DE.618A.0054.0@drew.edu> Message-ID: <20080819191652.GA2971@minus.seas.upenn.edu> On Tue, Aug 19, 2008 at 02:30:37PM -0400, Barry Burd wrote: > I'm just getting started with Haskell. I've written the following simple program: > > module Med > where > > -- lst = [5, 3, 7, 8, 0, 2, 4, 1, 6] > lst = [7, 3, 1, 2, 0, 9, 8] > numLessThan x = length([y | y <- lst, y < x]) > numGreaterThan x = length([y | y <- lst, y > x]) > > median = [ x | x <- lst, numLessThan x == numGreaterThan x] > > I realize that this code isn't very robust. My questions are as follows: > - I remember running this code with some values of lst (containing an odd number of unique integer values) and getting the wrong answer. Is that possible? I can't replicate the results because I don't remember what values of lst didn't work. It seems to me that you would run into problems with a list containing an even number of unique integer values. In such a list, there are no values which have an equal number of greater and lesser values. For example, if your list has four elements, then any particular element would have either 0 less than it and 3 greater, or 1 less and 2 greater, or 2 less and 1 greater, etc. If I recall correctly, in such a case the median is defined as the average of the two centermost values. > - How can I add a line or two to display intermediate results (in order to debug the code if necessary)? I've tried adding putTraceMsg but I keep getting parse errors. I probably haven't fully assimilated the syntax of functional programming yet. You can always import Debug.Trace and use the 'trace' function, which takes a String and another value, and prints the String before returning the other value. So for example, you could say numLessThan x = length( [ y <- lst, trace (show y ++ " < " ++ show x ++ "?\n") (y < x)] ) to have each test print a message. *However*, you will probably find that printing intermediate results is not as useful in Haskell as you are used to in other languages. For one thing, Haskell's laziness means that things may not be evaluated in the order you might think, so the order in which things are printed may be confusing. And in any case, a much better debugging strategy is to make sure to break things down into many simple top-level functions which you can test interactively on their own. The absence of side-effects makes it quite easy to test pieces of your program separately before putting them together. Using testing tools like QuickCheck is also a great way to make sure your functions behave in the way you expect, and to help figure out what is wrong with them when they don't. -Brent From vss at 73rus.com Tue Aug 19 15:37:06 2008 From: vss at 73rus.com (Vlad Skvortsov) Date: Tue Aug 19 15:36:12 2008 Subject: [Haskell-beginners] Absolute beginner's questions... In-Reply-To: <48AAD8DE.618A.0054.0@drew.edu> References: <48AAD8DE.618A.0054.0@drew.edu> Message-ID: <48AB20E2.9070805@73rus.com> Barry Burd wrote: > I'm just getting started with Haskell. I've written the following simple program: > > module Med > where > > -- lst = [5, 3, 7, 8, 0, 2, 4, 1, 6] > lst = [7, 3, 1, 2, 0, 9, 8] > numLessThan x = length([y | y <- lst, y < x]) > numGreaterThan x = length([y | y <- lst, y > x]) > > median = [ x | x <- lst, numLessThan x == numGreaterThan x] > > I realize that this code isn't very robust. My questions are as follows: > - I remember running this code with some values of lst (containing an odd number of unique integer values) and getting the wrong answer. Is that possible? I can't replicate the results because I don't remember what values of lst didn't work. > - How can I add a line or two to display intermediate results (in order to debug the code if necessary)? I've tried adding putTraceMsg but I keep getting parse errors. I probably haven't fully assimilated the syntax of functional programming yet. > As for the second part of your question, it usually helps to develop your programs "bottom up"; also try to avoid using global data (lst in your case), pass that as a parameter instead. For example, start with a function which returns values from a given list which are less than the given value (btw, type signatures are really helpful too): lessThan :: Int -> [Int] -> [Int] lessThan x lst = [y | y <- lst, y < x] In fact, this function can be redefined as: lessThan x lst = filter (< x) lst (once you get more advanced, you'll also figure out it can be "eta-reduced" to just 'lessThan x = filter (< x)' ) After you've defined it, it's pretty easy to test the function in an interpreter to see if it works as expected. Due to the fact that no global data is used, testing becomes real easy: *Main> let lessThan x lst = filter (< x) lst *Main> lessThan 5 [1, 4, 6, 2, 7] [1,4,2] ... Along the same lines, define a 'greaterThan' function: greaterThan :: Int -> [Int] -> [Int] greaterThan x lst = filter (> x) lst Then let's make another baby step and create functions that return a *number* of items in the list which are less or greater than the passed value. numLessThan x lst = length (lessThan x lst) numGreaterThan x lst = length (greaterThan x lst) Note that for improved readability we can also write them as: numLessThan x lst = length $ lessThan x lst numGreaterThan x lst = length $ greaterThan x lst Now, again, we can easily test these functions from the interpreter: *Main> numLessThan 3 [1, 4, 2, 7, 6] 2 Now we can create a function that would return a pair of values; the first value in the pair denotes the number of items in the list less than given value, the second value is the number of items in the list greater than the given value: numLessGreater :: Int -> [Int] -> (Int, Int) numLessGreater x lst = (numLessThan x lst, numGreaterThan x lst) Let's test it as well: *Main> numLessGreater 3 [1, 4, 2, 7, 6] (2,3) The target condition is when the first and the second values are equal in the pair returned by 'numLessGreater'. Let's write a function to test this condition: isMedian (x, y) = x == y Now we can write a function to return *all* medians from the list. medians :: [Int] -> [Int] medians lst = [x | x <- lst, isMedian (numLessGreater x lst)] As you can see by testing this function, it can return any number (including 0) of medians, depending on the input: *Main> medians [] [] *Main> medians [1, 2, 3] [2] *Main> medians [1, 2, 3, 2] [2,2] Now back to the main function, 'median'. We have to think about what happens if this function receives an empty list. There are a couple of options (it may make sense to return a value of type 'Maybe Int'); here I chose the function to crash if given invalid input. All our function has to do is to call 'medians' and pick a single value out of the result returned. By using pattern matching we make sure the function will crash if given empty list as an input. median :: [Int] -> Int median lst = case medians lst of -- All the values in the result are the same, we just pick the first one x:xs -> x And again, here is how we test it: *Main> median [1, 2, 3, 2] 2 *Main> median [1, 2, 3] 2 *Main> median [] *** Exception: median.hs:(158,2)-(160,12): Non-exhaustive patterns in case So this is the kind of approach one (well, me ;-)) usually takes. Summarizing: * build from bottom up, start with simple functions; * test as you go; * make your functions pure (not depending on global data), it simplifies development and testing; * strive for clarity first, optimize only after measuring; * optimize only the bottleneck(s). Note that for the sake of simplicity I used Int's everywhere, but in fact it should be any comparable value. Hope this helps. -- Vlad Skvortsov, vss@73rus.com, http://vss.73rus.com From bburd at drew.edu Wed Aug 20 16:19:36 2008 From: bburd at drew.edu (Barry Burd) Date: Wed Aug 20 16:18:34 2008 Subject: [Haskell-beginners] Reading input Message-ID: <48AC4408.618A.0054.0@drew.edu> In the last line of this program, I get the following error message (from ghci)... Couldn't match expected type `Int' against inferred type `Char' Expected type: [Int] Inferred type: String In the first argument of `median', namely `lst' In the expression: median lst Failed, modules loaded: none. Here's the program... module Main where import IO lessThan :: Int -> [Int] -> [Int] lessThan x lst = filter (< x) lst greaterThan :: Int -> [Int] -> [Int] greaterThan x lst = filter (> x) lst numLessThan :: Int -> [Int] -> Int numLessThan x lst = length (lessThan x lst) numGreaterThan :: Int -> [Int] -> Int numGreaterThan x lst = length (greaterThan x lst) numLessGreater :: Int -> [Int] -> (Int, Int) numLessGreater x lst = (numLessThan x lst, numGreaterThan x lst) isMedian :: (Int, Int) -> Bool isMedian (x, y) = x == y medians :: [Int] -> [Int] medians lst = [x | x <- lst, isMedian (numLessGreater x lst)] median :: [Int] -> Int median lst = case medians lst of -- All the values in the result are the same, we just pick the first one x:xs -> x main = do putStr "Enter a list: " lst <- getLine median lst I'm sure this is because Haskell isn't automatically changing a String to a List of numbers. But how can I do this? Thanks. From cmb21 at kent.ac.uk Wed Aug 20 16:25:41 2008 From: cmb21 at kent.ac.uk (C.M.Brown) Date: Wed Aug 20 16:24:35 2008 Subject: [Haskell-beginners] Reading input In-Reply-To: <48AC4408.618A.0054.0@drew.edu> References: <48AC4408.618A.0054.0@drew.edu> Message-ID: Hi Barry, You can use read: ... lst <- getline median (read lst::[Int]) ... You will have to enter your list like this at the prompt: > [1,2,3,4] read transforms Strings into some other type (usually specified by a type annotation). read :: Read a => String -> a HTH Chris. On Wed, 20 Aug 2008, Barry Burd wrote: > In the last line of this program, I get the following error message (from ghci)... > > Couldn't match expected type `Int' against inferred type `Char' > Expected type: [Int] > Inferred type: String > In the first argument of `median', namely `lst' > In the expression: median lst > Failed, modules loaded: none. > > Here's the program... > > module Main > where > > import IO > > lessThan :: Int -> [Int] -> [Int] > lessThan x lst = filter (< x) lst > > greaterThan :: Int -> [Int] -> [Int] > greaterThan x lst = filter (> x) lst > > numLessThan :: Int -> [Int] -> Int > numLessThan x lst = length (lessThan x lst) > numGreaterThan :: Int -> [Int] -> Int > numGreaterThan x lst = length (greaterThan x lst) > > numLessGreater :: Int -> [Int] -> (Int, Int) > numLessGreater x lst = (numLessThan x lst, numGreaterThan x lst) > > isMedian :: (Int, Int) -> Bool > isMedian (x, y) = x == y > > medians :: [Int] -> [Int] > medians lst = [x | x <- lst, isMedian (numLessGreater x lst)] > > median :: [Int] -> Int > median lst = > case medians lst of > -- All the values in the result are the same, we just pick the first one > x:xs -> x > > main = do > putStr "Enter a list: " > lst <- getLine > median lst > > I'm sure this is because Haskell isn't automatically changing a String to a List of numbers. But how can I do this? > Thanks. > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > From gale at sefer.org Wed Aug 20 16:31:16 2008 From: gale at sefer.org (Yitzchak Gale) Date: Wed Aug 20 16:30:10 2008 Subject: [Haskell-beginners] Reading input In-Reply-To: <48AC4408.618A.0054.0@drew.edu> References: <48AC4408.618A.0054.0@drew.edu> Message-ID: <2608b8a80808201331t784e98b5vfe5887340ae29b3a@mail.gmail.com> Hi Barry, Barry Burd wrote: > median :: [Int] -> Int > median lst = > case medians lst of > -- All the values in the result are the same, we just pick the first one > x:xs -> x > > main = do > putStr "Enter a list: " > lst <- getLine > median lst > I'm sure this is because Haskell isn't automatically changing a String > to a List of numbers. But how can I do this? Use the "read" function. Watch out, though - there is no error checking there. So if the user enters a string that does not have the right syntax for a Haskell list of integers, your program will halt with an error message. You have another problem - you used the "median" function as a step in a do block - but each step in a do block must have type "IO a" for some type a. Here's how you could write your main function: main = do putStr "Enter a list: " lst <- getLine print $ median $ read lst Regards, Yitz From cmb21 at kent.ac.uk Wed Aug 20 16:34:23 2008 From: cmb21 at kent.ac.uk (C.M.Brown) Date: Wed Aug 20 16:33:18 2008 Subject: [Haskell-beginners] Reading input In-Reply-To: <2608b8a80808201331t784e98b5vfe5887340ae29b3a@mail.gmail.com> References: <48AC4408.618A.0054.0@drew.edu> <2608b8a80808201331t784e98b5vfe5887340ae29b3a@mail.gmail.com> Message-ID: Barry, On another note, you may want to avoid monads altogether for this. You can run this straight from ghci (replacing mainProg with main) mainProg :: [Int] -> Int mainProg arg = median lst and then call mainProg with your desired list of stings > mainProg [1,2,3,4] Chris. On Wed, 20 Aug 2008, Yitzchak Gale wrote: > Hi Barry, > > Barry Burd wrote: > > median :: [Int] -> Int > > median lst = > > case medians lst of > > -- All the values in the result are the same, we just pick the first one > > x:xs -> x > > > > main = do > > putStr "Enter a list: " > > lst <- getLine > > median lst > > > I'm sure this is because Haskell isn't automatically changing a String > > to a List of numbers. But how can I do this? > > Use the "read" function. Watch out, though - there is > no error checking there. So if the user enters a string > that does not have the right syntax for a Haskell list > of integers, your program will halt with an error message. > > You have another problem - you used the "median" > function as a step in a do block - but each step in a > do block must have type "IO a" for some type a. > > Here's how you could write your main function: > > main = do > putStr "Enter a list: " > lst <- getLine > print $ median $ read lst > > Regards, > Yitz > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > From cmb21 at kent.ac.uk Wed Aug 20 16:38:33 2008 From: cmb21 at kent.ac.uk (C.M.Brown) Date: Wed Aug 20 16:37:27 2008 Subject: [Haskell-beginners] Reading input In-Reply-To: References: <48AC4408.618A.0054.0@drew.edu> <2608b8a80808201331t784e98b5vfe5887340ae29b3a@mail.gmail.com> Message-ID: Or, call median with your list of ints and forget about mainProg...:) Chris. On Wed, 20 Aug 2008, C.M.Brown wrote: > Barry, > > On another note, you may want to avoid monads altogether for this. You can > run this straight from ghci (replacing mainProg with main) > > mainProg :: [Int] -> Int > mainProg arg = median lst > > and then call mainProg with your desired list of stings > > > mainProg [1,2,3,4] > > Chris. > > > On Wed, 20 Aug 2008, Yitzchak Gale wrote: > > > Hi Barry, > > > > Barry Burd wrote: > > > median :: [Int] -> Int > > > median lst = > > > case medians lst of > > > -- All the values in the result are the same, we just pick the first one > > > x:xs -> x > > > > > > main = do > > > putStr "Enter a list: " > > > lst <- getLine > > > median lst > > > > > I'm sure this is because Haskell isn't automatically changing a String > > > to a List of numbers. But how can I do this? > > > > Use the "read" function. Watch out, though - there is > > no error checking there. So if the user enters a string > > that does not have the right syntax for a Haskell list > > of integers, your program will halt with an error message. > > > > You have another problem - you used the "median" > > function as a step in a do block - but each step in a > > do block must have type "IO a" for some type a. > > > > Here's how you could write your main function: > > > > main = do > > putStr "Enter a list: " > > lst <- getLine > > print $ median $ read lst > > > > Regards, > > Yitz > > _______________________________________________ > > Beginners mailing list > > Beginners@haskell.org > > http://www.haskell.org/mailman/listinfo/beginners > > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > From venkatr2004 at gmail.com Wed Aug 20 17:23:26 2008 From: venkatr2004 at gmail.com (Venkat Ramanan) Date: Wed Aug 20 17:22:23 2008 Subject: [Haskell-beginners] ghci interactive behaviour. Message-ID: Hi all, I'm just beginning to learn haskell. I see some strange behaviour in ghci. Don't know if it is related to readline. Behaviour-1: Lets say after we enter an expression, we just hit "Enter" 3 times to insert 3 empty lines. To get back the expression, we need to do ( or up-arrow ) 3 times. In other words, the empty lines seem to be stored in the history. Bash ( and tcsh ) seem to save only non-empty lines. Behaviour-2: It doesn't seem to do pruning of duplicates. If the same expression is entered twice, both of them are stored in the history instead of just one. Bash uses environmental variables (HISTCONTROL and HISTIGNORE ) to modify this behavior. Is there a way to get saner behaviour like in bash? I'm using ghc-6.8.2 which comes with ubuntu 8.04. Thanks, Venkat. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080820/2cb3137f/attachment.htm From daniel.is.fischer at web.de Wed Aug 20 17:35:17 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Aug 20 17:32:09 2008 Subject: [Haskell-beginners] ghci interactive behaviour. In-Reply-To: References: Message-ID: <200808202335.17661.daniel.is.fischer@web.de> Am Mittwoch, 20. August 2008 23:23 schrieb Venkat Ramanan: > Hi all, > > I'm just beginning to learn haskell. > > I see some strange behaviour in ghci. Don't know if it is related to > readline. > > Behaviour-1: > Lets say after we enter an expression, we just hit "Enter" 3 times to > insert 3 empty lines. To get back the expression, we need to do ( or > up-arrow ) 3 times. > > In other words, the empty lines seem to be stored in the history. Bash ( > and tcsh ) seem to save only non-empty lines. > > Behaviour-2: > It doesn't seem to do pruning of duplicates. If the same expression is > entered twice, both of them are stored in the history instead of just one. > Bash uses environmental variables (HISTCONTROL and HISTIGNORE ) to modify > this behavior. > > Is there a way to get saner behaviour like in bash? > > I'm using ghc-6.8.2 which comes with ubuntu 8.04. > > Thanks, > Venkat. #1 is fixed in 6.8.3, but duplicates aren't eliminated there either. From chaddai.fouche at gmail.com Thu Aug 21 00:08:54 2008 From: chaddai.fouche at gmail.com (=?ISO-8859-1?Q?Chadda=EF_Fouch=E9?=) Date: Thu Aug 21 00:07:47 2008 Subject: [Haskell-beginners] Reading input In-Reply-To: <2608b8a80808201331t784e98b5vfe5887340ae29b3a@mail.gmail.com> References: <48AC4408.618A.0054.0@drew.edu> <2608b8a80808201331t784e98b5vfe5887340ae29b3a@mail.gmail.com> Message-ID: 2008/8/20 Yitzchak Gale : > Here's how you could write your main function: > > main = do > putStr "Enter a list: " > lst <- getLine > print $ median $ read lst > Another possibility would be a space delimited number list, easier for your users to remember : > parseWordList :: (Read a) => String -> [a] > parseWordList str = map read . unwords $ str > > main = do > putStrLn "Enter a list of integers : " > line <- getLine > print . median . parseWordList $ line -- Jeda? From chaddai.fouche at gmail.com Thu Aug 21 00:09:53 2008 From: chaddai.fouche at gmail.com (=?ISO-8859-1?Q?Chadda=EF_Fouch=E9?=) Date: Thu Aug 21 00:08:45 2008 Subject: [Haskell-beginners] Reading input In-Reply-To: References: <48AC4408.618A.0054.0@drew.edu> <2608b8a80808201331t784e98b5vfe5887340ae29b3a@mail.gmail.com> Message-ID: 2008/8/21 Chadda? Fouch? : > > Another possibility would be a space delimited number list, easier for > your users to remember : > >> parseWordList :: (Read a) => String -> [a] >> parseWordList str = map read . unwords $ str >> Oups, that was wrong : > parseWordList :: (Read a) => String -> [a] > parseWordList str = map read . words $ str -- Jeda? From gale at sefer.org Thu Aug 21 04:56:25 2008 From: gale at sefer.org (Yitzchak Gale) Date: Thu Aug 21 04:55:17 2008 Subject: [Haskell-beginners] Reading input In-Reply-To: References: <48AC4408.618A.0054.0@drew.edu> <2608b8a80808201331t784e98b5vfe5887340ae29b3a@mail.gmail.com> Message-ID: <2608b8a80808210156m767edbb4nc585a25d5f5d3802@mail.gmail.com> Chadda? Fouch? wrote: > Another possibility would be a space delimited number list, easier for > your users to remember : > > parseWordList :: (Read a) => String -> [a] > parseWordList str = map read . words $ str Even nicer, here is a function that will allow the user to enter a "list of numbers" in any reasonable format. If the input doesn't make sense as a "list of numbers", the empty list is returned: parseWordList :: (Read a) => String -> [a] parseWordList = unfoldr $ listToMaybe . concatMap reads . tails You'll need to import the Data.List and Data.Maybe libraries for this. Here is a snippet from a GHCi session that illustrates its use: Prelude Data.List Data.Maybe> parseWordList "The numbers are 34, 56, and 22." :: [Int] [34,56,22] Regards, Yitz From fbrubacher at gmail.com Thu Aug 21 09:32:29 2008 From: fbrubacher at gmail.com (Federico Brubacher) Date: Thu Aug 21 09:31:20 2008 Subject: [Haskell-beginners] purely functional (non-monadic) alternativesfor Haskell animations in _The Haskell School of Expression_? In-Reply-To: References: <125EACD0CAE4D24ABDB4D148C4593DA9049E951A@GBLONXMB02.corp.amvescap.net> Message-ID: <206c53410808210632w78533b0ekffef712fef7d56be@mail.gmail.com> Hey Benjamin, I solved the quiz myself but would you mind posting your code again so I can compare ?? Thanks a ton Federico On Thu, Aug 14, 2008 at 2:10 AM, Benjamin L. Russell wrote: > On Wed, 13 Aug 2008 14:14:46 +0100, "Chaddai Fouche" > wrote: > > >2008/8/13 Bayley, Alistair : > >>> First, monad /= imperative > >>> It is important to establish this distinction which doesn't seem to be > >>> very clear in some minds... > >> > >> I think Matthias Felleisen probably understands this, but I could be > wrong... > >> > > > >I think so too, but we're on Haskell-beginners and the formulation was > >much too ambiguous to let it pass, I would prefer that beginners in > >Haskell don't start with the idea that Monad are always imperative, > >it's already too current a misunderstanding. > > Can you recommend any specific examples to illustrate this point to a > programmer/educator from a Scheme background arguing that specific > libraries in world.ss are more functional than the monadic examples > for animations in SOE? > > If possible, I would like to write a rebuttal to his claim, using > specific examples. > > >> I had a quick scan of the SOE source and it looks as though all of the > graphics operations are in IO (). I don't see why you couldn't rearrange it > so that describing shapes was purely functional, while rendering was still > IO () (required by OpenGL, I assume), but it looks like it could be quite a > bit of work. > >> > > > >That's unfortunate. Of course IO (or some FRP hiding the IO) is still > >required to do the rendering, but it would be much nicer to split > >those concerns. > > That's probably the point that Felleisen was addressing. If functions > have any side-effects, then they aren't purely functional, but in > order to perform rendering, side-effects would be necessary in both > Haskell and Scheme, so this can't be his point. Therefore, he must be > referring to other functions written in a more purely functional style > in world.ss than in SOE. In order to address his point, they would > probably be need to be rewritten in a purely functional style. > > -- Benjamin L. Russell > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > -- Federico Brubacher www.fbrubacher.com Colonial Duty Free Shop www.colonial.com.uy -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080821/cba8593a/attachment.htm From DekuDekuplex at Yahoo.com Thu Aug 21 22:37:00 2008 From: DekuDekuplex at Yahoo.com (Benjamin L.Russell) Date: Thu Aug 21 22:35:56 2008 Subject: [Haskell-beginners] purely functional (non-monadic) alternativesfor Haskell animations in _The Haskell School of Expression_? References: <125EACD0CAE4D24ABDB4D148C4593DA9049E951A@GBLONXMB02.corp.amvescap.net> <206c53410808210632w78533b0ekffef712fef7d56be@mail.gmail.com> Message-ID: On Thu, 21 Aug 2008 10:32:29 -0300, "Federico Brubacher" wrote: >Hey Benjamin, I solved the quiz myself but would you mind posting your code >again so I can compare ?? Which quiz? -- Benjamin L. Russell From quergle at googlemail.com Fri Aug 22 13:07:50 2008 From: quergle at googlemail.com (Quergle Quergle) Date: Fri Aug 22 13:06:38 2008 Subject: [Haskell-beginners] How does the type of "ap = liftM2 id" work? Message-ID: Hello, I'm a bit perplexed by what it means to do something like "ap = liftM2 id" liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r id :: a -> a liftM2 id :: (Monad m) => m (a2 -> r) -> m a2 -> m r My intuitive understanding is that liftM2 is expecting a two-argument function as its first argument, so it seems a little unexpected to pass it "id", a one-argument function. And I can't really see how the type signature of "liftM2 id" is derived from "liftM2" and "id". Any help much appreciated! -- Matt From felipe.lessa at gmail.com Fri Aug 22 13:18:58 2008 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Fri Aug 22 13:17:45 2008 Subject: [Haskell-beginners] How does the type of "ap = liftM2 id" work? In-Reply-To: References: Message-ID: On Fri, Aug 22, 2008 at 2:07 PM, Quergle Quergle wrote: > Hello, > > I'm a bit perplexed by what it means to do something like "ap = liftM2 id" > > liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r > id :: a -> a > liftM2 id :: (Monad m) => m (a2 -> r) -> m a2 -> m r > > My intuitive understanding is that liftM2 is expecting a two-argument > function as its first argument, so it seems a little unexpected to > pass it "id", a one-argument function. And I can't really see how the > type signature of "liftM2 id" is derived from "liftM2" and "id". Any > help much appreciated! Just remember that 'a1 -> a2 -> r' is equivalent to '(a1) -> (a2 -> r)', and unifying this type with 'a -> a' gives a1 = a2 -> r So, liftM2's type becomes ((a2 -> r) -> a2 -> r) -> m (a2 -> r) -> m a2 -> m r Is it clearer now? HTH, -- Felipe. From allbery at ece.cmu.edu Fri Aug 22 13:24:26 2008 From: allbery at ece.cmu.edu (Brandon S. Allbery KF8NH) Date: Fri Aug 22 13:23:17 2008 Subject: [Haskell-beginners] How does the type of "ap = liftM2 id" work? In-Reply-To: References: Message-ID: <5D76C3FE-983D-4C5D-A892-5D9DDD7ACF53@ece.cmu.edu> On 2008 Aug 22, at 13:07, Quergle Quergle wrote: > id :: a -> a > liftM2 id :: (Monad m) => m (a2 -> r) -> m a2 -> m r > > My intuitive understanding is that liftM2 is expecting a two-argument > function as its first argument, so it seems a little unexpected to > pass it "id", a one-argument function. And I can't really see how the That's not quite how types work. "a -> a", with nothing constraining the "a", can be *any* type... including a function type. And because in Haskell a multiple-argument function is identical to a single- argument function returning a single-argument function, the type of "id" encompasses any number of arguments. So, "liftM2 id" constrains "id" by usage (as you noted, it requires a 2-argument function) to have the type "(a -> b) -> (a -> b)" instead of "a -> a", and now it works. -- 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 rendel at daimi.au.dk Fri Aug 22 15:02:12 2008 From: rendel at daimi.au.dk (Tillmann Rendel) Date: Fri Aug 22 15:01:13 2008 Subject: [Haskell-beginners] How does the type of "ap = liftM2 id" work? In-Reply-To: References: Message-ID: <48AF0D34.60508@daimi.au.dk> Quergle Quergle wrote: > I'm a bit perplexed by what it means to do something like "ap = liftM2 id" > > liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r > id :: a -> a > liftM2 id :: (Monad m) => m (a2 -> r) -> m a2 -> m r > > My intuitive understanding is that liftM2 is expecting a two-argument > function as its first argument, so it seems a little unexpected to > pass it "id", a one-argument function. And I can't really see how the > type signature of "liftM2 id" is derived from "liftM2" and "id". Any > help much appreciated! Polymorphic values in Haskell have more then one type. Lets try to figure out a type of the id in liftM2 id. From the type signature of id, we know that it has to be a -> a for some a. From the type signature of liftM2, we know that is has to be a1 -> a2 -> r for some a1, a2 and r. Since a1 -> a2 -> r is a1 -> (a2 -> r), we have (a -> a) == a1 -> (a2 -> r) and therefore a == a1 == a2 -> r. If we substitute a2 -> r for both a and a1 in the types of id and liftM2, we see why liftM2 id is well-typed and one of its types: id :: (a2 -> r) -> (a2 -> r) liftM2 :: ((a2 -> r) -> (a2 -> r)) -> m (a2 -> r) -> m a2 -> m r liftM2 id :: m (a2 -> r) -> m a2 -> mr If you have problems with understand ap = liftM2 id, you may want to look into ($) = id first. Tillmann From nielsadb at gmail.com Sat Aug 23 18:53:04 2008 From: nielsadb at gmail.com (Niels Aan de Brugh) Date: Sat Aug 23 18:51:53 2008 Subject: [Haskell-beginners] Running Yi 0.4.3 Message-ID: <48B094D0.2020700@gmail.com> Hi there, I'm having some trouble installing and running Yi 0.4.3. I just compiled and installed Yi, after disabling parsec-3.0.0 and recompiling regex-tdfa first (Yi requires a 2.x version, regex takes whatever it can get, including 3.0.0). Here's a short excerpt from my console (newlines inserted for readability). niels(~/src/yi-0.4.3): sudo runhaskell Setup.hs install Installing: /usr/local/lib/yi-0.4.3/ghc-6.8.2 Installing: /usr/local/bin Registering yi-0.4.3... Reading package info from "dist/installed-pkg-config" ... done. Saving old package config file... done. Writing new package config file... done. niels(~): mkdir .yi niels(~): cd .yi/ niels(~/.yi): cp /home/niels/src/yi-0.4.3/examples/yi.hs . niels(~/.yi): yi Launching custom yi: "/home/niels/.yi/yi-i386-linux" yi: exception :: System.Glib.GError.GError niels(~/.yi): yi --frontend=pango Launching custom yi: "/home/niels/.yi/yi-i386-linux" yi-i386-linux: exception :: System.Glib.GError.GError niels(~/.yi): yi --frontend=gtk Launching custom yi: "/home/niels/.yi/yi-i386-linux" yi-i386-linux: exception :: System.Glib.GError.GError niels(~/.yi): ghc-pkg list /usr/lib/ghc-6.8.2/package.conf: (Cabal-1.2.3.0), Cabal-1.4.0.1, (Cabal-1.5.1), Crypto-4.1.0, HTTP-3001.0.4, HUnit-1.2.0.0, HaXml-1.13.3, QuickCheck-1.1.0.0, Stream-0.2.2, X11-1.4.1, array-0.1.0.0, arrows-0.3, base-3.0.1.0, binary-0.4.1, bitset-0.6, bloomfilter-1.2.1, bytestring-0.9.0.1, cairo-0.9.12.1, cairo-0.9.13, containers-0.1.0.1, directory-1.0.0.0, fgl-5.4.1.1, filepath-1.1.0.0, fingertree-0.0, gconf-0.9.12.1, gconf-0.9.13, (ghc-6.8.2), glade-0.9.12.1, glade-0.9.13, glib-0.9.12.1, glib-0.9.13, gnomevfs-0.9.13, gstreamer-0.9.13, gtk-0.9.12.1, gtk-0.9.13, gtkglext-0.9.12.1, gtkglext-0.9.13, haddock-2.1.0, haskell98-1.0.1.0, hpc-0.5.0.0, html-1.0.1.1, hxt-8.0.0, mtl-1.1.0.0, network-2.1.0.0, old-locale-1.0.0.0, old-time-1.0.0.0, packedstring-0.1.0.0, pandoc-0.46, parallel-1.0.0.0, parsec-2.1.0.0, pretty-1.0.0.0, process-1.0.0.0, pureMD5-0.2.3, random-1.0.0.0, readline-1.0.1.0, regex-base-0.72.0.1, regex-base-0.93.1, regex-compat-0.71.0.1, regex-compat-0.91, regex-posix-0.72.0.2, regex-posix-0.93.1, regex-tdfa-0.94, rts-1.0, soegtk-0.9.13, sourceview-0.9.12.1, sourceview-0.9.13, svgcairo-0.9.13, tagsoup-0.6, template-haskell-2.2.0.0, time-1.1.2.0, unix-2.3.0.0, utf8-string-0.3.1, vty-3.0.1, wx-0.10.3, wxcore-0.10.3, xhtml-3000.0.2.1, xmonad-0.6, xmonad-contrib-0.6, yi-0.4.3 niels(~/.yi): dpkg -l | grep libghc6-gtk ii libghc6-gtk-dev 0.9.12.1-1ubuntu2 A GUI library for Haskell (Gtk2Hs) -- GTK+ b ii libghc6-gtkglext-dev 0.9.12.1-1ubuntu2 A GUI library for Haskell (Gtk2Hs) -- gtkgle I'm running a recent version of Ubuntu Linux and GHC 6.8.2. Does anyone know what mistake I'm making? I'd really like to replace Vim for Yi for Haskell source file editing some day but up until now this is actually the first time I got Yi to compile. Regards, Niels From lpillay at webafrica.org.za Sun Aug 24 13:38:48 2008 From: lpillay at webafrica.org.za (Logesh Pillay) Date: Sun Aug 24 13:39:37 2008 Subject: [Haskell-beginners] Puzzling type error Message-ID: <48B19CA8.8090406@webafrica.org.za> I've written the following implementation of the algorithm in this article http://www.afjarvis.staff.shef.ac.uk/maths/jarvisspec02.pdf sqRoot n scale = sqRoot' (5*n) 5 where sqRoot' a b | floor (logBase 10 b) >= scale = div b 10 | a >= b = sqRoot' (a-b) (b+10) | otherwise = sqRoot' (a*100) ((100 * (div b 10)) + (mod b 10)) Since this involves whole numbers only, I was surprised by the following run-time error. *Main> sqRoot 2 5 :1:0: Ambiguous type variable `t' in the constraints: `RealFrac t' arising from a use of `sqRoot' at :1:0-9 `Floating t' arising from a use of `sqRoot' at :1:0-9 `Integral t' arising from a use of `sqRoot' at :1:0-9 Probable fix: add a type signature that fixes these type variable(s) What am I missing? Logesh Pillay From daniel.is.fischer at web.de Sun Aug 24 14:27:25 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sun Aug 24 14:24:05 2008 Subject: [Haskell-beginners] Puzzling type error In-Reply-To: <48B19CA8.8090406@webafrica.org.za> References: <48B19CA8.8090406@webafrica.org.za> Message-ID: <200808242027.25677.daniel.is.fischer@web.de> Am Sonntag, 24. August 2008 19:38 schrieb Logesh Pillay: > I've written the following implementation of the algorithm in this > article http://www.afjarvis.staff.shef.ac.uk/maths/jarvisspec02.pdf > > sqRoot n scale = sqRoot' (5*n) 5 > where > sqRoot' a b > > | floor (logBase 10 b) >= scale = div b 10 > | a >= b = sqRoot' (a-b) (b+10) > | otherwise = sqRoot' (a*100) ((100 * (div b > > 10)) + (mod b 10)) > > Since this involves whole numbers only, I was surprised by the following > run-time error. > > *Main> sqRoot 2 5 > > :1:0: > Ambiguous type variable `t' in the constraints: > `RealFrac t' arising from a use of `sqRoot' at :1:0-9 > `Floating t' arising from a use of `sqRoot' at :1:0-9 > `Integral t' arising from a use of `sqRoot' at :1:0-9 > Probable fix: add a type signature that fixes these type variable(s) > > What am I missing? > > Logesh Pillay > There is no automatic conversion between different numeric types, you must do that explicitly, except for numeric literals. From the guard a >= b (and the expression a-b) follows that a and b must have the same type. From the expressions (b `div` 10) and (b `mod` 10) follows that that type must belong to the type class Integral. From the use of logBase follows that that type must belong to the type class Floating. Finally, from the use of floor follows that that type must also belong to the type class RealFrac. If you ask GHCi for the type of sqRoot, it will tell you: *Main> :t sqRoot sqRoot :: (Integral t, Floating t, RealFrac t, Integral b) => t -> b -> t The problem occurs when you want to evaluate sqRoot, because then the types t and b must be decided. Since only standard numeric type classes are involved, GHCi is willing to default the ambiguous types, so it will look if it can find a type which simultaneously belongs to all three type classes in the default list (I think the default list GHCi uses is (Integer, Double)). Of course it doesn't find such a type, so it complains. Note, however, that it doesn't complain about the scale parameter, that can be defaulted to Integer without any problem. The ugly (and insane) fix would be to provide instances of Fractional, RealFrac and Floating for Integer or an instance of Integral for Double. The good fix is to insert calls to the apprpriate conversion function where necessary, for example sqRoot n scale = sqRoot' (5*n) 5 where sqRoot' a b | floor (logBase 10 $ fromIntegral b) >= scale = div b 10 | a >= b = sqRoot' (a-b) (b+10) | otherwise = sqRoot' (a*100) ((100 * (div b 10)) + (mod b 10)) works. HTH, Daniel From gale at sefer.org Sun Aug 24 14:25:40 2008 From: gale at sefer.org (Yitzchak Gale) Date: Sun Aug 24 14:24:21 2008 Subject: [Haskell-beginners] Puzzling type error In-Reply-To: <48B19CA8.8090406@webafrica.org.za> References: <48B19CA8.8090406@webafrica.org.za> Message-ID: <2608b8a80808241125u3c9f5c41kf3ccc2a7fba5d9c9@mail.gmail.com> Logesh Pillay wrote: > Since this involves whole numbers only, I was surprised by the following > run-time error... The type of logBase is Floating a => a -> a -> a So by using b as an argument to logBase, you are forcing it to be in a type that is an instance of Floating. Use "fromIntegral b". Regards, Yitz From emmanuel.delaborde at cimex.com Sun Aug 24 15:23:14 2008 From: emmanuel.delaborde at cimex.com (Emmanuel) Date: Sun Aug 24 15:22:01 2008 Subject: [Haskell-beginners] plugins package Message-ID: <182C0728-B4EA-49A7-9F15-007352B1F710@cimex.com> Hello I am having troubles bulding the plugins package : manu:~/Desktop/tmp manu$ cabal install plugins Resolving dependencies... cabal: cannot configure plugins-1.2. It requires ghc >=6.8 There is no available version of ghc that satisfies >=6.8 I am on a Mac PPC (OS X 10.4) with ghc-6.8.2 and Cabal-1.4.0.1 so the error message is puzzling... Can anyone help ? I'd like to install Lambdabot and plugins is one of the dependencies... Thanks Manu From daniel.is.fischer at web.de Sun Aug 24 15:43:41 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Sun Aug 24 15:40:19 2008 Subject: [Haskell-beginners] plugins package In-Reply-To: <182C0728-B4EA-49A7-9F15-007352B1F710@cimex.com> References: <182C0728-B4EA-49A7-9F15-007352B1F710@cimex.com> Message-ID: <200808242143.41312.daniel.is.fischer@web.de> Am Sonntag, 24. August 2008 21:23 schrieb Emmanuel: > Hello > > I am having troubles bulding the plugins package : > > manu:~/Desktop/tmp manu$ cabal install plugins > Resolving dependencies... > cabal: cannot configure plugins-1.2. It requires ghc >=6.8 That is the ghc-api package, of which it requires a version >= 6.8. Could you verify that you have it installed (ghc-pkg list will tell you what you have)? > There is no available version of ghc that satisfies >=6.8 > > > I am on a Mac PPC (OS X 10.4) with ghc-6.8.2 and Cabal-1.4.0.1 > > so the error message is puzzling... > Can anyone help ? I'd like to install Lambdabot and plugins is one of > the dependencies... > > Thanks > > Manu Cheers, Daniel From ajb at spamcop.net Sun Aug 24 21:07:53 2008 From: ajb at spamcop.net (ajb@spamcop.net) Date: Sun Aug 24 21:06:33 2008 Subject: [Haskell-beginners] Puzzling type error In-Reply-To: <200808242027.25677.daniel.is.fischer@web.de> References: <48B19CA8.8090406@webafrica.org.za> <200808242027.25677.daniel.is.fischer@web.de> Message-ID: <20080824210753.42c5u3ihw444gc8o-nwo@webmail.spamcop.net> G'day all. Quoting Daniel Fischer : > The good fix is to insert calls to the apprpriate conversion function where > necessary, for example > > sqRoot n scale = sqRoot' (5*n) 5 > where > sqRoot' a b > | floor (logBase 10 $ fromIntegral b) >= scale = div b 10 > | a >= b = sqRoot' (a-b) (b+10) > | otherwise = sqRoot' (a*100) ((100 * (div b 10)) + (mod b 10)) The problem here is that floating-point numbers do not have arbitrary precision, whereas Integers do. For very large numbers, the conversion might not be possible. Option #1: sqRoot n scale = sqRoot' (5*n) 5 where sqRoot' a b | b >= invScale = div b 10 | a >= b = sqRoot' (a-b) (b+10) | otherwise = sqRoot' (a*100) ((100 * (div b 10)) + (mod b 10)) invScale = 10^scale Option #2: sqRoot n scale = sqRoot' (5*n) 5 where sqRoot' a b | length (show b) >= scale = div b 10 -- May be an off-by-one error here. | a >= b = sqRoot' (a-b) (b+10) | otherwise = sqRoot' (a*100) ((100 * (div b 10)) + (mod b 10)) Sadly, option #2 (and option #3, not shown, which is essentially to implement your own integer-only floor-log-base-10) destroys the pretty "mostly subtraction only" property of the algorithm. Cheers, Andrew Bromage From ajb at spamcop.net Sun Aug 24 21:59:41 2008 From: ajb at spamcop.net (ajb@spamcop.net) Date: Sun Aug 24 21:58:21 2008 Subject: [Haskell-beginners] Puzzling type error In-Reply-To: <20080824210753.42c5u3ihw444gc8o-nwo@webmail.spamcop.net> References: <48B19CA8.8090406@webafrica.org.za> <200808242027.25677.daniel.is.fischer@web.de> <20080824210753.42c5u3ihw444gc8o-nwo@webmail.spamcop.net> Message-ID: <20080824215941.a2nxb4dqss88o8ok-nwo@webmail.spamcop.net> G'day all. One more thing, a quick comment on Haskell style. I wrote: > sqRoot n scale = sqRoot' (5*n) 5 > where > sqRoot' a b > | b >= invScale = div b 10 > | a >= b = sqRoot' (a-b) (b+10) > | otherwise = sqRoot' (a*100) ((100 * (div b 10)) + (mod b 10)) > invScale = 10^scale In this kind of algorithm, you are almost always better off decoupling the end-of-loop test from the main computation stuff: sqRoot n scale = findEnd (sqRoot' (5*n) 5) where findEnd ((a,b):rest) | b >= 10^scale = b `div` 10 | otherwise = findEnd rest -- Rewrote this a bit. I don't like the "case" sqRoot' a b = (a,b) : case () of _ | a >= b -> sqRoot' (a - b) (b + 10) otherwise -> let (q,r) = b `divMod` 10 in sqRoot' (a * 100) (100 * q + r) There are several reasons why this is better. The main one is testability. You have, in your specification, an execution trace of the algorithm on some sample data. Use it. A second reason is because you would have tracked down your type error quicker, because it would only have been in one of these functions. A third reason is that there are circumstances where you might like to change termination conditions. This is especially true in this sort of numeric iterate-to-fixpoint algorithm. For more information, see: http://www.haskell.org/haskellwiki/Data_structures_not_functions Cheers, Andrew Bromage From chompmotte at yahoo.fr Sun Aug 24 15:11:03 2008 From: chompmotte at yahoo.fr (chomp) Date: Sun Aug 24 22:17:25 2008 Subject: [Haskell-beginners] plugins package Message-ID: Hello I am having troubles bulding the plugins package : manu:~/Desktop/tmp manu$ cabal install plugins Resolving dependencies... cabal: cannot configure plugins-1.2. It requires ghc >=6.8 There is no available version of ghc that satisfies >=6.8 I am on a Mac PPC (OS X 10.4) with ghc-6.8.2 and Cabal-1.4.0.1 so the error message is puzzling... Can anyone help ? I'd like to install Lambdabot and plugins is one of the dependencies... Thanks Manu From lpillay at webafrica.org.za Mon Aug 25 01:14:12 2008 From: lpillay at webafrica.org.za (Logesh Pillay) Date: Mon Aug 25 01:15:08 2008 Subject: [Haskell-beginners] Re:Re Puzzling type erros Message-ID: <48B23FA4.1030507@webafrica.org.za> Thanks, chaps, for the replies to my over-hasty post. I should have checked with a power of 10 value for scale which would have pointed to types to logBase as the error. Andrew's comment about floating point not having unlimited precision clears up a glitch that using fromInteger introduces. If you use it to typecast b, it appears to set a limit to the number of digits it generates. It only gives you 308 or so even if you set scale equal to 1000, say. If you test b against 10^scale, you get as many digits as you wish. Logesh Pillay > Message: 10 > Date: Sun, 24 Aug 2008 21:07:53 -0400 > From: ajb@spamcop.net > Subject: Re: [Haskell-beginners] Puzzling type error > To: beginners@haskell.org > Message-ID: <20080824210753.42c5u3ihw444gc8o-nwo@webmail.spamcop.net> > Content-Type: text/plain; charset=ISO-8859-1; DelSp="Yes"; > format="flowed" > > G'day all. > > Quoting Daniel Fischer : > > >> > The good fix is to insert calls to the apprpriate conversion function where >> > necessary, for example >> > >> > sqRoot n scale = sqRoot' (5*n) 5 >> > where >> > sqRoot' a b >> > | floor (logBase 10 $ fromIntegral b) >= scale = div b 10 >> > | a >= b = sqRoot' (a-b) (b+10) >> > | otherwise = sqRoot' (a*100) ((100 * (div b 10)) + (mod b 10)) >> > > The problem here is that floating-point numbers do not have arbitrary > precision, whereas Integers do. For very large numbers, the > conversion might not be possible. > > Option #1: > > sqRoot n scale = sqRoot' (5*n) 5 > where > sqRoot' a b > | b >= invScale = div b 10 > | a >= b = sqRoot' (a-b) (b+10) > | otherwise = sqRoot' (a*100) ((100 * (div b 10)) + (mod b 10)) > invScale = 10^scale > > Option #2: > > sqRoot n scale = sqRoot' (5*n) 5 > where > sqRoot' a b > | length (show b) >= scale = div b 10 -- May be an off-by-one error here. > | a >= b = sqRoot' (a-b) (b+10) > | otherwise = sqRoot' (a*100) ((100 * (div b 10)) + (mod b 10)) > > Sadly, option #2 (and option #3, not shown, which is essentially to > implement your own integer-only floor-log-base-10) destroys the > pretty "mostly subtraction only" property of the algorithm. > > Cheers, > Andrew Bromage > From apfelmus at quantentunnel.de Mon Aug 25 04:02:47 2008 From: apfelmus at quantentunnel.de (apfelmus) Date: Mon Aug 25 04:01:43 2008 Subject: [Haskell-beginners] How does the type of "ap = liftM2 id" work? In-Reply-To: <5D76C3FE-983D-4C5D-A892-5D9DDD7ACF53@ece.cmu.edu> References: <5D76C3FE-983D-4C5D-A892-5D9DDD7ACF53@ece.cmu.edu> Message-ID: Brandon S. Allbery KF8NH wrote: > Quergle Quergle wrote: > >> My intuitive understanding is that liftM2 is expecting a two-argument >> function as its first argument, so it seems a little unexpected to >> pass it "id", a one-argument function. > > And because in > Haskell a multiple-argument function is identical to a single-argument > function returning a single-argument function, the type of "id" > encompasses any number of arguments. In other words, there are no two-argument functions in Haskell anyway. Every function has only one argument. Regards, apfelmus From arind_roy at fast-mail.org Mon Aug 25 08:12:25 2008 From: arind_roy at fast-mail.org (Arindam Roy) Date: Mon Aug 25 08:11:03 2008 Subject: [Haskell-beginners] Help with monad syntax? Message-ID: <1219666345.12781.1270353523@webmail.messagingengine.com> I'm trying to learn Haskell using Hutton's book and Hugs (Sep 06), and am trying to work the parsing examples (chapter 8, Functional parsers), but I can't understand the error I'm seeing when I try to load the program into Hugs. Following the book, I've defined a Parser type, then written the basic parsers, then a sequencing operator >>=, followed by the example p parser (bottom of page 77). However, trying to load this file in Hugs generates an error (caused by the definition of p). I've given below the entire file I've created and the error message I get on trying to load it. Any help much appreciated - Arindam ---------------------------------------- type Parser a = String -> [(a, String)] return :: a -> Parser a return v = \inp -> [(v, inp)] failure :: Parser a failure = \inp -> [] item :: Parser Char item = \inp -> case inp of [] -> [] (x:xs) -> [(x, xs)] parse :: Parser a -> String -> [(a, String)] parse p inp = p inp (>>=) :: Parser a -> (a -> Parser b) -> Parser b p >>= f = \inp -> case parse p inp of [] -> [] [(v, out)] -> parse (f v) out p :: Parser (Char, Char) p = do x <- item item y <- item Main.return (x, y) ------------------------------------------ Hugs> :r ERROR file:c:\parsers.hs:23 - Type error in explicitly typed binding *** Term : p *** Type : [Char] -> [(([(Char,[Char])],[(Char,[Char])]),[Char])] *** Does not match : Parser (Char,Char) Hugs> -- Arindam Roy arind_roy@fast-mail.org -- http://www.fastmail.fm - IMAP accessible web-mail From rendel at daimi.au.dk Mon Aug 25 10:29:08 2008 From: rendel at daimi.au.dk (Tillmann Rendel) Date: Mon Aug 25 10:27:45 2008 Subject: [Haskell-beginners] Help with monad syntax? In-Reply-To: <1219666345.12781.1270353523@webmail.messagingengine.com> References: <1219666345.12781.1270353523@webmail.messagingengine.com> Message-ID: <48B2C1B4.3050902@daimi.au.dk> Arindam Roy wrote: > I'm trying to learn Haskell using Hutton's book and Hugs (Sep 06), > and am trying to work the parsing examples (chapter 8, Functional > parsers), but I can't understand the error I'm seeing when I try to > load the program into Hugs. > > Following the book, I've defined a Parser type, then written the basic > parsers, then a sequencing operator >>=, followed by the example p > parser (bottom of page 77). However, trying to load this file in Hugs > generates an error (caused by the definition of p). To make do notation work, you have to (1) use a data type for Parser (instead of a type synonym) and (2) declare that data type an instance of the Monad typeclass. Your code should look something like this: data Parser = Parser (...) instance Monad Parser where return v = ... Parser p >>= f = ... ... > (>>=) :: Parser a -> (a -> Parser b) -> Parser b > p >>= f = \inp -> case parse p inp of > [] -> [] > [(v, out)] -> parse (f v) out What happens if p returns more then one result? Tillmann From quergle at googlemail.com Tue Aug 26 02:34:39 2008 From: quergle at googlemail.com (Quergle Quergle) Date: Tue Aug 26 02:33:16 2008 Subject: [Haskell-beginners] Re: How does the type of "ap = liftM2 id" work? In-Reply-To: References: Message-ID: Thanks for the replies, that's much clearer now. Cheers, -- Matt From arind_roy at fast-mail.org Tue Aug 26 03:44:14 2008 From: arind_roy at fast-mail.org (Arindam Roy) Date: Tue Aug 26 04:08:44 2008 Subject: [Haskell-beginners] Help with monad syntax? References: <1219666345.12781.1270353523@webmail.messagingengine.com> <48B2C1B4.3050902@daimi.au.dk> Message-ID: > To make do notation work, you have to > > (1) use a data type for Parser (instead of a type synonym) and > (2) declare that data type an instance of the Monad typeclass. > > Your code should look something like this: > > data Parser = Parser (...) > instance Monad Parser where > return v = ... > Parser p >>= f = ... > > ... Thanks, I'll try this. I haven't read upto the data declaration and inheritance yet, but I'll try it as soon as I have :-) > > > (>>=) :: Parser a -> (a -> Parser b) -> Parser b > > p >>= f = \inp -> case parse p inp of > > [] -> [] > > [(v, out)] -> parse (f v) out > > What happens if p returns more then one result? > The way Parsers are designed in the book, it can't. Parsers always return a list with one element. The only reason the return value is a list is to use the empty list as an error indication. Arindam From paul.a.johnston at manchester.ac.uk Tue Aug 26 05:39:42 2008 From: paul.a.johnston at manchester.ac.uk (Paul Johnston) Date: Tue Aug 26 05:36:23 2008 Subject: [Haskell-beginners] ord Message-ID: <48B3CF5E.3000309@manchester.ac.uk> Hi Using the book by Hutton and in chapter 5 it talks about 'ord' and 'chr' being in the standard prelude. paulj@opensolaris4:~$ ghci GHCi, version 6.8.3: http://www.haskell.org/ghc/ :? for help Loading package base ... linking ... done. Prelude> ord 3 :1:0: Not in scope: `ord' Prelude> chr 67 :1:0: Not in scope: `chr' Prelude> They seem to do what you would expect from their perl counterparts Any ideas? Cheers Paul From a.d.clark at ed.ac.uk Tue Aug 26 05:53:29 2008 From: a.d.clark at ed.ac.uk (allan) Date: Tue Aug 26 05:50:45 2008 Subject: [Haskell-beginners] ord In-Reply-To: <48B3CF5E.3000309@manchester.ac.uk> References: <48B3CF5E.3000309@manchester.ac.uk> Message-ID: <48B3D299.4010503@ed.ac.uk> Hi These are both defined in the module Data.Char, I guess they were in the Prelude when the book was written. GHCi, version 6.8.3: http://www.haskell.org/ghc/ :? for help Loading package base ... linking ... done. Prelude> :m Data.Char Prelude Data.Char> ord 'a' 97 Prelude Data.Char> chr 97 'a' Prelude Data.Char> Remember you can use hoogle to look up library functions: http://haskell.org/hoogle/ regards allan Paul Johnston wrote: > Hi > Using the book by Hutton and in chapter 5 it talks about 'ord' and 'chr' > being in the standard prelude. > > paulj@opensolaris4:~$ ghci > GHCi, version 6.8.3: http://www.haskell.org/ghc/ :? for help > Loading package base ... linking ... done. > Prelude> ord 3 > > :1:0: Not in scope: `ord' > Prelude> chr 67 > > :1:0: Not in scope: `chr' > Prelude> > > They seem to do what you would expect from their perl counterparts > Any ideas? > > Cheers Paul > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > -- The University of Edinburgh is a charitable body, registered in Scotland, with registration number SC005336. From RafaelGCPP.Linux at gmail.com Tue Aug 26 11:43:31 2008 From: RafaelGCPP.Linux at gmail.com (Rafael Gustavo da Cunha Pereira Pinto) Date: Tue Aug 26 11:42:07 2008 Subject: [Haskell-beginners] findSubstring deprecated Message-ID: <351ff25e0808260843w717729d3l9759e4839418b587@mail.gmail.com> Two quick questions: 1) Is there any replacement for the (now deprecated) findSubstring function on ByteString.Char8? 2) Does it work with ByteString.Lazy.Char8? Best Regards, Rafael Gustavo da Cunha Pereira Pinto Electronic Engineer, MSc. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080826/9e85c7a5/attachment.htm From daniel.is.fischer at web.de Tue Aug 26 17:43:02 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Tue Aug 26 17:39:37 2008 Subject: [Haskell-beginners] findSubstring deprecated In-Reply-To: <351ff25e0808260843w717729d3l9759e4839418b587@mail.gmail.com> References: <351ff25e0808260843w717729d3l9759e4839418b587@mail.gmail.com> Message-ID: <200808262343.02637.daniel.is.fischer@web.de> Am Dienstag, 26. August 2008 17:43 schrieb Rafael Gustavo da Cunha Pereira Pinto: > Two quick questions: > > 1) Is there any replacement for the (now deprecated) findSubstring function > on ByteString.Char8? > 2) Does it work with ByteString.Lazy.Char8? > > Best Regards, > > > Rafael Gustavo da Cunha Pereira Pinto > Electronic Engineer, MSc. Use the stringsearch package: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/stringsearch That has pretty fast stringsearch functions (usually, Boyer-Moore is faster than Knuth-Morris-Pratt) for strict and lazy ByteStrings. I'm not sure if it works on ByteString(.Lazy).Char8, too, or only on Word8 ByteStrings, but it would be trivial to adapt, just change the import. There's one thing to be aware of, however, if there are overlapping occurences of the searched-for string, KMP reports only the first of their indices, BM all. Maybe we should complete it and also add search&replace functions? Cheers, Daniel From rafaelgcpp at gmail.com Wed Aug 27 07:19:01 2008 From: rafaelgcpp at gmail.com (Rafael Gustavo da Cunha Pereira Pinto) Date: Wed Aug 27 07:17:44 2008 Subject: [Haskell-beginners] findSubstring deprecated In-Reply-To: <200808262343.02637.daniel.is.fischer@web.de> References: <351ff25e0808260843w717729d3l9759e4839418b587@mail.gmail.com> <200808262343.02637.daniel.is.fischer@web.de> Message-ID: <351ff25e0808270419g18138d15p1bf562f752d8a1e7@mail.gmail.com> Thanks! Either KMP or BM are good for me as I will probably do a (take 1 $ matchSL pat list) on it. KMP is O(n+m), right? Regards, Rafael On Tue, Aug 26, 2008 at 18:43, Daniel Fischer wrote: > Am Dienstag, 26. August 2008 17:43 schrieb Rafael Gustavo da Cunha Pereira > Pinto: > > Two quick questions: > > > > 1) Is there any replacement for the (now deprecated) findSubstring > function > > on ByteString.Char8? > > 2) Does it work with ByteString.Lazy.Char8? > > > > Best Regards, > > > > > > Rafael Gustavo da Cunha Pereira Pinto > > Electronic Engineer, MSc. > > Use the stringsearch package: > http://hackage.haskell.org/cgi-bin/hackage-scripts/package/stringsearch > > That has pretty fast stringsearch functions (usually, Boyer-Moore is faster > than Knuth-Morris-Pratt) for strict and lazy ByteStrings. > I'm not sure if it works on ByteString(.Lazy).Char8, too, or only on Word8 > ByteStrings, but it would be trivial to adapt, just change the import. > > There's one thing to be aware of, however, if there are overlapping > occurences > of the searched-for string, KMP reports only the first of their indices, BM > all. > > Maybe we should complete it and also add search&replace functions? > > Cheers, > Daniel > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > -- Rafael Gustavo da Cunha Pereira Pinto Electronic Engineer, MSc. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080827/bead38d6/attachment.htm From rafaelgcpp at gmail.com Wed Aug 27 07:54:21 2008 From: rafaelgcpp at gmail.com (Rafael Gustavo da Cunha Pereira Pinto) Date: Wed Aug 27 07:52:53 2008 Subject: [Haskell-beginners] Functional programming concepts Message-ID: <351ff25e0808270454i6d53909xa0f30b8f71d9c99f@mail.gmail.com> Hi folks! Since I don't have a CS degree, there are some concepts I don't fully understand, and I'd like to propose a "begginers" thread to discuss some of those topics. For starters, what does a WHNF (weak-head normal form) mean? Cheers, -- Rafael Gustavo da Cunha Pereira Pinto Electronic Engineer, MSc. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080827/2e526077/attachment.htm From daniel.is.fischer at web.de Wed Aug 27 10:33:22 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Aug 27 10:29:52 2008 Subject: [Haskell-beginners] Functional programming concepts In-Reply-To: <351ff25e0808270454i6d53909xa0f30b8f71d9c99f@mail.gmail.com> References: <351ff25e0808270454i6d53909xa0f30b8f71d9c99f@mail.gmail.com> Message-ID: <200808271633.22991.daniel.is.fischer@web.de> Am Mittwoch, 27. August 2008 13:54 schrieb Rafael Gustavo da Cunha Pereira Pinto: > Hi folks! > > Since I don't have a CS degree, there are some concepts I don't fully > understand, and I'd like to propose a "begginers" thread to discuss some of > those topics. > > For starters, what does a WHNF (weak-head normal form) mean? > > Cheers, > -- > Rafael Gustavo da Cunha Pereira Pinto > Electronic Engineer, MSc. You can find a definition at http://burks.bton.ac.uk/burks/foldoc/53/126.htm It's not entirely helpful if you don't know some lambda-calculus. I don't have a CS degree either, so someone please correct me if I'm wrong (or confirm if I'm right). In Haskell, reducing a term to whnf (which e.g. seq is for) means evaluating it far enough that its top level constructor is known (or it's found to be bottom). For some types like Int, that means complete evaluation, for others it's far less. A list is in whnf if you know whether it's bottom, [] or h:t, where you might or might not know something about h and t. A Maybe term is in whnf if you know if it's bottom, Nothing or Just whatever. A function is in whnf if you know if it's bottom or \x -> rhs. HTH, Daniel From rendel at daimi.au.dk Wed Aug 27 10:42:45 2008 From: rendel at daimi.au.dk (Tillmann Rendel) Date: Wed Aug 27 10:41:18 2008 Subject: [Haskell-beginners] Functional programming concepts In-Reply-To: <200808271633.22991.daniel.is.fischer@web.de> References: <351ff25e0808270454i6d53909xa0f30b8f71d9c99f@mail.gmail.com> <200808271633.22991.daniel.is.fischer@web.de> Message-ID: <48B567E5.4070505@daimi.au.dk> Daniel Fischer wrote: > I don't have a CS degree either, so someone please correct me if I'm wrong (or > confirm if I'm right). > In Haskell, reducing a term to whnf (which e.g. seq is for) means evaluating > it far enough that its top level constructor is known (or it's found to be > bottom). > For some types like Int, that means complete evaluation, for others it's far > less. > A list is in whnf if you know whether it's bottom, [] or h:t, where you might > or might not know something about h and t. > A Maybe term is in whnf if you know if it's bottom, Nothing or Just whatever. > A function is in whnf if you know if it's bottom or \x -> rhs. That's correct, but be careful with your use of the term bottom. Most bottoms are never "found to be bottom", but instead, the program runs forever trying to find the top-level constructor. Another thing: you do not need seq to evaluate something to whnf, you can just pattern match on the top-level constructor instead. seq is there for polymorphic values where you cannot pattern match since you don't know the possible constructors. Pattern matching is the main mechanism in Haskell to trigger evaluation. Tillmann From daniel.is.fischer at web.de Wed Aug 27 10:47:42 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Aug 27 10:44:12 2008 Subject: [Haskell-beginners] findSubstring deprecated In-Reply-To: <351ff25e0808270419g18138d15p1bf562f752d8a1e7@mail.gmail.com> References: <351ff25e0808260843w717729d3l9759e4839418b587@mail.gmail.com> <200808262343.02637.daniel.is.fischer@web.de> <351ff25e0808270419g18138d15p1bf562f752d8a1e7@mail.gmail.com> Message-ID: <200808271647.42046.daniel.is.fischer@web.de> Am Mittwoch, 27. August 2008 13:19 schrieb Rafael Gustavo da Cunha Pereira Pinto: > Thanks! > > Either KMP or BM are good for me as I will probably do a (take 1 $ matchSL > pat list) on it. > > KMP is O(n+m), right? Yes, and it doesn't have bad constant factors, but take into account the last paragraphs of http://en.wikipedia.org/wiki/Knuth-Morris-Pratt_algorithm to decide which one to use. > > Regards, > Rafael Cheers, Daniel From daniel.is.fischer at web.de Wed Aug 27 11:37:11 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Aug 27 11:33:42 2008 Subject: [Haskell-beginners] Functional programming concepts In-Reply-To: <48B567E5.4070505@daimi.au.dk> References: <351ff25e0808270454i6d53909xa0f30b8f71d9c99f@mail.gmail.com> <200808271633.22991.daniel.is.fischer@web.de> <48B567E5.4070505@daimi.au.dk> Message-ID: <200808271737.11485.daniel.is.fischer@web.de> Am Mittwoch, 27. August 2008 16:42 schrieb Tillmann Rendel: > Daniel Fischer wrote: > > I don't have a CS degree either, so someone please correct me if I'm > > wrong (or confirm if I'm right). > > In Haskell, reducing a term to whnf (which e.g. seq is for) means > > evaluating it far enough that its top level constructor is known (or it's > > found to be bottom). > > For some types like Int, that means complete evaluation, for others it's > > far less. > > A list is in whnf if you know whether it's bottom, [] or h:t, where you > > might or might not know something about h and t. > > A Maybe term is in whnf if you know if it's bottom, Nothing or Just > > whatever. A function is in whnf if you know if it's bottom or \x -> rhs. > > That's correct, but be careful with your use of the term bottom. Most > bottoms are never "found to be bottom", but instead, the program runs > forever trying to find the top-level constructor. Distinguish between findable and unfindable bottoms? The difference in practice is clear, but is there also a theoretical difference? > > Another thing: you do not need seq to evaluate something to whnf, you > can just pattern match on the top-level constructor instead. Yes, what I wanted to convey was that seq doesn't fully evaluate its first argument but only reduces it to whnf. Failed on that point :( > seq is there for polymorphic values where you cannot pattern match > since you don't know the possible constructors. Pattern matching is > the main mechanism in Haskell to trigger evaluation. > > Tillmann Cheers, Daniel From rendel at daimi.au.dk Wed Aug 27 11:58:44 2008 From: rendel at daimi.au.dk (Tillmann Rendel) Date: Wed Aug 27 11:57:11 2008 Subject: [Haskell-beginners] Functional programming concepts In-Reply-To: <200808271737.11485.daniel.is.fischer@web.de> References: <351ff25e0808270454i6d53909xa0f30b8f71d9c99f@mail.gmail.com> <200808271633.22991.daniel.is.fischer@web.de> <48B567E5.4070505@daimi.au.dk> <200808271737.11485.daniel.is.fischer@web.de> Message-ID: <48B579B4.6000504@daimi.au.dk> Daniel Fischer wrote: > Distinguish between findable and unfindable bottoms? > The difference in practice is clear, but is there also a theoretical > difference? That depends on the theory you choose. If you're only interested in non-bottom results anyway, you can choose to use a simple theory (that is: a simple formal semantic) which doesn't distinguish between non-termination and other errors. If you're interested in modeling error-handling, you should probably use a semantic which does distinguish different kinds of errors. A denotational semantics which takes errors into account could use the error monad similar to how you use it in Haskell for explicit error handling. In fact, monads in CS where first introduced for denotational semantics, before they where applied to functional programming. That means that you have a choice: Avoid findable bottoms by using explicit error handling with error monads in your program, so that you can use a simpler semantics to understand your code. Or use findable bottoms to encode errors, and use an error monad to upgrade your semantics to cope with them. I prefer to use the monads in my Haskell code, and not in my head (where the semantics is processed in the code understanding cycles of my programming process). Tillmann From rafaelgcpp at gmail.com Wed Aug 27 12:43:48 2008 From: rafaelgcpp at gmail.com (Rafael Gustavo da Cunha Pereira Pinto) Date: Wed Aug 27 12:42:21 2008 Subject: [Haskell-beginners] Functional programming concepts In-Reply-To: <200808271633.22991.daniel.is.fischer@web.de> References: <351ff25e0808270454i6d53909xa0f30b8f71d9c99f@mail.gmail.com> <200808271633.22991.daniel.is.fischer@web.de> Message-ID: <351ff25e0808270943u5199c299h4ac988e99f802a13@mail.gmail.com> > > > You can find a definition at > http://burks.bton.ac.uk/burks/foldoc/53/126.htm > It's not entirely helpful if you don't know some lambda-calculus. > > Thanks Daniel, Is there any easy to follow Lambda Calculus (intro-level) tutorial? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080827/dd078f85/attachment.htm From emmanuel.delaborde at cimex.com Wed Aug 27 15:31:40 2008 From: emmanuel.delaborde at cimex.com (Emmanuel) Date: Wed Aug 27 15:30:22 2008 Subject: [Haskell-beginners] Re: Beginners Digest, Vol 2, Issue 7 In-Reply-To: <20080825010634.DE50A3243DF@www.haskell.org> References: <20080825010634.DE50A3243DF@www.haskell.org> Message-ID: <02F2AFF6-5C48-45FD-B6C1-21906AC0EE7F@cimex.com> >> >> I am having troubles bulding the plugins package : >> >> manu:~/Desktop/tmp manu$ cabal install plugins >> Resolving dependencies... >> cabal: cannot configure plugins-1.2. It requires ghc >=6.8 > > That is the ghc-api package, of which it requires a version >= 6.8. > Could you verify that you have it installed (ghc-pkg list will tell > you what > you have)? it's not listed by ghc-pkg list, I have ... {ghc-6.8.1}, {ghc-6.8.2} ... where do I get it ? It's not listed on Hackage Thanks Emmanuel From daniel.is.fischer at web.de Wed Aug 27 15:40:22 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Aug 27 15:36:49 2008 Subject: [Haskell-beginners] Functional programming concepts In-Reply-To: <351ff25e0808270943u5199c299h4ac988e99f802a13@mail.gmail.com> References: <351ff25e0808270454i6d53909xa0f30b8f71d9c99f@mail.gmail.com> <200808271633.22991.daniel.is.fischer@web.de> <351ff25e0808270943u5199c299h4ac988e99f802a13@mail.gmail.com> Message-ID: <200808272140.22369.daniel.is.fischer@web.de> Am Mittwoch, 27. August 2008 18:43 schrieb Rafael Gustavo da Cunha Pereira Pinto: > > You can find a definition at > > http://burks.bton.ac.uk/burks/foldoc/53/126.htm > > It's not entirely helpful if you don't know some lambda-calculus. > > Thanks Daniel, > > Is there any easy to follow Lambda Calculus (intro-level) tutorial? I don't know any :( The wikipedia article might be helpful and also some of the links at the bottom. I took a look at some of them and found none entirely convincing, but also none definitely bad. Cheers, Daniel From daniel.is.fischer at web.de Wed Aug 27 16:15:50 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Aug 27 16:12:17 2008 Subject: [Haskell-beginners] plugins package In-Reply-To: <02F2AFF6-5C48-45FD-B6C1-21906AC0EE7F@cimex.com> References: <20080825010634.DE50A3243DF@www.haskell.org> <02F2AFF6-5C48-45FD-B6C1-21906AC0EE7F@cimex.com> Message-ID: <200808272215.50019.daniel.is.fischer@web.de> Am Mittwoch, 27. August 2008 21:31 schrieb Emmanuel: > >> I am having troubles bulding the plugins package : > >> > >> manu:~/Desktop/tmp manu$ cabal install plugins > >> Resolving dependencies... > >> cabal: cannot configure plugins-1.2. It requires ghc >=6.8 > > > > That is the ghc-api package, of which it requires a version >= 6.8. > > Could you verify that you have it installed (ghc-pkg list will tell > > you what > > you have)? > > it's not listed by ghc-pkg list, I have ... {ghc-6.8.1}, {ghc-6.8.2} ... > where do I get it ? It's not listed on Hackage If the output of your ghc-pkg list contains something like filepath-1.1.0.0, (ghc-6.8.2), haskell-src-1.0.1.1, you have the package (the parentheses indicate that it's hidden), version 6.8.2 in this case, which clearly should be >= 6.8. Then I don't know what the problem is, maybe it would work if you manually exposed the package before cabal installing, but I doubt it. Have you tried to manually go through the runghc Setup.lhs configure / build / install routine? If your version of cabal install isn't new enough, have you already tried upgrading that? If nothing helps, ask on Haskell-cafe, there are people familiar with the workings of cabal there. > > Thanks > > Emmanuel Cheers, Daniel From RafaelGCPP.Linux at gmail.com Wed Aug 27 19:46:44 2008 From: RafaelGCPP.Linux at gmail.com (Rafael Gustavo da Cunha Pereira Pinto) Date: Wed Aug 27 19:45:14 2008 Subject: [Haskell-beginners] ICFP 2007 Message-ID: <351ff25e0808271646k4188e52wac01169eedd7ee47@mail.gmail.com> First of all, sorry asking too many questions! I am using the ICFP 2007 (http://save-endo.cs.uu.nl/) problem as a case for learning Haskell. I started with the prototype, listed below =================Main.hs======================= module Main(main) where import qualified Data.ByteString.Lazy.Char8 as L import qualified Data.ByteString.Char8 as S import Data.ByteString.Search.BoyerMoore as BM import Debug.Trace data DNA=DNA {prefix :: L.ByteString, suffix :: L.ByteString} main::IO () main=do d<-L.readFile "endo.dna" let dna=DNA (L.pack "IIIIIIIIIIICCICCICCICFFIIIIIIIIIIIIIIIICFP") d let pat=S.pack "ICFP" print $ take 1 $ matchSL pat $ L.append (prefix dna) (suffix dna) =================EOF Main.hs=================== My question is: Knowing that the searched pattern is in DNA prefix, will "suffix dna" ever be called here? I mean, will the "append" suspension ever be fully evaluated? I am thinking on using a data type like data DNA=DNA {prefix::L.ByteString, worked::L.ByteString, suffix::ByteString} The invariant is that worked should be L.empty whenever prefix is L.empty. Thanks in advance -- Rafael Gustavo da Cunha Pereira Pinto Electronic Engineer, MSc. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080827/3be4a8e4/attachment.htm From daniel.is.fischer at web.de Wed Aug 27 22:05:22 2008 From: daniel.is.fischer at web.de (Daniel Fischer) Date: Wed Aug 27 22:01:49 2008 Subject: [Haskell-beginners] ICFP 2007 In-Reply-To: <351ff25e0808271646k4188e52wac01169eedd7ee47@mail.gmail.com> References: <351ff25e0808271646k4188e52wac01169eedd7ee47@mail.gmail.com> Message-ID: <200808280405.22504.daniel.is.fischer@web.de> Am Donnerstag, 28. August 2008 01:46 schrieb Rafael Gustavo da Cunha Pereira Pinto: > First of all, sorry asking too many questions! That's what this list is for :) > > I am using the ICFP 2007 (http://save-endo.cs.uu.nl/) problem as a case for > learning Haskell. > > I started with the prototype, listed below > > > =================Main.hs======================= > module Main(main) where > > import qualified Data.ByteString.Lazy.Char8 as L > import qualified Data.ByteString.Char8 as S > > import Data.ByteString.Search.BoyerMoore as BM > import Debug.Trace > > data DNA=DNA {prefix :: L.ByteString, suffix :: L.ByteString} > > > main::IO () > main=do > d<-L.readFile "endo.dna" > let dna=DNA (L.pack "IIIIIIIIIIICCICCICCICFFIIIIIIIIIIIIIIIICFP") d > let pat=S.pack "ICFP" > print $ take 1 $ matchSL pat $ L.append (prefix dna) (suffix dna) > =================EOF Main.hs=================== > > > My question is: > > Knowing that the searched pattern is in DNA prefix, will "suffix dna" ever > be called here? > I mean, will the "append" suspension ever be fully evaluated? No. That's one nice thing about lazy ByteStrings. You only use as many chunks as you really need. L.append is lazy enough to survive even L.append (prefix dna) undefined. Unfortunately our BM searching algorithm isn't, an optimisation for the case of a lazy ByteString consisting of a single chunk requires that the second argument of L.append is reduced to WHNF (KMP doesn't), so it needs to read one chunk from the file. Hence in this case (suffix dna) is called, but only one chunk of it is used. You can verify this by running your programme with the option "+RTS -sstderr", which will print out some time and allocation stats. I did: dafis@linux:~/Documents/haskell/move> ghc -O2 --make endo [1 of 1] Compiling Main ( endo.hs, endo.o ) Linking endo ... dafis@linux:~/Documents/haskell/move> ./endo +RTS -sstderr ./endo +RTS -sstderr [38] 89,388 bytes allocated in the heap 520 bytes copied during GC (scavenged) 0 bytes copied during GC (not scavenged) 57,344 bytes maximum residency (1 sample(s)) Searching in L.append (prefix dna) (L.append (L.pack "u") (suffix dna)) gives the figures 56,604 bytes allocated in the heap 528 bytes copied during GC (scavenged) 8 bytes copied during GC (not scavenged) 57,344 bytes maximum residency (1 sample(s)) , so then no chunk (~32K on my system) needs to be read from the file. > > > I am thinking on using a data type like > > data DNA=DNA {prefix::L.ByteString, worked::L.ByteString, > suffix::ByteString} > > The invariant is that worked should be L.empty whenever prefix is L.empty. > > > Thanks in advance Cheers, Daniel From apfelmus at quantentunnel.de Thu Aug 28 03:22:52 2008 From: apfelmus at quantentunnel.de (apfelmus) Date: Thu Aug 28 03:21:36 2008 Subject: [Haskell-beginners] Functional programming concepts In-Reply-To: <351ff25e0808270943u5199c299h4ac988e99f802a13@mail.gmail.com> References: <351ff25e0808270454i6d53909xa0f30b8f71d9c99f@mail.gmail.com> <200808271633.22991.daniel.is.fischer@web.de> <351ff25e0808270943u5199c299h4ac988e99f802a13@mail.gmail.com> Message-ID: Rafael Gustavo da Cunha Pereira Pinto wrote: > > Is there any easy to follow Lambda Calculus (intro-level) tutorial? I don't really know one, but the following course notes L. Paulson. Foundations of Functional Programming. http://www.cl.cam.ac.uk/~lp15/papers/Notes/Founds-FP.pdf are pretty short and understandable. For the many possible reduction strategies and normal forms, see also P. Sestoft. Demonstrating Lambda Calculus Reduction. http://www.itu.dk/~sestoft/papers/sestoft-lamreduce.pdf Regards, apfelmus From rafaelgcpp at gmail.com Thu Aug 28 08:07:17 2008 From: rafaelgcpp at gmail.com (Rafael Gustavo da Cunha Pereira Pinto) Date: Thu Aug 28 08:05:47 2008 Subject: [Haskell-beginners] Re: [Haskell-cafe] Is there GHC 6.8.3 on Ubuntu? In-Reply-To: <87ljyhmzax.fsf@malde.org> References: <351ff25e0808271122o3086a896t671deebe97880cf4@mail.gmail.com> <87ljyhmzax.fsf@malde.org> Message-ID: <351ff25e0808280507i2284bc19oa64e1dc1b22c6dcd@mail.gmail.com> I'll take a look on how to build this package... Although I just want to use 6.8.3, I would really like to share my efforts. Now I just have to find a gap on my (and my wife's) agenda to do that! :-) Best regards On Thu, Aug 28, 2008 at 03:25, Ketil Malde wrote: > "Rafael Gustavo da Cunha Pereira Pinto" > writes: > > > Is there anyone packing GHC 6.8.3 for Ubuntu Hardy? > > The next Ubuntu release (8.10 Intrepid), seems to come with 6.8.2 as > well. > > If you want to pack 6.8.3, go for it! If you just wanted to use it, > I've had success using the binary snapshots on previous Ubuntus. > > -k > -- > If I haven't seen further, it is by standing in the footprints of giants > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > -- Rafael Gustavo da Cunha Pereira Pinto Electronic Engineer, MSc. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/beginners/attachments/20080828/ea65f8fe/attachment-0001.htm From vss at 73rus.com Thu Aug 28 18:37:56 2008 From: vss at 73rus.com (Vlad Skvortsov) Date: Thu Aug 28 18:36:32 2008 Subject: [Haskell-beginners] profiling in haskell Message-ID: <48B728C4.2040708@73rus.com> Hi! I'm trying to profile the code pasted below. Per the profiler output it takes about 30% of my program running time and I'd like to analyze it further. What I need is a breakdown on a finer level, so I inserted SCC annotations. However, they appear to have attributed zero cost. I use GHC 6.8.2 on FreeBSD, the code is compiled without -O options. What am I doing wrong? Note: I'm not trying to *optimize* this code (I intuitively know where the problems are). My intention is to learn the mechanics of profiling Haskell code. serialize :: Database -> [[String]] serialize (dmap, tmap) = [ {-# SCC "XXX1" #-} [dbFormatTag], {-# SCC "XXX2" #-} (dumpWith docToStr dmap), {-# SCC "XXX3" #-} (dumpWith termToStr tmap) ] where dumpWith f = Data.Map.foldWithKey f [] docToStr k (Doc { docName=n, docVectorLength=vl}) = (:) ("d " ++ show k ++ " " ++ n ++ " " ++ (show vl)) termToStr t il = (:) ("t " ++ t ++ " " ++ (foldl ilItemToStr "" il)) ilItemToStr acc (docid, weight) = show docid ++ ":" ++ show weight ++ " " ++ acc -- Vlad Skvortsov, vss@73rus.com, http://vss.73rus.com From jgbailey at gmail.com Fri Aug 29 00:11:36 2008 From: jgbailey at gmail.com (Justin Bailey) Date: Fri Aug 29 02:50:48 2008 Subject: [Haskell-beginners] profiling in haskell In-Reply-To: <48B728C4.2040708@73rus.com> References: <48B728C4.2040708@73rus.com> Message-ID: On Thu, Aug 28, 2008 at 3:37 PM, Vlad Skvortsov wrote: > Hi! > > I'm trying to profile the code pasted below. Per the profiler output it > takes about 30% of my program running time and I'd like to analyze it > further. What I need is a breakdown on a finer level, so I inserted SCC > annotations. However, they appear to have attributed zero cost. I use GHC > 6.8.2 on FreeBSD, the code is compiled without -O options. > > What am I doing wrong? You need more SCC annotations. > > Note: I'm not trying to *optimize* this code (I intuitively know where the > problems are). My intention is to learn the mechanics of profiling Haskell > code. Are you sure? Lazy evaluation is tricky. Try adding an SCC annotation to each function. E.g.: > dumpWith f = {-# SCC 'fold' #-} Data.Map.foldWithKey f [] > docToStr k (Doc { docName=n, docVectorLength=vl}) = > {-# SCC 'docToStr' #-} (:) ("d " ++ show k ++ " " ++ n ++ " " ++ (show vl)) > The call stack will then help you determine which invocation of the given function is taking up the time. Or it may be somewhere else. The Real World Haskell chapter on profiling is a good guide: http://book.realworldhaskell.org/beta/profiling.html Justin From greghaskell at me.com Sat Aug 30 22:52:23 2008 From: greghaskell at me.com (Greg Best) Date: Sat Aug 30 22:50:46 2008 Subject: [Haskell-beginners] Monads and infinite types Message-ID: <6EA709B4-9136-45F2-8031-5F2C12E886DF@me.com> Hello-- I'm still trying to wade into Haskell after a fair amount of experience in other (mostly, but not exclusively, C-type) languages, and I'm finding this mind numbingly difficult. Usually the way I learn a new language is by finding an application for it and pounding my way through that application. In this case I've started by trying to parse apart a simple GPS NMEA sentence. I'm sure there are prefab libraries for parsing strings, but this seemed like a good way of getting aquatinted with the Monad. I've created a new data type similar to Maybe, but which can return no value, a single value, or a list of values. It seems to behave, but I haven't ruled it out as the cause of my frustration. The NMEAParser monad will eventually take a comma separated string and return a list of fields, lopping off the checksum at the end. Once I can do that, I can start adding other intelligence such as testing the checksum, bounds checking the fields, etc. At the bottom is the little bit of code I'm working with, and the error messages I'm getting out of ghci. Both errors confuse me-- infinite type message because I'm not sure where I've suggested that it build that type, and the "expected ZeroOrMore a but got ZeroOrMore b" message because I thought 'b' and 'a' were allowed to be different types but could also be the same. Any help wrapping my head around this would be appreciated, and will almost certainly be rewarded with more dumb questions in the near future. Thanks-- Greg --------------------------------- NMEATest.hs---------------------------------- module NMEATest where data ZeroOrMore a = NoVal | SingleVal a | MultiVal [a] deriving (Eq,Ord,Show) type Sentence = String newtype NMEAParser a = NMEAParser(Sentence -> (ZeroOrMore a, Sentence)) instance Monad NMEAParser where return a = NMEAParser(\s -> (SingleVal a,s)) NMEAParser k >>= f = NMEAParser(\s0 -> let (r1, s1) = k s0 k2 = f r1 (r2, s2) = k2 s1 in (r1,s2)) ------------------------------------------------------------------------------------ ------------------ghci output-------------------------------------------- Prelude> :l NMEATest.hs [1 of 1] Compiling NMEATest ( NMEATest.hs, interpreted ) NMEATest.hs:26:45: Occurs check: cannot construct the infinite type: a = ZeroOrMore a When generalising the type(s) for `k2' In the expression: let (r1, s1) = k s0 k2 = f r1 (r2, s2) = k2 s1 in (r1, s2) In the first argument of `NMEAParser', namely `(\ s0 -> let (r1, s1) = k s0 k2 = f r1 .... in (r1, s2))' NMEATest.hs:28:42: Couldn't match expected type `b' against inferred type `a' `b' is a rigid type variable bound by the type signature for `>>=' at `a' is a rigid type variable bound by the type signature for `>>=' at Expected type: ZeroOrMore b Inferred type: ZeroOrMore a In the expression: r1 In the expression: let (r1, s1) = k s0 k2 = f r1 (r2, s2) = k2 s1 in (r1, s2) Failed, modules loaded: none. Prelude> ------------------------------------------------------------------------------------------------- From rendel at daimi.au.dk Sat Aug 30 23:32:49 2008 From: rendel at daimi.au.dk (Tillmann Rendel) Date: Sat Aug 30 23:31:18 2008 Subject: [Haskell-beginners] Monads and infinite types In-Reply-To: <6EA709B4-9136-45F2-8031-5F2C12E886DF@me.com> References: <6EA709B4-9136-45F2-8031-5F2C12E886DF@me.com> Message-ID: <48BA10E1.9050504@daimi.au.dk> Greg Best wrote: > ---------------------------------NMEATest.hs---------------------------------- > > module NMEATest where > > data ZeroOrMore a = NoVal | SingleVal a | MultiVal [a] deriving > (Eq,Ord,Show) > type Sentence = String > newtype NMEAParser a = NMEAParser(Sentence -> (ZeroOrMore a, Sentence)) > > > instance Monad NMEAParser where > return a = NMEAParser(\s -> (SingleVal a,s)) > NMEAParser k >>= f = NMEAParser(\s0 -> let (r1, s1) = k s0 > k2 = f r1 > (r2, s2) = k2 s1 in > (r1,s2)) > ------------------------------------------------------------------------------------ > > NMEATest.hs:26:45: > Occurs check: cannot construct the infinite type: a = ZeroOrMore a f and r1 have types f :: a -> NMEAParser b r1 :: ZeroOrMore a so that your use of f r1 forces a = ZeroOrMore a which cannot be the case. You have to deconstruct r1 and do something appropriate for the three different cases. > NMEATest.hs:28:42: > Couldn't match expected type `b' against inferred type `a' > Expected type: ZeroOrMore b > Inferred type: ZeroOrMore a Your >>= returns r1, the result of executing the left hand side action, but the overall result of executing (k >>= f) should be the result of the right hand side, i.e. r2. Note that r1 and r2 have indeed the types r1 :: ZeroOrMore a r2 :: ZeroOrMore b. Tillmann From chaddai.fouche at gmail.com Sun Aug 31 02:45:24 2008 From: chaddai.fouche at gmail.com (=?ISO-8859-1?Q?Chadda=EF_Fouch=E9?=) Date: Sun Aug 31 02:43:44 2008 Subject: [Haskell-beginners] Monads and infinite types In-Reply-To: <48BA10E1.9050504@daimi.au.dk> References: <6EA709B4-9136-45F2-8031-5F2C12E886DF@me.com> <48BA10E1.9050504@daimi.au.dk> Message-ID: 2008/8/31 Tillmann Rendel : >> instance Monad NMEAParser where >> return a = NMEAParser(\s -> (SingleVal a,s)) >> NMEAParser k >>= f = NMEAParser(\s0 -> let (r1, s1) = k s0 >> k2 = f r1 >> (r2, s2) = k2 s1 in >> (r1,s2)) "f r1" evaluates to a parser, you forgot to pattern match, k2 isn't a function, it's a parser. -- Jeda?