A bug of groupBy implement

Hi there: My friend asked me a question, and i suppose he has found a bug of `groupBy'. Here is the code piece:
List.groupBy (\a b -> Foreign.unsafePerformIO (Text.Printf.printf "\t%d <= %d ?: %s\n" a b (show (a<=b)) >> return (a<=b))) [7,3,5,9,6,8,3,5,4]
I have tested it in GHC 6.10.4 (Win XP) and GHC 6.8.3 (Linux), both give the wrong result (categaried): 7 <= 3 ?: False 3 <= 5 ?: True 3 <= 9 ?: True 3 <= 6 ?: True 3 <= 8 ?: True 3 <= 3 ?: True 3 <= 5 ?: True 3 <= 4 ?: True [[7],[3,5,9,6,8,3,5,4]] Regards -------------- L.Guo 2009-12-08

Could it not be a bug in
a) printf
b) unsafePerformIO
c) >>
d) return
e) <=
f) show
g) GHC or GHCi?
All of the above?
Best wishes
Stephen
2009/12/7 L.Guo
Hi there:
My friend asked me a question, and i suppose he has found a bug of `groupBy'.
Here is the code piece:
List.groupBy (\a b -> Foreign.unsafePerformIO (Text.Printf.printf "\t%d <= %d ?: %s\n" a b (show (a<=b)) >> return (a<=b))) [7,3,5,9,6,8,3,5,4]
I have tested it in GHC 6.10.4 (Win XP) and GHC 6.8.3 (Linux), both give the wrong result (categaried):
7 <= 3 ?: False 3 <= 5 ?: True 3 <= 9 ?: True 3 <= 6 ?: True 3 <= 8 ?: True 3 <= 3 ?: True 3 <= 5 ?: True 3 <= 4 ?: True [[7],[3,5,9,6,8,3,5,4]]
Regards -------------- L.Guo 2009-12-08
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Hello Stephen, Monday, December 7, 2009, 8:11:01 PM, you wrote: it's just what goupBy compares with the first element of group rather than comparing two adjancent elements. look at the trace it's not a bug, but misunderstanding of specification :)
Could it not be a bug in
a) printf b) unsafePerformIO c) >>> d) return e) <= f) show g) GHC or GHCi?
All of the above?
Best wishes
Stephen
2009/12/7 L.Guo
: Hi there:
My friend asked me a question, and i suppose he has found a bug of `groupBy'.
Here is the code piece:
List.groupBy (\a b -> Foreign.unsafePerformIO (Text.Printf.printf "\t%d <= %d ?: %s\n" a b (show (a<=b)) >> return (a<=b))) [7,3,5,9,6,8,3,5,4]
I have tested it in GHC 6.10.4 (Win XP) and GHC 6.8.3 (Linux), both give the wrong result (categaried):
7 <= 3 ?: False 3 <= 5 ?: True 3 <= 9 ?: True 3 <= 6 ?: True 3 <= 8 ?: True 3 <= 3 ?: True 3 <= 5 ?: True 3 <= 4 ?: True [[7],[3,5,9,6,8,3,5,4]]
Regards -------------- L.Guo 2009-12-08
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Hi L.Guo Brent has replied with the right answer. The definition of groupBy is below - the span in the where clause only compares with the first element of the current sub-list: -- | The 'groupBy' function is the non-overloaded version of 'group'. groupBy :: (a -> a -> Bool) -> [a] -> [[a]] groupBy _ [] = [] groupBy eq (x:xs) = (x:ys) : groupBy eq zs where (ys,zs) = span (eq x) xs -- list1 = [7,3,5,9,6,8,3,5,4::Int] Here are two more runs on your input with a wee bit less clutter. In both cases there are 'spans' where the numbers increase and decrease - this is because the operation is comparing the rest of the input against the first element in the 'span' not consecutive elements. *GroupBy Data.List> groupBy (<) list1 [[7],[3,5,9,6,8],[3,5,4]] *GroupBy Data.List> groupBy (<=) list1 [[7],[3,5,9,6,8,3,5,4]] Best wishes Stephen

On Tue, Dec 08, 2009 at 12:45:59AM +0800, L.Guo wrote:
Hi there:
My friend asked me a question, and i suppose he has found a bug of `groupBy'.
Here is the code piece:
List.groupBy (\a b -> Foreign.unsafePerformIO (Text.Printf.printf "\t%d <= %d ?: %s\n" a b (show (a<=b)) >> return (a<=b))) [7,3,5,9,6,8,3,5,4]
I have tested it in GHC 6.10.4 (Win XP) and GHC 6.8.3 (Linux), both give the wrong result (categaried):
7 <= 3 ?: False 3 <= 5 ?: True 3 <= 9 ?: True 3 <= 6 ?: True 3 <= 8 ?: True 3 <= 3 ?: True 3 <= 5 ?: True 3 <= 4 ?: True [[7],[3,5,9,6,8,3,5,4]]
This looks like the right result to me. What makes you think it is wrong? What result do you expect? -Brent

On Mon, Dec 07, 2009 at 12:15:45PM -0500, Brent Yorgey wrote:
On Tue, Dec 08, 2009 at 12:45:59AM +0800, L.Guo wrote:
Hi there:
My friend asked me a question, and i suppose he has found a bug of `groupBy'.
Here is the code piece:
List.groupBy (\a b -> Foreign.unsafePerformIO (Text.Printf.printf "\t%d <= %d ?: %s\n" a b (show (a<=b)) >> return (a<=b))) [7,3,5,9,6,8,3,5,4]
I have tested it in GHC 6.10.4 (Win XP) and GHC 6.8.3 (Linux), both give the wrong result (categaried):
7 <= 3 ?: False 3 <= 5 ?: True 3 <= 9 ?: True 3 <= 6 ?: True 3 <= 8 ?: True 3 <= 3 ?: True 3 <= 5 ?: True 3 <= 4 ?: True [[7],[3,5,9,6,8,3,5,4]]
This looks like the right result to me. What makes you think it is wrong? What result do you expect?
I just realized I think I understand what the confusion is. You think it should return [[7],[3,5,9],[6,8],[3,5],[4]]? But in fact, groupBy only works that way for equivalence relations, where it makes perfect sense to just compare the first thing in each sublist against all the rest, instead of comparing each pair of adjacent elements. The behavior you want is something I have been planning to add to the Data.List.Split module for a while. -Brent

Hi,
I have tested it in GHC 6.10.4 (Win XP) and GHC 6.8.3 (Linux), both give the wrong result (categaried):
7 <= 3 ?: False 3 <= 5 ?: True 3 <= 9 ?: True 3 <= 6 ?: True 3 <= 8 ?: True 3 <= 3 ?: True 3 <= 5 ?: True 3 <= 4 ?: True [[7],[3,5,9,6,8,3,5,4]] What exactly is wrong with this result? All of the above comparisons seem to get the right result, and they say 7 is not in the same categorie as 3, but all other numbers are in the same category as 3. So the returned list looks ok too.
Perhaps you had expected another output list (please tell us what you think you've found a bug!)? In fact, it seems that any output list would have been correct, since you're using a comparison function that is not symmetrical. In other words, you're say 7 should be in the same category as 3, but 3 should not be in the same category as 7. Since nothing is guaranteed about the order in which groupBy compares elements, any grouping could be achieved by letting groupBy choose the "right" ordering. So, it seems your comparison function is wrong since it does not satisfy the (unwritten) requirement of symmetry? Gr. Matthijs
participants (5)
-
Brent Yorgey
-
Bulat Ziganshin
-
L.Guo
-
Matthijs Kooijman
-
Stephen Tetley