RULES for SPECIALIZ(E)ations

I'm playing with rules, and I wonder if it is posible to define a rule that will trigger for a specialization of a function. (In the following examples, the functions are not necesarily useful or good-style... :) I have: count :: (Integral b) => (a -> Bool) -> [a] -> b count = count' 0 where count' n _ [] = n count' n f (x:xs) | f x = count' (n+1) f xs | otherwise = count' n f xs with b of class Integral and not an Int because it could posibly be used to count lists with more than maxInt elements (let's say, bytes in a huge file, or records in a long-lived socket connection, or whatever). Ok, if I'm not mistaken I can add: {-# SPECIALIZE count :: (a -> Bool) -> [a] -> Int #-} and have the compiler add an alternate version of count for uses such as: let c :: Int = count even [1..100] Now, to learn about RULES, I defined: {-# RULES "count/generic" forall f g xs. count f (filter g xs) = genericLength (filter (\x -> g x && f x) xs) #-} where I'm forced to use genericLength so the types of the LHS and RHS can match. Then I wondered: as I have an specialization of count which returns Int, wouldn't be possible to do: {-# RULES "count/int" forall f g xs. count f (filter g xs) = length (filter (\x -> g x && f x) xs) -#} Well, the fact is that: testc1 n = count even (filter (\x -> x `mod` 3 > 0) [1..n]) fires "count/generic" all right, but testc2 :: Int -> Int testc2 n = count even (filter (\x -> x `mod` 3 > 0) [1..n]) does not fire "count/int". I suppose I'm being bitten by User's Guide 7.8.2: "If more than one rule matches a call, GHC will choose one arbitrarily to apply." even if a bit later it says: "So a rule only matches if the types match too." Am I understanding right and it's that so? Thanks, /L/e/k/t/u
participants (1)
-
Juanma Barranquero