Code Comments
Programming Forum and web based access to our favorite programming groups.Hi I have 2 minor problems. 1- Let's say I want to write functions for the "implies" and "xor" boolean operations. If I write them as... imp p q = if p then q else True xor p q = if p then not q else q .. I have to use them with the prefix notation: imp True False -- False xor True False -- True To use them as operators, I have to use the backquote solution which is even less attractive (5 characters per operator in these instances). To take the "implies" example, I can make some weirdo operator (since "=>" is used by Haskell already) and code this: infixl 5 --> (--> ) :: Bool -> Bool -> Bool p --> q = imp p q When I try to use the characters sequence "imp," however, I get errors: -- Doesn't work !!! infixl 5 imp (imp) :: Bool -> Bool -> Bool p imp q = imp p q Anyway we can use character sequences as operators -- without the backquotes? 2- Haskell has the binary functions "min" and "max" which you can use as min 1 2 -- 1 max 1 2 -- 2 However, if I wanted to use them on a list, I can't "map" it on them as this makes no sense (the whole list must be checked in pairs). So I wrote this: max2 [] = 0 max2 (x:xs) = max x (max2 xs) ..which works. Trouble is, when I use the same pattern in the "min" function, the first line (necessary for pattern matching) has to return 0, so I end up always returning 0 since if the list contains positive integers, 0 is always the minimum. min2 [] = 0 min2 (x:xs) = min x (min2 xs) How do I get around this (keeping it as simple as here)? Thanks -- K -- Message posted using http://www.talkaboutprogramming.com...tiona l/ More information at http://www.talkaboutprogramming.com/faq.html
Post Follow-up to this message"Xcriber51" <ken@mail.com> wrote in message news:01b43d23de0b67e2c894e04a754b9e7a@lo calhost.talkaboutprogramming.com... > Hi > > I have 2 minor problems. > [ SNIP ] > 2- Haskell has the binary functions "min" and "max" which you can use as > > min 1 2 -- 1 > max 1 2 -- 2 > > However, if I wanted to use them on a list, I can't "map" it on them as > this makes no sense (the whole list must be checked in pairs). So I wrote > this: > > max2 [] = 0 > max2 (x:xs) = max x (max2 xs) > > ..which works. Trouble is, when I use the same pattern in the "min" > function, the first line (necessary for pattern matching) has to return 0, > so I end up always returning 0 since if the list contains positive > integers, 0 is always the minimum. > > min2 [] = 0 > min2 (x:xs) = min x (min2 xs) > > How do I get around this (keeping it as simple as here)? > > > Thanks > -- K For the latter problem you can use foldr1, as in foldr1 min list foldr1 max list AHS
Post Follow-up to this messageXcriber51 <ken@mail.com> wrote: > Anyway we can use character sequences as operators -- without the > backquotes? No. To see why, look at the expression "f g h". Is that a function f taking to parameters g and h, or an infix operator g taking two parameters f and h? > so I end up always returning 0 since if the list contains positive > integers, 0 is always the minimum. Yes. So does it really make sense to return 0 for the empty list? How do you know your list will only contain positive numbers? > How do I get around this (keeping it as simple as here)? You can use the functions "minimum" and "maximum" from the Prelude, for example. (Which return an error for the empty list). Arved Sandstrom <asandstrom@accesswave.ca> wrote: > For the latter problem you can use foldr1, as in > > foldr1 min list > foldr1 max list NB that "minimum" and "maximum" use "foldl1" instead of "foldr1", so you must pay attention to strictness when deciding which of those alternatives to use. F'up to comp.lang.haskell? - Dirk
Post Follow-up to this messageDirk Thierbach <dthierbach@usenet.arcornews.de> writes: > NB that "minimum" and "maximum" use "foldl1" instead of "foldr1", so > you must pay attention to strictness when deciding which of those > alternatives to use. Why on earth do they do that?! Is there a way to get them to use foldl1' ?
Post Follow-up to this messageYou're right about the 0 issue, Dirk. Thanks. But you see (or you could see, which I didn't make clear), I was only fooling around with the idea of using a binary function recursively in a list context... fbin x y = ... flist (x:xs) = fbin x (flist xs) ..and 0 was the first (habitual) thing to place at the first line to terminate the recursion. All this because I still don't get the notion of "folding" obviously :) Just can't wrap my mind around it. In real life, the things that I fold don't calculate things :D Thanks everyone. Cheers -- K -- Message posted using http://www.talkaboutprogramming.com...tiona l/ More information at http://www.talkaboutprogramming.com/faq.html
Post Follow-up to this messagePaul Rubin <http://phr.cx@nospam.invalid> wrote: > Dirk Thierbach <dthierbach@usenet.arcornews.de> writes: > Why on earth do they do that?! Is there a way to get them to use foldl1' ?[/color ] Yes. Strictness analysis in GHC, when enabled, will automatically turn non-strict left-fold into strict left-fold. Or, just write your own versions (I have a module with a collection of convenient "missing" list operations, and this is one of them). BTW, "sum" and "product" are also non-strict left-fold in the Prelude. Hence the FAQ "why does my tail-recursive program fail with a stack overflow?" - Dirk
Post Follow-up to this messageXcriber51 <ken@mail.com> wrote: > All this because I still don't get the notion of "folding" obviously :) Think of it as putting a binary operator "in between" all elements of a list. If you have a list xs = [x1,x2,x3,x4], and some binary operator #, then folding the list with the operators will give you something like x1 # x2 # x3 # x4 Usually, the operator won't be associative, so you have to add parenthesis. There are two ways to do that. Either group them to the left, ((x1 # x2) # x3) # x4 which equals foldl1 (#) xs or to the right, x1 # (x2 # (x3 # x4)) which equals foldr1 (#) xs That obviously only works if you have at least one element (which will get returned in that case). If you want to generalize that, you have to throw in a "neutral" or "zero" element z. As in (((z # x1) # x2) # x3) # x4 which equals foldl (#) z xs, or x1 # (x2 # (x3 # (x4 # z))) which equals foldr (#) z xs Then, if you remove all elements, you get foldl (#) z [] = z = foldr (#) z [ ] for the empty list. > Just can't wrap my mind around it. In real life, the things that I fold > don't calculate things :D Does that help? If you're still, imagine just addition instead of (#). Then, because (+) is declared as infixl, we get 0 + x1 + x2 + x3 + x4 = foldl (+) 0 xs = sum xs The next step then is to understand what foldl and foldr have to do with strictness, and why that can cause stack overflows for large lists if you're not careful. - Dirk
Post Follow-up to this messageWell, I figure from now on whenever I fold a shirt to tuck it in a suitcase, I'll use brackets and throw a neutral item in :D Ok, I'm being silly. YES, Dirk, it absolutely does. First time I get this "fold" thing -- crystal clear now! Before I saw your explanation, though, I figured out a "trick" on the first lines of my maxOf and minOf functions that did the job: maxOf [x] = x maxOf (x:xs) = max x (maxOf xs) minOf [x] = x minOf (x:xs) = min x (minOf xs) But then, I discovered this page which explained how beautifully "fold" functions could be used to isolate certain patterns: http://caos.di.uminho.pt/~ulisses/b...magic-function/ Then, I saw you explanation, and now I'm totally convinced. Thanks for taking the time for this, Dirk. Cheers -- K -- Message posted using http://www.talkaboutprogramming.com...tiona l/ More information at http://www.talkaboutprogramming.com/faq.html
Post Follow-up to this message"Xcriber51" <ken@mail.com> writes: > 1- Let's say I want to write functions for the "implies" and "xor" boolean > operations. If I write them as... > > imp p q = if p then q else True > xor p q = if p then not q else q > > .. I have to use them with the prefix notation: > > imp True False -- False > xor True False -- True > > To use them as operators, I have to use the backquote solution which is > even less attractive (5 characters per operator in these instances). > > To take the "implies" example, I can make some weirdo operator (since "=>" > is used by Haskell already) and code this: > > infixl 5 --> > (--> ) :: Bool -> Bool -> Bool > p --> q = imp p q > > When I try to use the characters sequence "imp," however, I get errors: > > -- Doesn't work !!! > infixl 5 imp > (imp) :: Bool -> Bool -> Bool > p imp q = imp p q > > Anyway we can use character sequences as operators -- without the > backquotes? In Haskell, infix operators can be made in two ways: 1. Sequences that consist entirely of characters from a subset of the non-alphanumeric characters. 2. Alphanumeric sequences starting with lower-case letters but enclosed in back quotes. So you indeed can't have alphanumeric infix operators without the backquotes. The reason for this restriction is to make lexing and parsing easier -- not only for the compiler, but also for the human reader. Torben
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.